diff --git a/XSchemWin/XSchemWin.vcxproj b/XSchemWin/XSchemWin.vcxproj index a601fc21..f630ae55 100644 --- a/XSchemWin/XSchemWin.vcxproj +++ b/XSchemWin/XSchemWin.vcxproj @@ -254,6 +254,7 @@ + @@ -261,6 +262,7 @@ + @@ -284,6 +286,11 @@ + + Document + bison -p kk -o eval_expr.c ..\src\eval_expr.y + eval_expr.c + diff --git a/XSchemWin/XSchemWin_cairo.vcxproj b/XSchemWin/XSchemWin_cairo.vcxproj index 793d0135..b4a64661 100644 --- a/XSchemWin/XSchemWin_cairo.vcxproj +++ b/XSchemWin/XSchemWin_cairo.vcxproj @@ -254,6 +254,7 @@ + @@ -261,6 +262,7 @@ + @@ -284,6 +286,11 @@ + + Document + bison -p kk -o eval_expr.c ..\src\eval_expr.y + eval_expr.c + diff --git a/XSchemWin/XSchemWix/Product.wxs b/XSchemWin/XSchemWix/Product.wxs index 8a036a35..2d3e9335 100644 --- a/XSchemWin/XSchemWix/Product.wxs +++ b/XSchemWin/XSchemWix/Product.wxs @@ -250,10 +250,7 @@ - - - - + @@ -374,7 +371,6 @@ - diff --git a/XSchemWin/XSchemWix/heat_xschem_library.wxs b/XSchemWin/XSchemWix/heat_xschem_library.wxs index 76fc66cb..08996ad1 100644 --- a/XSchemWin/XSchemWix/heat_xschem_library.wxs +++ b/XSchemWin/XSchemWix/heat_xschem_library.wxs @@ -3,5917 +3,5920 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -6026,6 +6029,7 @@ + diff --git a/XSchemWin/XSchemWix/xschem_library.wxs b/XSchemWin/XSchemWix/xschem_library.wxs index e39f2c4c..db02bb6c 100644 --- a/XSchemWin/XSchemWix/xschem_library.wxs +++ b/XSchemWin/XSchemWix/xschem_library.wxs @@ -293,6 +293,9 @@ + + + @@ -457,6 +460,7 @@ + diff --git a/XSchemWin/XSchemWix/xschemrc b/XSchemWin/XSchemWix/xschemrc index 94adef3a..a9081bb5 100644 --- a/XSchemWin/XSchemWix/xschemrc +++ b/XSchemWin/XSchemWix/xschemrc @@ -171,8 +171,14 @@ #### this is the default: # set initial_geometry {900x600} -#### initial geometry of load /save / insert component file selector -# set file_dialog_default_geometry 800x600 +#### initial size of the load_file_dialog (the file selector) dialog box +# set file_dialog_default_geometry 700x680+100+40 +#### load_file_dialog directory list (+ recent if shown) X width in pixels +# set file_dialog_sp0 350 +#### load_file_dialog recent components list X width in pixels +# set file_dialog_sp1 100 +#### load_file_dialog components list Y height in pixels +# set file_dialog_v_sp0 420 #### display full path (1) or only name (0) for component directories. Default: 1 # set load_file_dialog_fullpath 1 @@ -195,6 +201,11 @@ #### default: 0 # set persistent_command 1 +#### if set to 0 users must click a point after hitting a command key +#### like 'w(ire)', 'l(ine)' and so on. +#### default is 1 (hitting the command key sets also the first point). +# set infix_interface 0 + #### if set to 1 allow click & drag objects in the schematic #### to move them without keyboard commands ('m') #### default: enabled (1) @@ -256,8 +267,24 @@ #### enable drawing crosshairs at mouse coordinates. Default: disabled (0) # set draw_crosshair 1 -#### set crosshair layer; Default 3 (TEXTLAYER) -# set crosshair_layer 3 +#### set crosshair layer; Default 8 (Yellow) +# set crosshair_layer 8 + +#### set crosshair size; Default: 0 (full screen spanning crosshair) +# set crosshair_size 5 + +#### enable drawing a diamond-shaped cursor at the closest circuit endpoint. Default: disabled (0) +# set snap_cursor 1 + +#### set snap_cursor_size; Default: 6 (Diamond-shaped cursor that snaps to nearest circuit endpoint) +# set snap_cursor_size 6 + +#### set cadence_compat; Default: 0 (Cadence-style keybinds are not used by default) +# set cadence_compat 1 + +#### if set, then, when cursor (regardless of style) is on an object, and user clicks (though mouse pointer is not on the object), +#### the object is selected. Default: 0 +# set use_cursor_for_selection 1 #### enable to scale grid point size as done with lines at close zoom, default: 0 # set big_grid_points 0 @@ -510,7 +537,10 @@ set editor {notepad.exe} # } # } - +########################################################################### +#### TCL COMMANDS TO BE EXECUTED AFTER GENERATING NETLIST +########################################################################### +# set netlist_postprocess {textfile $netlist_dir/[xschem get netlist_name fallback]} ########################################################################### #### WEB URL DOWNLOAD HELPER APPLICATION @@ -553,6 +583,14 @@ set editor {notepad.exe} #### default: 0 (not set) # set show_hidden_texts 1 +########################################################################### +#### USE CTRL MODIFIER TO OPERATE ON GRAPHS WITH MOUSE & KEYBOARD +########################################################################### +#### if enabled forces to hold Control key pressed to operate on graphs +#### to prevent "graph event stealing to schematic" +#### Default: 0 (not set) +# set graph_use_ctrl_key 1 + ########################################################################### #### HIDE GRAPHS IF NO SPICE DATA LOADED ########################################################################### @@ -560,6 +598,16 @@ set editor {notepad.exe} #### default: not enabled (0) # set hide_empty_graphs 0 + +########################################################################### +#### ATTACH HOOK FUNCTION TO CURSOR 2 MOVEMENT +########################################################################### +#### if enabled whenever the cursor2 is moved the specified script is +#### executed. Examples: +#### set cursor_2_hook {conducting_devices 10e-3 nodraw} +#### set cursor_2_hook {hilight_high_nets 0 1.8 nodraw} +#### this can be used to add backannotation actions. + ########################################################################### #### LIVE BACKANNOTATION OF DATA AT CURSOR 2 (B) POSITION ########################################################################### @@ -591,3 +639,6 @@ set editor {notepad.exe} #### Default: not enabled (0) # set fix_mouse_coord 0 +#### redefine some variables to emulate Cadence UI / bindkeys +# source /home/schippes/share/xschem/cadence_style_rc + diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html index 4cc88d12..0cc1b8b6 100644 --- a/doc/xschem_man/developer_info.html +++ b/doc/xschem_man/developer_info.html @@ -551,6 +551,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" +
  • abort_operation
  • @@ -588,7 +589,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
        all inside selected instances will be deleted 
  • build_colors
  •     Rebuild color palette using values of tcl vars dim_value and dim_bg 
    -
  • callback winpath event mx my key button aux state
  • +   
  • callback win_path event mx my key button aux state
  •     Invoke the callback event dispatcher with a software event 
  • case_insensitive 1|0
  •     Set case insensitive symbol lookup. Use only on case insensitive filesystems 
    @@ -713,6 +714,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
  • escape_chars source [charset]
  •     escape tcl special characters with backslash
        if charset is given escape characters in charset 
    +
  • eval_expr str
  • +   debug function: evaluate arithmetic expression in str 
  • exit [exit_code] [closewindow] [force]
  •     Exit the program, ask for confirm if current file modified.
        if exit_code is given exit with its value, otherwise use 0 exit code
    @@ -757,6 +760,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
          
  • bbox bounding box schematic
  • bbox_hilighted bounding box of highlinhted objects
  • bbox_selected bounding box of selected objects
  • +
  • build_date time and date this file was built.
  • cadlayers number of layers
  • case_insensitive case_insensitive symbol matching
  • color_ps color postscript flag
  • @@ -974,7 +978,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" Example: xschem instances_to_net PANEL --> { {Vsw} {plus} {580} {-560} } { {p2} {p} {660} {-440} } { {Vpanel1} {minus} {600} {-440} }
    -
  • is_symgen symbol
  • +   
  • is_generator symbol
  •     tell if 'symbol' is a generator (symbol(param1,param2,...) 
  • line [x1 y1 x2 y2] [pos] [propstring] [draw]
  •     if 'x1 y1 x2 y2'is given place line on current
    @@ -1025,6 +1029,11 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
        If 'f' is given output stderr messages to file 'f'
        if 'f' is not given and a file log is open, close log
        file and resume logging to stderr 
    +
  • load_symbol [symbol_file]
  • +   Load specified symbol_file
    +   Returns:
    +     >= 0: symbol is already loaded or has been loaded
    +     <  0: symbol was not loaded
  • log_write text
  •     write given string to log file, so tcl can write messages on the log file
  • logic_get_net net_name
  • @@ -1096,22 +1105,22 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
        
  • new_process [f]
  •     Start a new xschem process for a schematic.
        If 'f' is given load specified schematic. 
    -
  • new_schematic create|destroy|destroy_all|switch winpath file [draw]
  • +   
  • new_schematic create|destroy|destroy_all|switch win_path file [draw]
  •     Open/destroy a new tab or window
          create: create new empty window or with 'file' loaded if 'file' given.
    -             The winpath must be given (even {} is ok).
    -             non empty winpath ({1}) will avoid warnings if opening the
    +             The win_path must be given (even {} is ok).
    +             non empty win_path ({1}) will avoid warnings if opening the
                  same file multiple times.
    -     destroy: destroy tab/window identified by winpath. Example:
    +     destroy: destroy tab/window identified by win_path. Example:
                   xschem new_schematic destroy .x1.drw
          destroy_all: close all tabs/additional windows
                   if the 'force'argument is given do not issue a warning if modified
                   tabs are about to be closed.
    -     switch: switch context to specified 'winpath' window or specified schematic name
    +     switch: switch context to specified 'win_path' window or specified schematic name
                   If 'draw' is given and set to 0 do not redraw after switching tab
                   (only tab i/f)
    -   Main window/tab has winpath set to .drw,
    -   Additional windows/tabs have winpath set to .x1.drw, .x2.drw and so on...
    + Main window/tab has win_path set to .drw, + Additional windows/tabs have win_path set to .x1.drw, .x2.drw and so on...
  • only_probes
  •         dim schematic to better show highlights 
  • origin x y [zoom]
  • @@ -1146,7 +1155,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
        Start a GUI placement of a text object 
  • polygon
  •     Start a GUI placement of a polygon 
    -
  • preview_window create|draw|destroy|close [winpath] [file]
  • +   
  • preview_window create|draw|destroy|close [win_path] [file]
  •     destroy: will delete preview schematic data and destroy container window
        close: same as destroy but leave the container window.
        Used in fileselector to show a schematic preview.
    @@ -1548,7 +1557,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
  • switch [window_path |schematic_name]
  •     Switch context to indicated window path or schematic name
        returns 0 if switch was successfull or 1 in case of errors
    -   (no tabs/windows present or no matching winpath / schematic name
    +   (no tabs/windows present or no matching win_path / schematic name
        found).
  • symbols [n | 'derived_symbols']
  •     if 'n' given list symbol with name or number 'n', else list all
    @@ -1723,7 +1732,6 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
     
     
     
    -
     
     
      
    diff --git a/src/Makefile.in b/src/Makefile.in
    index ec2d23ef..16bf9ac6 100644
    --- a/src/Makefile.in
    +++ b/src/Makefile.in
    @@ -15,7 +15,7 @@ put /local/install_shares {
      symgen.awk order_labels.awk sort_labels.awk spice.awk tedax.awk verilog.awk
      vhdl.awk hspice_backannotate.tcl add_custom_menu.tcl create_graph.tcl
      add_custom_button.tcl change_index.tcl icon.xpm resources.tcl xschemrc
    - ngspice_backannotate.tcl gschemtoxschem.awk mouse_bindings.tcl
    + ngspice_backannotate.tcl gschemtoxschem.awk mouse_bindings.tcl cadence_style_rc
      place_sym_pins.tcl place_pins.tcl make_sch_from_spice.awk make_sym_from_spice.awk
     }
     
    @@ -50,7 +50,7 @@ expandlabel.c expandlabel.h: expandlabel.y
     	bison -d -o expandlabel.c  expandlabel.y
     
     eval_expr.c: eval_expr.y
    -	bison -o eval_expr.c eval_expr.y
    +	bison -p kk -o eval_expr.c eval_expr.y
     
     parselabel.o: expandlabel.h
     
    diff --git a/src/actions.c b/src/actions.c
    index 59afb731..ba5bac99 100644
    --- a/src/actions.c
    +++ b/src/actions.c
    @@ -45,7 +45,7 @@ unsigned int hash_file(const char *f, int skip_path_lines)
       int cr = 0;
       unsigned int h=5381;
       char *line = NULL;
    -  fd = fopen(f, "r"); /* windows won't return \r in the lines and we chop them out anyway in the code */
    +  fd = my_fopen(f, "r"); /* windows won't return \r in the lines and we chop them out anyway in the code */
       if(fd) {
         while((line = my_fgets(fd, &n))) {
           /* skip lines of type: '** sch_path: ...' or '-- sch_path: ...' or '// sym_path: ...'
    diff --git a/src/cadence_style_rc b/src/cadence_style_rc
    new file mode 100644
    index 00000000..4086e2e2
    --- /dev/null
    +++ b/src/cadence_style_rc
    @@ -0,0 +1,10 @@
    +# run with $> xschem --script /path/to/cadence_style_rc
    +set draw_crosshair 1
    +set crosshair_size 2
    +set infix_interface 0
    +set cadence_compat 1
    +set orthogonal_wiring 1
    +set snap_cursor 1
    +set snap_cursor_size 4
    +set persistent_command 1
    +set use_cursor_for_selection 1
    diff --git a/src/cairo_jpg.c b/src/cairo_jpg.c
    index 62bc20cf..5c8b3359 100644
    --- a/src/cairo_jpg.c
    +++ b/src/cairo_jpg.c
    @@ -460,7 +460,7 @@ cairo_surface_t *cairo_image_surface_create_from_jpeg_stream(cairo_read_func_t r
      * @return Returns a pointer to a cairo_surface_t structure. It should be
      * checked with cairo_surface_status() for errors.
      * @note If the returned surface is invalid you can use errno to determine
    - * further reasons. Errno is set according to fopen(3) and malloc(3). If you
    + * further reasons. Errno is set according to my_fopen(3) and malloc(3). If you
      * intend to check errno you shall set it to 0 before calling this function
      * because it does not modify errno itself.
      */
    @@ -520,7 +520,7 @@ static cairo_status_t cj_read(void *closure, unsigned char *data, unsigned int l
      * @return Returns a pointer to a cairo_surface_t structure. It should be
      * checked with cairo_surface_status() for errors.
      * @note If the returned surface is invalid you can use errno to determine
    - * further reasons. Errno is set according to fopen(3) and malloc(3). If you
    + * further reasons. Errno is set according to my_fopen(3) and malloc(3). If you
      * intend to check errno you shall set it to 0 before calling this function
      * because it does not modify errno itself.
      */
    diff --git a/src/callback.c b/src/callback.c
    index c1deffe4..bbd75c0f 100644
    --- a/src/callback.c
    +++ b/src/callback.c
    @@ -151,6 +151,8 @@ void abort_operation(void)
       tcleval("set constr_mv 0" );
       dbg(1, "abort_operation(): Escape: ui_state=%d, last_command=%d\n", xctx->ui_state, xctx->last_command);
       xctx->constr_mv=0;
    +
    +  if(xctx->ui_state & STARTPOLYGON) new_polygon(END, xctx->mousex_snap, xctx->mousey_snap);
       if(xctx->last_command && xctx->ui_state & (STARTWIRE | STARTLINE)) {
         if(xctx->ui_state & STARTWIRE) new_wire(RUBBER|CLEAR, xctx->mousex_snap, xctx->mousey_snap);
         if(xctx->ui_state & STARTLINE) new_line(RUBBER|CLEAR, xctx->mousex_snap, xctx->mousey_snap);
    @@ -220,6 +222,7 @@ static void start_line(double mx, double my)
           if(xctx->constr_mv == 1) my = xctx->my_double_save;
           if(xctx->constr_mv == 2) mx = xctx->mx_double_save;
         } else {
    +      xctx->manhattan_lines = 0;
           xctx->mx_double_save=mx;
           xctx->my_double_save=my;
         }
    @@ -228,30 +231,31 @@ static void start_line(double mx, double my)
     
     static void start_wire(double mx, double my)
     {
    -     dbg(1, "start_wire(): ui_state=%d, ui_state2=%d last_command=%d\n", xctx->ui_state, xctx->ui_state2, xctx->last_command);
    -     xctx->last_command = STARTWIRE;
    -     if(xctx->ui_state & STARTWIRE) {
    -       if(tclgetboolvar("orthogonal_wiring") && !tclgetboolvar("constr_mv")){
    -         xctx->constr_mv = xctx->manhattan_lines;
    -         new_wire(CLEAR, mx, my);
    -         redraw_w_a_l_r_p_z_rubbers(1);
    -       }
    -       if(xctx->constr_mv != 2) {
    -         xctx->mx_double_save = mx;
    -       }
    -       if(xctx->constr_mv != 1) {
    -         xctx->my_double_save = my;
    -       }
    -       if(xctx->constr_mv == 1) my = xctx->my_double_save;
    -       if(xctx->constr_mv == 2) mx = xctx->mx_double_save;
    -     } else {
    -       xctx->mx_double_save=mx;
    -       xctx->my_double_save=my;
    -     }
    -     new_wire(PLACE,mx, my);
    -     if(tclgetboolvar("orthogonal_wiring") && !tclgetboolvar("constr_mv")){
    -         xctx->constr_mv = 0;
    -     }
    +  dbg(1, "start_wire(): ui_state=%d, ui_state2=%d last_command=%d\n",
    +      xctx->ui_state, xctx->ui_state2, xctx->last_command);
    +  xctx->last_command = STARTWIRE;
    +  if(xctx->ui_state & STARTWIRE) {
    +    if(tclgetboolvar("orthogonal_wiring") && !tclgetboolvar("constr_mv")){
    +      xctx->constr_mv = xctx->manhattan_lines;
    +      new_wire(CLEAR, mx, my);
    +      redraw_w_a_l_r_p_z_rubbers(1);
    +    }
    +    if(xctx->constr_mv != 2) {
    +      xctx->mx_double_save = mx;
    +    }
    +    if(xctx->constr_mv != 1) {
    +      xctx->my_double_save = my;
    +    }
    +    if(xctx->constr_mv == 1) my = xctx->my_double_save;
    +    if(xctx->constr_mv == 2) mx = xctx->mx_double_save;
    +  } else {
    +    xctx->mx_double_save=mx;
    +    xctx->my_double_save=my;
    +  }
    +  new_wire(PLACE,mx, my);
    +  if(tclgetboolvar("orthogonal_wiring") && !tclgetboolvar("constr_mv")){
    +      xctx->constr_mv = 0;
    +  }
     }
     
     static double interpolate_yval(int idx, int p, double x, int sweep_idx, int point_not_last)
    @@ -1641,11 +1645,11 @@ static int end_place_move_copy_zoom()
         }
         xctx->constr_mv=0;
         tcleval("set constr_mv 0" );
    -    return 1;
    +    return 0;
       }
       else if(xctx->ui_state & STARTARC) {
         new_arc(SET, 0, xctx->mousex_snap, xctx->mousey_snap);
    -    return 1;
    +    return 0;
       }
       else if(xctx->ui_state & STARTLINE) {
         if(tclgetboolvar("persistent_command")) {
    @@ -1663,11 +1667,11 @@ static int end_place_move_copy_zoom()
         }
         xctx->constr_mv=0;
         tcleval("set constr_mv 0" );
    -    return 1;
    +    return 0;
       }
       else if(xctx->ui_state & STARTRECT) {
         new_rect(PLACE|END,xctx->mousex_snap, xctx->mousey_snap);
    -    return 1;
    +    return 0;
       }
       else if(xctx->ui_state & STARTPOLYGON) {
         if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save;
    @@ -1677,7 +1681,7 @@ static int end_place_move_copy_zoom()
         xctx->my_double_save=xctx->mousey_snap;
         xctx->constr_mv=0;
         tcleval("set constr_mv 0" );
    -    return 1;
    +    return 0;
       }
       else if(xctx->ui_state & STARTMOVE) {
         move_objects(END,0,0,0);
    @@ -1721,7 +1725,7 @@ void snapped_wire(double c_snap)
         new_wire(PLACE|END, x, y);
         xctx->constr_mv=0;
         tcleval("set constr_mv 0" );
    -    if((xctx->ui_state & MENUSTART) && !tclgetboolvar("persistent_command") ) xctx->ui_state &= ~MENUSTART;
    +    if((xctx->ui_state & MENUSTART) && !tclgetboolvar("persistent_command") ) xctx->ui_state &= ~MENUSTART; /*CD*/
       }
     }
     
    @@ -2459,6 +2463,7 @@ static void handle_enter_notify(int draw_xhair, int crosshair_size)
           xctx->mousey_snap = -340;
           merge_file(1, ".sch");
         }
    +    
         return;
     }
     
    @@ -2471,6 +2476,7 @@ static void handle_motion_notify(int event, KeySym key, int state, int rstate, i
         }
         if(draw_xhair) {
           draw_crosshair(1, state); /* when moving mouse: first action is delete crosshair, will be drawn later */
    +      if(snap_cursor && wire_draw_active) draw_snap_cursor(1);
         }
         if(snap_cursor && wire_draw_active) draw_snap_cursor(1);
         /* pan schematic */
    @@ -2582,6 +2588,7 @@ static void handle_motion_notify(int event, KeySym key, int state, int rstate, i
           draw_crosshair(2, state); /* what = 2(draw) */
         }
         if(snap_cursor && wire_draw_active) draw_snap_cursor(2);
    +
         return;
     }
     
    @@ -2777,12 +2784,12 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
        {
         int x;
         xctx->fill_pattern++;
    -    if(xctx->fill_pattern==3) xctx->fill_pattern=0;
    +    if(xctx->fill_pattern==2) xctx->fill_pattern=0;
     
         if(xctx->fill_pattern==1) {
          tcleval("alert_ { Stippled pattern fill} {}");
          for(x=0;xfill_type[x]==1) XSetFillStyle(display,xctx->gcstipple[x],FillSolid);
    +       if(xctx->fill_type[x]==2) XSetFillStyle(display,xctx->gcstipple[x],FillSolid);
            else XSetFillStyle(display,xctx->gcstipple[x],FillStippled);
          }
         }
    @@ -2837,6 +2844,7 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
        {
          int prev_state = xctx->ui_state;
          if(xctx->semaphore >= 2) return;
    +
          if(infix_interface) {
            start_wire(xctx->mousex_snap, xctx->mousey_snap);
            if(prev_state == STARTWIRE) {
    @@ -2881,7 +2889,7 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
        {
         view_zoom(0.0); return;
        }
    -   if(key=='z' && EQUAL_MODMASK) /* toggle snap-cursor option */
    +   if(key=='z' && EQUAL_MODMASK && cadence_compat) /* toggle snap-cursor option */
        {
          if(tclgetboolvar("snap_cursor")) {
            tclsetvar("snap_cursor", "0");
    @@ -3435,7 +3443,6 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
          int tool = 0;
          int exists = 0;
          char *tool_name = NULL;
    -     char str[200];
     
          if(xctx->semaphore >= 2) return;
          tcleval("winfo exists .graphdialog");
    @@ -3451,7 +3458,7 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
          if(exists) {
            if(!tool) {
              tool = tclgetintvar("sim(spicewave,default)");
    -         my_snprintf(str, S(str), "sim(spicewave,%d,name)", tool);
    +         my_snprintf(str, PATH_MAX + 100, "sim(spicewave,%d,name)", tool);
              my_strdup(_ALLOC_ID_, &tool_name, tclgetvar(str));
              dbg(1,"callback(): tool_name=%s\n", tool_name);
              if(strstr(tool_name, "Gaw")) tool=GAW;
    @@ -3475,7 +3482,7 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
        }
        if(key=='g' && rstate==ControlMask)              /* set snap factor 20161212 */
        {
    -    my_snprintf(str, S(str),
    +    my_snprintf(str,  S(str),
          "input_line {Enter snap value (default: %.16g current: %.16g)}  {xschem set cadsnap} {%g} 10",
          CADSNAP, c_snap, c_snap);
         tcleval(str);
    @@ -4087,6 +4094,7 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
          break_wires_at_pins(1);
          return;
        }
    +   
        return;
     }
     
    @@ -4094,6 +4102,8 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
                                     double c_snap, int draw_xhair, int crosshair_size, int enable_stretch, int aux)
     {
        dbg(1, "callback(): ButtonPress  ui_state=%d state=%d\n",xctx->ui_state,state);
    +   int use_cursor_for_sel = tclgetintvar("use_cursor_for_selection");
    +   int excl = xctx->ui_state & (STARTWIRE | STARTRECT | STARTLINE | STARTPOLYGON | STARTARC);
        if(waves_selected(event, key, state, button)) {
          waves_callback(event, mx, my, key, button, aux, state);
          return;
    @@ -4105,7 +4115,7 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
        }
     
        /* select instance and connected nets stopping at wire junctions */
    -   if(button == Button3 &&  state == ControlMask && xctx->semaphore <2)
    +   if(!excl && button == Button3 && state == ControlMask && xctx->semaphore <2)
        {
          Selected sel;
          sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0, NULL);
    @@ -4113,17 +4123,19 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
        }
        
        /* break wire at mouse coordinates, move break point to nearest grid point */
    -   else if(button == Button3 &&  EQUAL_MODMASK && !(state & ShiftMask) && xctx->semaphore <2)
    +   else if(!excl && button == Button3 && EQUAL_MODMASK &&
    +           !(state & ShiftMask) && xctx->semaphore <2)
        {
          break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 1);
        }
        /* break wire at mouse coordinates */
    -   else if(button == Button3 && EQUAL_MODMASK && (state & ShiftMask) && xctx->semaphore <2)
    +   else if(!excl && button == Button3 && EQUAL_MODMASK &&
    +           (state & ShiftMask) && xctx->semaphore <2)
        {
          break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 0);
        }
        /* select instance and connected nets NOT stopping at wire junctions */
    -   else if(button == Button3 &&  state == ShiftMask && xctx->semaphore <2)
    +   else if(!excl && button == Button3 && state == ShiftMask && xctx->semaphore <2)
        {
          Selected sel;
          sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0, NULL);
    @@ -4131,13 +4143,13 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
        }
        /* moved to Button3 release */
        /* 
    -    * else if(button == Button3 &&  state == 0 && xctx->semaphore <2) {
    +    * else if(button == Button3 && state == 0 && xctx->semaphore <2) {
         *   context_menu_action(xctx->mousex_snap, xctx->mousey_snap);
         * }
         */
     
        /* zoom rectangle by right clicking and drag */
    -   else if(button == Button3 && state == 0 && xctx->semaphore < 2) {
    +   else if(!excl && button == Button3 && state == 0 && xctx->semaphore < 2) {
          zoom_rectangle(START);return;
        }
          
    @@ -4187,18 +4199,18 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
          if(tclgetboolvar("persistent_command") && xctx->last_command) {
            if(xctx->last_command == STARTLINE)  start_line(xctx->mousex_snap, xctx->mousey_snap);
            if(xctx->last_command == STARTWIRE){
    -         if(tclgetboolvar("snap_cursor") 
    -              && (xctx->prev_snapx == xctx->mousex_snap 
    -              && xctx->prev_snapy == xctx->mousey_snap) 
    -              && (xctx->ui_state & STARTWIRE) 
    -              && xctx->closest_pin_found){
    -           new_wire(PLACE|END, xctx->mousex_snap, xctx->mousey_snap);
    -           xctx->ui_state &= ~STARTWIRE;
    -         }
    -         else
    -           start_wire(xctx->mousex_snap, xctx->mousey_snap);
    -       }
    -       return;
    +        if(tclgetboolvar("snap_cursor")
    +             && (xctx->prev_snapx == xctx->mousex_snap
    +             && xctx->prev_snapy == xctx->mousey_snap)
    +             && (xctx->ui_state & STARTWIRE)
    +             && xctx->closest_pin_found){
    +          new_wire(PLACE|END, xctx->mousex_snap, xctx->mousey_snap);
    +          xctx->ui_state &= ~STARTWIRE;
    +        }
    +        else
    +          start_wire(xctx->mousex_snap, xctx->mousey_snap);
    +      }
    +        return;
          }
          /* handle all object insertions started from Tools/Edit menu */
          if(check_menu_start_commands(c_snap, mx, my)) return;
    @@ -4207,7 +4219,7 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
          if(end_place_move_copy_zoom()) return;
     
          /* Button1Press to select objects */
    -     if( !(xctx->ui_state & STARTSELECT) && !(xctx->ui_state & STARTWIRE) && !(xctx->ui_state & STARTLINE) ) {
    +     if(!excl) {
            Selected sel;
            int already_selected = 0;
            int prev_last_sel = xctx->lastsel;
    @@ -4234,7 +4246,7 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
     
            /* find closest object. Use snap coordinates if full crosshair is enabled
             * since the mouse pointer is obscured and crosshair is snapped to grid points */
    -       if(draw_xhair) {
    +       if(draw_xhair && (use_cursor_for_sel || crosshair_size == 0)) {
              sel = find_closest_obj(xctx->mousex_snap, xctx->mousey_snap, 0);
            } else {
              sel = find_closest_obj(xctx->mousex, xctx->mousey, 0);
    @@ -4330,8 +4342,9 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
              }
            }
            return;
    -     }
    +     } /* if(!excl) */
        } /* button==Button1 */
    +   
        return;
     }
     
    @@ -4373,12 +4386,12 @@ static void handle_button_release(int event, KeySym key, int state, int button,
          xctx->semaphore = savesem;
        }
     
    -   /* end wire creation when dragging in intuitive interface from an inst pin ow wire endpoint */
    -   /*else if(state == Button1Mask && xctx->intuitive_interface 
    -    *     && (xctx->ui_state & STARTWIRE) && !(xctx->ui_state & MENUSTART)) {*/
    -   /*  if(end_place_move_copy_zoom()) break;*/
    -   /*}*/
    -
    +   /* end wire creation when dragging in intuitive interface from an inst pin or wire endpoint */
    +   else if(state == Button1Mask && xctx->intuitive_interface && !tclgetboolvar("persistent_command")
    +        && (xctx->ui_state & STARTWIRE) && !(xctx->ui_state & MENUSTART)) {
    +     if(end_place_move_copy_zoom()) return;
    +   }
    + 
        /* end intuitive_interface copy or move */
        if(xctx->ui_state & STARTCOPY && xctx->drag_elements) {
           copy_objects(END);
    @@ -4432,6 +4445,7 @@ static void handle_button_release(int event, KeySym key, int state, int button,
        }
        if(draw_xhair) draw_crosshair(3, state); /* restore crosshair when selecting / unselecting */
        if(snap_cursor && wire_draw_active) draw_snap_cursor(3);
    +
        return;
     }
     
    @@ -4471,9 +4485,10 @@ static void handle_double_click(int event, int state, KeySym key, int button,
              }
            }
          }
    -   }
    +    }
     }
     
    +
     /* main window callback */
     /* mx and my are set to the mouse coord. relative to window  */
     /* win_path: set to .drw or sub windows .x1.drw, .x2.drw, ...  */
    @@ -4493,12 +4508,12 @@ int enable_stretch = tclgetboolvar("enable_stretch");
     int draw_xhair = tclgetboolvar("draw_crosshair");
     int crosshair_size = tclgetintvar("crosshair_size");
     int infix_interface = tclgetboolvar("infix_interface");
    +int rstate; /* (reduced state, without ShiftMask) */
     int snap_cursor = tclgetboolvar("snap_cursor");
     int cadence_compat = tclgetboolvar("cadence_compat");
     int wire_draw_active = (xctx->ui_state & STARTWIRE) || 
                            ((xctx->ui_state2 & MENUSTARTWIRE) && (xctx->ui_state & MENUSTART)) || 
                            (tclgetboolvar("persistent_command") && (xctx->last_command & STARTWIRE));
    -int rstate; /* (reduced state, without ShiftMask) */
     
      /* this fix uses an alternative method for getting mouse coordinates on KeyPress/KeyRelease
       * events. Some remote connection softwares do not generate the correct coordinates
    @@ -4537,6 +4552,7 @@ int rstate; /* (reduced state, without ShiftMask) */
      } else {
         tclvareval(xctx->top_path, ".statusbar.10 configure -state normal -text { }", NULL);
      }
    +
      tclvareval(xctx->top_path, ".statusbar.7 configure -text $netlist_type", NULL);
      tclvareval(xctx->top_path, ".statusbar.3 delete 0 end;",
                          xctx->top_path, ".statusbar.3 insert 0 $cadsnap",
    @@ -4583,7 +4599,7 @@ int rstate; /* (reduced state, without ShiftMask) */
      state &= ~Mod2Mask; /* 20170511 filter out NumLock status */
      state &= ~LockMask; /* filter out Caps Lock */
      rstate = state; /* rstate does not have ShiftMask bit, so easier to test for KeyPress events */
    - rstate &= ~ShiftMask; /* don't use ShiftMask, identifying characters is sifficient */
    + rstate &= ~ShiftMask; /* don't use ShiftMask, identifying characters is sufficient */
      rstate &= ~Button1Mask; /* ignore button-1 */
      if(xctx->semaphore >= 2)
      {
    diff --git a/src/draw.c b/src/draw.c
    index b7c057dc..bee7b42b 100644
    --- a/src/draw.c
    +++ b/src/draw.c
    @@ -1591,9 +1591,9 @@ void drawarc(int c, int what, double x, double y, double r, double a, double b,
                   (int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64));
        }
     
    -   if(xctx->fill_pattern && (xctx->fill_type[c] || arc_fill == 3) ){
    +   if(xctx->fill_pattern && (xctx->fill_type[c] || arc_fill == 2) ){
     
    -     if(arc_fill & 2) gc = xctx->gc[c];
    +     if(arc_fill == 2) gc = xctx->gc[c];
          else             gc = xctx->gcstipple[c];
          if(arc_fill) {
            if(xctx->draw_window)
    @@ -1631,8 +1631,8 @@ void filledrect(int c, int what, double rectx1,double recty1,double rectx2,doubl
     
      if(!has_x) return;
      if(!xctx->fill_pattern) return;
    - if(fill != 3 && !xctx->fill_type[c]) return;
    - if(fill == 3) { /* full fill */
    + if(fill != 2 && !xctx->fill_type[c]) return;
    + if(fill == 2) { /* full fill */
        gc = xctx->gc[c];
        r = rf;
        i = &iif;
    @@ -1782,7 +1782,7 @@ void arc_bbox(double x, double y, double r, double a, double b,
     /* Convex Nonconvex Complex */
     #define Polygontype Nonconvex
     
    -/* fill = 1: stippled fill, fill == 3: solid fill */
    +/* fill = 1: stippled fill, fill == 2: solid fill */
     void drawbezier(Drawable w, GC gc, int c, double *x, double *y, int points, int fill)
     {
       const double bez_steps = 1.0/32.0; /* divide the t = [0,1] interval into 32 steps */
    @@ -1846,7 +1846,7 @@ void drawbezier(Drawable w, GC gc, int c, double *x, double *y, int points, int
       XDrawLines(display, w, gc, p, i, CoordModeOrigin);
       if(fill == 1) 
         XFillPolygon(display, w, xctx->gcstipple[c], p, i, Polygontype, CoordModeOrigin);
    -  else if(fill==3) 
    +  else if(fill==2) 
         XFillPolygon(display, w, xctx->gc[c], p, i, Polygontype, CoordModeOrigin);
     }
     
    @@ -1882,7 +1882,7 @@ void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fil
           for(i=0;ifill_pattern && ((xctx->fill_type[c] && poly_fill == 1) || poly_fill == 3 ) &&
    +  fill = xctx->fill_pattern && ((xctx->fill_type[c] && poly_fill == 1) || poly_fill == 2 ) &&
              (x[0] == x[points-1]) && (y[0] == y[points-1]);
       bezier = (flags & 1)  && (points > 2);
       if(dash) {
    @@ -1893,19 +1893,19 @@ void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fil
       }
       if(xctx->draw_window) {
         if(bezier) {
    -      drawbezier(xctx->window, xctx->gc[c], c, x, y, points, fill | (poly_fill & 2) );
    +      drawbezier(xctx->window, xctx->gc[c], c, x, y, points, fill ? poly_fill : 0 );
         } else {
           XDrawLines(display, xctx->window, xctx->gc[c], p, points, CoordModeOrigin);
         }
       }
       if(xctx->draw_pixmap) {
         if(bezier) {
    -      drawbezier(xctx->save_pixmap, xctx->gc[c], c, x, y, points, fill | (poly_fill & 2) );
    +      drawbezier(xctx->save_pixmap, xctx->gc[c], c, x, y, points, fill ? poly_fill : 0);
         } else {
           XDrawLines(display, xctx->save_pixmap, xctx->gc[c], p, points, CoordModeOrigin);
         }
       }
    -  if(poly_fill & 2) gc = xctx->gc[c];
    +  if(poly_fill == 2) gc = xctx->gc[c];
       else              gc = xctx->gcstipple[c];
       if(fill && !bezier) {
         if(xctx->draw_window)
    @@ -2836,9 +2836,9 @@ static void draw_graph_grid(Graph_ctx *gr, void *ct)
     
       /* clipping everything outside container area */
       /* background */
    -  filledrect(0, NOW, gr->rx1, gr->ry1, gr->rx2, gr->ry2, 3, -1, -1);
    +  filledrect(0, NOW, gr->rx1, gr->ry1, gr->rx2, gr->ry2, 2, -1, -1);
       /* graph bounding box */
    -  drawrect(GRIDLAYER, NOW, gr->rx1, gr->ry1, gr->rx2, gr->ry2, 2, -1, -1);
    +  drawrect(GRIDLAYER, NOW, gr->rx1, gr->ry1, gr->rx2, gr->ry2, 0, -1, -1);
     
       bbox(START, 0.0, 0.0, 0.0, 0.0);
       bbox(ADD, gr->rx1, gr->ry1, gr->rx2, gr->ry2);
    @@ -3133,7 +3133,7 @@ static void draw_cursor(double active_cursorx, double other_cursorx, int cursor_
         else
            my_snprintf(tmpstr, S(tmpstr), "%s",  dtoa_eng(active_cursorx));
         text_bbox(tmpstr, txtsize, txtsize, 2, flip, 0, 0, xx + xoffs, gr->ry2-1, &tx1, &ty1, &tx2, &ty2, &tmp, &dtmp);
    -    filledrect(0, NOW,  tx1, ty1, tx2, ty2, 3, -1, -1);
    +    filledrect(0, NOW,  tx1, ty1, tx2, ty2, 2, -1, -1);
         draw_string(cursor_color, NOW, tmpstr, 2, flip, 0, 0, xx + xoffs, gr->ry2-1, txtsize, txtsize);
       }
     }
    @@ -3198,7 +3198,7 @@ static void draw_hcursor(double active_cursory, int cursor_color, Graph_ctx *gr)
         th = (ty2 - ty1) / 2.; /* half text height */
         ty1 -= th;
         ty2 -= th;
    -    filledrect(0, NOW,  tx1, ty1, tx2, ty2, 3, -1, -1);
    +    filledrect(0, NOW,  tx1, ty1, tx2, ty2, 2, -1, -1);
         draw_string(cursor_color, NOW, tmpstr, 0, 0, 0, 0, gr->rx1 + 5, yy - th, txtsize, txtsize);
       }
     }
    @@ -3230,7 +3230,7 @@ static void draw_hcursor_difference(double c1, double c2, Graph_ctx *gr)
          my_snprintf(tmpstr, S(tmpstr), " %s ",  dtoa_eng(diffh));
       text_bbox(tmpstr, txtsize, txtsize, 0, 0, 0, 1, xx, yy, &tx1, &ty1, &tx2, &ty2, &tmp, &dtmp);
       if( 2 * (ty2 - ty1) < diff ) {
    -    filledrect(0, NOW,  tx1, ty1, tx2, ty2, 3, -1, -1);
    +    filledrect(0, NOW,  tx1, ty1, tx2, ty2, 2, -1, -1);
         draw_string(3, NOW, tmpstr, 0, 0, 0, 1, xx, yy, txtsize, txtsize);
         if( a > b) {
           dtmp = a; a = b; b = dtmp;
    @@ -3487,10 +3487,12 @@ int edit_wave_attributes(int what, int i, Graph_ctx *gr)
               } else {
                  if(gr->hilight_wave == wcnt) {
                    gr->hilight_wave = -1;
    -               my_strdup2(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
    +               my_strdup2(_ALLOC_ID_, &r->prop_ptr,
    +                          subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
                  } else {
                    gr->hilight_wave = wcnt;
    -               my_strdup2(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
    +               my_strdup2(_ALLOC_ID_, &r->prop_ptr,
    +                          subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
                  }
               }
             }
    @@ -3512,10 +3514,12 @@ int edit_wave_attributes(int what, int i, Graph_ctx *gr)
             } else {
               if(gr->hilight_wave == wcnt) {
                 gr->hilight_wave = -1;
    -            my_strdup2(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
    +            my_strdup2(_ALLOC_ID_, &r->prop_ptr,
    +                       subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
               } else {
                 gr->hilight_wave = wcnt;
    -            my_strdup2(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
    +            my_strdup2(_ALLOC_ID_, &r->prop_ptr,
    +                       subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
               }
             }
           }
    @@ -4472,7 +4476,7 @@ static cairo_surface_t *get_surface_from_file(const char *filename, const char *
         }
         filesize = (size_t)buf.st_size;
         if(filesize > 0) {
    -      fd = fopen(filename, fopen_read_mode);
    +      fd = my_fopen(filename, fopen_read_mode);
           if(fd) {
             size_t bytes_read;
             filedata = my_malloc(_ALLOC_ID_, filesize);
    @@ -4530,7 +4534,7 @@ static cairo_surface_t *get_surface_from_file(const char *filename, const char *
             #endif
           }
           if(!surface || cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
    -        if(jpg != 1) dbg(0, "draw_image(): failure creating image surface from %s\n", filename);
    +        if(jpg != 1) dbg(0, "get_surface_from_file(): failure creating image surface from %s\n", filename);
             if(surface) cairo_surface_destroy(surface);
             my_free(_ALLOC_ID_, &closure.buffer);
             *buffer = NULL;
    @@ -4732,7 +4736,7 @@ int draw_image(int dr, xRect *r, double *x1, double *y1, double *x2, double *y2,
         cairo_translate(xctx->cairo_ctx, x, y);
         cairo_rotate(xctx->cairo_ctx, rot * XSCH_PI * 0.5);
         if(flip && (rot == 0 || rot == 2)) cairo_scale(xctx->cairo_ctx, -scalex, scaley);
    -    else if(flip && (rot == 1 || rot == 3)) cairo_scale(xctx->cairo_ctx, scalex, -scaley);
    +    else if(flip && (rot == 1 || rot == 3)) cairo_scale(xctx->cairo_ctx, -scalex, scaley);
         else cairo_scale(xctx->cairo_ctx, scalex, scaley);
         cairo_set_source_surface(xctx->cairo_ctx, emb_ptr->image, 0. , 0.);
         cairo_rectangle(xctx->cairo_ctx, 0, 0, w , h );
    @@ -4986,7 +4990,7 @@ void draw(void)
                 draw_symbol(ADD, cc, i,c, 0, 0, 0.0, 0.0);     /* ... then draw current layer      */
             }
           }
    -      filledrect(cc, END, 0.0, 0.0, 0.0, 0.0, 3, -1, -1); /* last parameter must be 3! */
    +      filledrect(cc, END, 0.0, 0.0, 0.0, 0.0, 2, -1, -1); /* fill parameter must be 2! */
           drawarc(cc, END, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0);
           drawrect(cc, END, 0.0, 0.0, 0.0, 0.0, 0, -1, -1);
           drawline(cc, END, 0.0, 0.0, 0.0, 0.0, 0, NULL);
    @@ -5013,7 +5017,7 @@ void draw(void)
                 xctx->wire[i].x2,xctx->wire[i].y2, 0, NULL);
           }
           update_conn_cues(cc, 1, xctx->draw_window);
    -      filledrect(cc, END, 0.0, 0.0, 0.0, 0.0, 3, -1, -1); /* fill parameter must be 3! */
    +      filledrect(cc, END, 0.0, 0.0, 0.0, 0.0, 2, -1, -1); /* fill parameter must be 2! */
           drawline(cc, END, 0.0, 0.0, 0.0, 0.0, 0, NULL);
         }
         if(xctx->draw_single_layer ==-1 || xctx->draw_single_layer==TEXTLAYER) {
    diff --git a/src/editprop.c b/src/editprop.c
    index 44a5d8e0..3a7f9323 100644
    --- a/src/editprop.c
    +++ b/src/editprop.c
    @@ -586,6 +586,19 @@ char *dtoa_prec(double i)
       return s;
     }
     
    +FILE *my_fopen(const char *f, const char *m)
    +{
    +  struct stat buf;
    +  FILE *fd = NULL;
    +  int st;
    +
    +  st = stat(f, &buf);
    +  if(st) return NULL; /* not existing or error */
    +  if(!S_ISREG(buf.st_mode)) return NULL; /* not a regular file/symlink to a regular file */
    +  fd = fopen(f, m);
    +  return fd;
    +}
    +
     size_t my_mstrcat(int id, char **str, const char *add, ...)
     {
       va_list args;
    @@ -1020,7 +1033,7 @@ static int edit_rect_property(int x)
           }
     
           attr = get_tok_value(xctx->rect[c][n].prop_ptr,"fill", 0);
    -      if(!strcmp(attr, "full")) xctx->rect[c][n].fill = 3;
    +      if(!strcmp(attr, "full")) xctx->rect[c][n].fill = 2;
           else if(!strboolcmp(attr, "false")) xctx->rect[c][n].fill = 0;
           else xctx->rect[c][n].fill = 1;
     
    @@ -1203,11 +1216,11 @@ static int edit_arc_property(void)
          old_fill = xctx->arc[c][i].fill;
          fill_ptr = get_tok_value(xctx->arc[c][i].prop_ptr,"fill",0);
          if( !strcmp(fill_ptr,"full") )
    -       xctx->arc[c][i].fill =3; /* bit 1: solid fill (not stippled) */
    +       xctx->arc[c][i].fill = 2; /* bit 1: solid fill (not stippled) */
          else if( !strboolcmp(fill_ptr,"true") )
    -       xctx->arc[c][i].fill =1;
    +       xctx->arc[c][i].fill = 1;
          else
    -       xctx->arc[c][i].fill =0;
    +       xctx->arc[c][i].fill = 0;
          old_dash = xctx->arc[c][i].dash;
          dash = get_tok_value(xctx->arc[c][i].prop_ptr,"dash",0);
          if( strcmp(dash, "") ) {
    @@ -1281,11 +1294,11 @@ static int edit_polygon_property(void)
     
          fill_ptr = get_tok_value(xctx->poly[c][i].prop_ptr,"fill",0);
          if( !strcmp(fill_ptr,"full") )
    -       xctx->poly[c][i].fill =3; /* bit 1: solid fill (not stippled) */
    +       xctx->poly[c][i].fill = 2; /* bit 1: solid fill (not stippled) */
          else if( !strboolcmp(fill_ptr,"true") )
    -       xctx->poly[c][i].fill =1;
    +       xctx->poly[c][i].fill = 1;
          else
    -       xctx->poly[c][i].fill =0;
    +       xctx->poly[c][i].fill = 0;
          dash = get_tok_value(xctx->poly[c][i].prop_ptr,"dash",0);
          if( strcmp(dash, "") ) {
            int d = atoi(dash);
    diff --git a/src/eval_expr.y b/src/eval_expr.y
    index ba954f26..5198718f 100644
    --- a/src/eval_expr.y
    +++ b/src/eval_expr.y
    @@ -2,7 +2,6 @@
     #include 
     #include   /* For math functions, cos(), sin(), etc. */
     #include 
    -#include 
     #include 
     #include 
     #include "xschem.h"
    @@ -16,7 +15,8 @@ static int dbglev = 1;
     struct symrec
     {
       char *name;  /* name of symbol */
    -  double (*fnctptr)();  /* value of a FNCT */
    +  double (*fnctptr)(double);  /* value of a FNCT */
    +  double value;
       struct symrec *next;    /* link field */
     };
     
    @@ -32,30 +32,42 @@ static void kkerror(char *s);
     static double toint(double x);
     static void get_expr(double x);
     static void get_char(int c);
    +static double rnd6(double x) {return round_to_n_digits(x, 6);}
     
     struct fn
     {
       char *fname;
       double (*fnct)();
    +  double value;
     };
     static int lex_state = 0;
     struct fn fn_array[]
       = {
    -      {"int" , toint},
    -      {"sin" , sin},
    -      {"cos" , cos},
    -      {"asin", asin},
    -      {"acos", acos},
    -      {"atan", atan},
    -      {"log"  , log10},
    -      {"ln"  , log},
    -      {"exp" , exp},
    -      {"sqrt", sqrt},
    -      {0     , 0}
    +      {"int"      , toint, 0},
    +      {"sin"      , sin, 0},
    +      {"cos"      , cos, 0},
    +      {"exp"      , exp, 0},
    +      {"asin"     , asin, 0},
    +      {"acos"     , acos, 0},
    +      {"atan"     , atan, 0},
    +      {"log"      , log10, 0},
    +      {"ln"       , log, 0},
    +      {"exp"      , exp, 0},
    +      {"sqrt"     , sqrt, 0},
    +      {"round"    , rnd6, 0},
    +      {"pi"       , NULL, 3.141592653589793},
    +      {"e"        , NULL, 2.718281828459045},
    +      {"k"        , NULL, 1.380649e-23},
    +      {"h"        , NULL, 6.62607e-34},
    +      {"echarge"  , NULL, 1.60217646e-19},
    +      {"abszero"  , NULL, 273.15},
    +      {"c"        , NULL, 2.99792458e8},
    +      {0          , 0, 0}
         };
     %}
     
    -%define api.prefix {kk}
    +
    +/* %define api.prefix {kk} */
     %union {
     int          c;
     double     val; /* For returning numbers. */
    @@ -63,7 +75,7 @@ symrec  *tptr; /* For returning symbol-table pointers */
     }
     
     %token STREND 0
    -%token  CHAR
    +%token  XCHAR
     %token EXPR       /* expr( */
     %token   NUM /* Simple double precision number */
     %token  FNCT /* Variable and Function */
    @@ -81,14 +93,15 @@ input:
     ;
     
     line:   
    -          CHAR                    {get_char($1);}
    +          XCHAR                   {get_char($1);}
             | EXPR exp ')'            {get_expr($2);lex_state = 0;}
             | EXPR '\'' exp '\'' ')'  {get_expr($3);lex_state = 0;}
             | EXPR exp error          
     ;
     
     exp:      NUM                     {$$ = $1;}
    -        | FNCT '(' exp ')'        {$$ = $1 ? (*($1->fnctptr))($3) : 0.0;}
    +        | FNCT '(' exp ')'        {$$ = $1 ? ($1->fnctptr ? (*($1->fnctptr))($3) : 0.0) : 0.0;}
    +        | FNCT                    {$$ = $1 ? $1->value : 0.0;}
             | exp '+' exp             {$$ = $1 + $3;		 }
             | exp '-' exp             {$$ = $1 - $3;}
             | exp '*' exp             {$$ = $1 * $3;}
    @@ -188,18 +201,21 @@ void eval_expr_init_table(void)  /* puts arithmetic functions in table. */
       {
         ptr = putsym (fn_array[i].fname);
         ptr->fnctptr = fn_array[i].fnct;
    +    ptr->value = fn_array[i].value;
       }
     }
     
     void eval_expr_clear_table(void)
     {
    -  symrec *ptr;
    -  for (ptr = sym_table; ptr; ptr = ptr->next) {
    +  symrec *ptr = sym_table;
    +  while(ptr) {
         symrec *tmp = ptr;
    +    ptr = ptr->next;
         my_free(_ALLOC_ID_, &(tmp->name));
         my_free(_ALLOC_ID_, &tmp);
       }
     }
    +    
     
     static int kklex()
     {
    @@ -216,8 +232,8 @@ static int kklex()
         c = *str++;
         if(c) {
           kklval.c = c;
    -      dbg(dbglev, "lex(): CHAR; %c\n", c);
    -      return CHAR;
    +      dbg(dbglev, "lex(): XCHAR; %c\n", c);
    +      return XCHAR;
         } else {
          dbg(dbglev, "lex(): STREND\n");
          return STREND;
    @@ -237,7 +253,7 @@ static int kklex()
         str--; 
     
         sscanf(str, "%99[.0-9a-zA-Z_]%n", s, &rd);
    -    kklval.val = atof_spice(s);
    +    kklval.val = atof_eng(s);
         str += rd;
         dbg(dbglev, "lex(): NUM: %s\n", s);
         return NUM;
    diff --git a/src/hilight.c b/src/hilight.c
    index 19c18a34..f7081c33 100644
    --- a/src/hilight.c
    +++ b/src/hilight.c
    @@ -696,7 +696,7 @@ static int bus_search(const char*s)
     }
     
     #ifndef __unix__
    -static int win_regexec(const char *options, const char *pattern, const char *name) 
    +int win_regexec(const char *options, const char *pattern, const char *name) 
     {
       if (options!=NULL)
         tclvareval("regexp {", options,"} {", pattern, "} {", name, "}", NULL);
    @@ -754,7 +754,7 @@ int search(const char *tok, const char *val, int sub, int sel, int match_case)
      if(regcomp(&re, val , cflags)) return TCL_ERROR;
      #else 
      if(!match_case) {
    -   regexp_options = "-nocase";
    +   my_strdup(_ALLOC_ID_, ®exp_options, "-nocase");
      }
      #endif
      dbg(1, "search():val=%s\n", val);
    @@ -1014,6 +1014,8 @@ int search(const char *tok, const char *val, int sub, int sel, int match_case)
      }
      #ifdef __unix__
      regfree(&re);
    +#else
    + my_free(_ALLOC_ID_, ®exp_options);
      #endif
      xctx->draw_window = save_draw;
      my_free(_ALLOC_ID_, &tmpname);
    @@ -2224,7 +2226,7 @@ void draw_hilight_net(int on_window)
               ((c==TEXTWIRELAYER || c==TEXTLAYER) && symptr->texts)) {
             draw_symbol(ADD, col, i,c,0,0,0.0,0.0);
           }
    -      filledrect(col, END, 0.0, 0.0, 0.0, 0.0, 3, -1, -1); /* last parameter must be 3! */
    +      filledrect(col, END, 0.0, 0.0, 0.0, 0.0, 2, -1, -1); /* last parameter must be 2! */
           drawarc(col, END, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0);
           drawrect(col, END, 0.0, 0.0, 0.0, 0.0, 0, -1, -1);
           drawline(col, END, 0.0, 0.0, 0.0, 0.0, 0, NULL);
    diff --git a/src/netlist.c b/src/netlist.c
    index 4180d46d..afa7f5b0 100644
    --- a/src/netlist.c
    +++ b/src/netlist.c
    @@ -1665,8 +1665,7 @@ int sym_vs_sch_pins(int all)
           /* pass through symbols, duplicated pins: do not check with schematic */
           if(rects > unique_pins) continue;
           get_sch_from_sym(filename, xctx->sym + i, -1, 0);
    -      if(!stat(filename, &buf)) {
    -        fd = fopen(filename, "r");
    +      if(!stat(filename, &buf) && (fd = my_fopen(filename, fopen_read_mode))) {
             pin_cnt = 0;
             endfile = 0;
             f_version[0] = '\0';
    diff --git a/src/options.c b/src/options.c
    index e2872111..732cc3ed 100644
    --- a/src/options.c
    +++ b/src/options.c
    @@ -111,10 +111,11 @@ static void check_opt(char *opt, char *optval, int type)
         } else if( (type == SHORT && *opt == 'l') || (type == LONG && !strcmp("log", opt)) ) {
             if(optval) {
               errfp = fopen(optval, "w");
    -          setvbuf(errfp, NULL, _IOLBF, 0); /* line (_IOLBF) or disable (_IONBF) buffering on error log */
               if(!errfp) {
                 errfp = stderr;
                 dbg(0, "Problems opening log file: %s\n", optval);
    +          } else {
    +            setvbuf(errfp, NULL, _IOLBF, 0); /* line (_IOLBF) or disable (_IONBF) buffering on error log */
               }
             }
         } else if( (type == SHORT && *opt == 'o') || (type == LONG && !strcmp("netlist_path", opt)) ) {
    diff --git a/src/paste.c b/src/paste.c
    index 125905e9..7ed3c536 100644
    --- a/src/paste.c
    +++ b/src/paste.c
    @@ -120,11 +120,11 @@ static void merge_box(FILE *fd)
     
         fill_ptr = get_tok_value(ptr[i].prop_ptr,"fill",0);
         if( !strcmp(fill_ptr, "full") )
    -      ptr[i].fill =3;
    +      ptr[i].fill = 2;
         else if( !strboolcmp(fill_ptr, "false") )
    -      ptr[i].fill =0;
    +      ptr[i].fill = 0;
         else
    -      ptr[i].fill =1;
    +      ptr[i].fill = 1;
         set_rect_flags(&xctx->rect[c][i]); /* set cached .flags bitmask from on attributes */
         select_box(c,i, SELECTED, 1, 1);
         xctx->rects[c]++;
    @@ -159,11 +159,11 @@ static void merge_arc(FILE *fd)
     
         fill_ptr = get_tok_value(ptr[i].prop_ptr,"fill",0);
         if( !strcmp(fill_ptr, "full") )
    -      ptr[i].fill =3; /* bit 1: solid fill (not stippled) */
    +      ptr[i].fill = 2; /* bit 1: solid fill (not stippled) */
         else if( !strboolcmp(fill_ptr, "true") )
    -      ptr[i].fill =1;
    +      ptr[i].fill = 1;
         else
    -      ptr[i].fill =0;
    +      ptr[i].fill = 0;
         dash = get_tok_value(ptr[i].prop_ptr,"dash",0);
         if(strcmp(dash, "")) {
           int d = atoi(dash);
    @@ -219,11 +219,11 @@ static void merge_polygon(FILE *fd)
         load_ascii_string( &ptr[i].prop_ptr, fd);
         fill_ptr = get_tok_value(ptr[i].prop_ptr,"fill",0);
         if( !strcmp(fill_ptr, "full") )
    -      ptr[i].fill =3; /* bit 1: solid fill (not stippled) */
    +      ptr[i].fill = 2; /* bit 1: solid fill (not stippled) */
         else if( !strboolcmp(fill_ptr, "true") )
    -      ptr[i].fill =1;
    +      ptr[i].fill = 1;
         else
    -      ptr[i].fill =0;
    +      ptr[i].fill = 0;
         dash = get_tok_value(ptr[i].prop_ptr,"dash",0);
         if(strcmp(dash, "")) {
           int d = atoi(dash);
    @@ -379,7 +379,7 @@ void merge_file(int selection_load, const char ext[])
             my_free(_ALLOC_ID_, &cmd);
           } else fd = NULL;
         } else {
    -      fd=fopen(name, fopen_read_mode);
    +      fd=my_fopen(name, fopen_read_mode);
         }
         if(fd) {
          xctx->prep_hi_structs=0;
    diff --git a/src/psprint.c b/src/psprint.c
    index 295ed1ed..3332aeb8 100644
    --- a/src/psprint.c
    +++ b/src/psprint.c
    @@ -301,7 +301,6 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
       rwi = (int)(rw * scale + 1.0);
       rhi = (int)(rh * scale + 1.0);
       dbg(1, "graph size: %dx%d\n", rwi, rhi);
    -  dbg(1, "ps_embedded_graph: saving zoom\n");
       save_restore_zoom(1, &zi);
       set_viewport_size(rwi, rhi, xctx->lw);
     
    @@ -354,7 +353,6 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
       cairo_surface_destroy(png_sfc);
       xctx->draw_pixmap = 1;
       tclsetboolvar("draw_grid", save_draw_grid);
    -  dbg(1, "ps_embedded_graph: restoring zoom\n");
       save_restore_zoom(0, &zi);
       resetwin(1, 1, 1, 0, 0);
       change_linewidth(xctx->lw);
    @@ -445,11 +443,27 @@ static void ps_xdrawpoint(int layer, double x1, double y1)
      fprintf(fd, "%g %g %g %g L\n", x1, y1,x1,y1);
     }
     
    -static void ps_xfillrectange(int layer, double x1, double y1, double x2,
    +/* fill_pattern:
    + * 0 : no fill
    + * 1 : stippled fill
    + * 2 : solid fill
    + *
    + * fill_type[i]: 
    + * 0 : no fill
    + * 1 : patterned (stippled) fill
    + * 2 : solid fill
    + *
    + * fill:
    + * 0 : no fill
    + * 1 : stippled fill
    + * 2 : solid fill
    + */
    +
    +static void ps_xfillrectangle(int layer, double x1, double y1, double x2,
                       double y2, int fill)
     {
      fprintf(fd, "%g %g %g %g R\n", x1,y1,x2-x1,y2-y1);
    - if(fill &&  (xctx->fill_type[layer] == 1) && xctx->fill_pattern) {
    + if(xctx->fill_pattern && xctx->fill_type[layer] && fill) {
        fprintf(fd, "%g %g %g %g RF\n", x1,y1,x2-x1,y2-y1);
        /* fprintf(fd,"fill\n"); */
      }
    @@ -547,7 +561,8 @@ static void ps_drawpolygon(int c, int what, double *x, double *y, int points, in
     }
     
     
    -static void ps_filledrect(int gc, double rectx1,double recty1,double rectx2,double recty2, int dash, int fill)
    +static void ps_filledrect(int gc, double rectx1,double recty1,double rectx2,double recty2,
    +     int dash, int fill, int e_a, int e_b)
     {
      double x1,y1,x2,y2, tmp;
      double psdash;
    @@ -562,7 +577,21 @@ static void ps_filledrect(int gc, double rectx1,double recty1,double rectx2,doub
         if(dash) {
           fprintf(fd, "[%g %g] 0 setdash\n", psdash, psdash);
         }
    -    ps_xfillrectange(gc, x1,y1,x2,y2, fill);
    +    if(e_a != -1) {
    +      double rx = (x2 - x1) / 2.0;
    +      double ry = (y2 - y1) / 2.0;
    +      double cx = (x2 + x1) / 2.0;
    +      double cy = (y2 + y1) / 2.0;
    +
    +      if(xctx->fill_pattern && xctx->fill_type[gc] && fill) {
    +        fprintf(fd, "%g %g MT %g %g %g %g %d %d E %g %g LT C F S\n",
    +                    cx, cy, cx, cy, rx, ry, -e_a, -e_a-e_b, cx, cy);
    +      } else {
    +        fprintf(fd, "%g %g %g %g %d %d E S\n", cx, cy, rx, ry, -e_a, -e_a-e_b);
    +      }
    +    } else {
    +      ps_xfillrectangle(gc, x1,y1,x2,y2, fill);
    +    }
         if(dash) {
           fprintf(fd, "[] 0 setdash\n");
         }
    @@ -937,7 +966,7 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho
         #endif
         else if((xctx->inst[n].x2 - xctx->inst[n].x1) * xctx->mooz < 3 &&
                            (xctx->inst[n].y2 - xctx->inst[n].y1) * xctx->mooz < 3) {
    -      ps_filledrect(c, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 0, 0);
    +      ps_filledrect(c, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 0, 0, -1, -1);
           xctx->inst[n].flags|=1;
           return;
         }
    @@ -946,7 +975,7 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho
         }
         if(hide) {
           int color = (disabled==1) ? GRIDLAYER : (disabled == 2) ? PINLAYER : SYMLAYER;
    -      ps_filledrect(color, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 2, 0);
    +      ps_filledrect(color, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 2, 0, -1, -1);
         }
         /* pdfmarks, only if doing hierarchy print and if symbol has a subcircuit */ 
         if(what != 7) {
    @@ -1033,6 +1062,7 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho
     
       if( (!hide && xctx->enable_layer[layer]) ||
           (hide && layer == PINLAYER && xctx->enable_layer[layer]) ) {
    +    if(symptr->rects[layer]) fprintf(fd, "NP\n"); /* newpath */
         for(j=0;j< symptr->rects[layer]; ++j)
         {
            int dash;
    @@ -1044,9 +1074,27 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho
            if (layer == GRIDLAYER && rect->flags & 1024) /* image */
            {
              ps_embedded_image(rect, x0 + x1, y0 + y1, x0 + x2, y0 + y2, rot, flip);
    -         continue;
    +       } else {
    +         int ellipse_a = rect->ellipse_a;
    +         int ellipse_b = rect->ellipse_b;
    +      
    +         if(ellipse_a != -1 && ellipse_b != 360) {
    +           if(flip) {
    +             ellipse_a = 180 - ellipse_a - ellipse_b;
    +           }
    +           if(rot) {
    +             if(rot == 3) {
    +               ellipse_a += 90;
    +             } else if(rot == 2) {
    +               ellipse_a += 180;
    +             } else if(rot == 1) {
    +               ellipse_a += 270;
    +             }
    +             ellipse_a %= 360;
    +           }
    +         }              
    +         ps_filledrect(c, x0+x1, y0+y1, x0+x2, y0+y2, dash, rect->fill, ellipse_a, ellipse_b);
            }
    -       ps_filledrect(c, x0+x1, y0+y1, x0+x2, y0+y2, dash, rect->fill);
         }
       } /* if( (!hide && xctx->enable_layer[layer]) || ... */
       
    @@ -1192,83 +1240,78 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
       old_grid=tclgetboolvar("draw_grid");
       tclsetvar("draw_grid", "0");
     
    +  /* xschem window aspect ratio decides if portrait or landscape */
    +  boundbox.x1 = xctx->areax1;
    +  boundbox.x2 = xctx->areax2;
    +  boundbox.y1 = xctx->areay1;
    +  boundbox.y2 = xctx->areay2;
    +  dx=boundbox.x2-boundbox.x1;
    +  dy=boundbox.y2-boundbox.y1;
    +
    +  /* xschem drawing bbox decides if portrait or landscape */
    +  if(fullzoom == 1) {
    +    calc_drawing_bbox(&boundbox, 0);
    +    dx=boundbox.x2-boundbox.x1;
    +    dy=boundbox.y2-boundbox.y1;
    +  }
    +  if(dx >= dy) {
    +    landscape = 1;
    +  } else {
    +    landscape = 0;
    +  }
    +  dbg(1, "dx=%g, dy=%g\n", dx, dy);
     
     
    -  if(!(what & 4)) {
    -    /* xschem window aspect ratio decides if portrait or landscape */
    +  if(fullzoom == 1) {
    +    /* save size and zoom factor */
    +    save_restore_zoom(1, &zi);
    +    /* this zoom only done to reset lw */
    +    zoom_full(0, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
    +    /* adjust aspect ratio to paper size */
    +    if(landscape) 
    +      xctx->xrect[0].height = (short unsigned int) (xctx->xrect[0].width * pagey / pagex);
    +    else
    +      xctx->xrect[0].width = (short unsigned int) (xctx->xrect[0].height * pagey / pagex);
    +    dbg(1, "xrect.width=%d, xrect.height=%d\n", xctx->xrect[0].width, xctx->xrect[0].height);
    +    xctx->areax1 = -2*INT_WIDTH(xctx->lw);
    +    xctx->areay1 = -2*INT_WIDTH(xctx->lw);
    +    xctx->areax2 = xctx->xrect[0].width+2*INT_WIDTH(xctx->lw);
    +    xctx->areay2 = xctx->xrect[0].height+2*INT_WIDTH(xctx->lw);
    +    xctx->areaw = xctx->areax2-xctx->areax1;
    +    xctx->areah = xctx->areay2 - xctx->areay1;
    +    dbg(1, "dx=%g, dy=%g\n", dx, dy);
    +    /* fit schematic into adjusted size */
    +    zoom_full(0, 0, 0 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
         boundbox.x1 = xctx->areax1;
         boundbox.x2 = xctx->areax2;
         boundbox.y1 = xctx->areay1;
         boundbox.y2 = xctx->areay2;
         dx=boundbox.x2-boundbox.x1;
         dy=boundbox.y2-boundbox.y1;
    -  
    -    /* xschem drawing bbox decides if portrait or landscape */
    -    if(fullzoom == 1) {
    -      calc_drawing_bbox(&boundbox, 0);
    -      dx=boundbox.x2-boundbox.x1;
    -      dy=boundbox.y2-boundbox.y1;
    -    }
    -    if(dx >= dy) {
    -      landscape = 1;
    +  }
    +
    +  if(!landscape) { /* decide paper orientation for best schematic fit */
    +    double tmp;
    +    tmp = pagex;
    +    pagex = pagey;
    +    pagey = tmp;
    +  }
    +  if(fullzoom == 2) { /* set media size to bbox */
    +    double sc;
    +    my_strncpy(papername, "bbox", S(papername));
    +    pagex = xctx->xrect[0].width;
    +    pagey = xctx->xrect[0].height;
    +    if(pagex > pagey) {
    +      sc = 842. / pagex;
    +      pagex = my_round(pagex * sc);
    +      pagey = my_round(pagey * sc);
         } else {
    -      landscape = 0;
    +      sc = 842. / pagey;
    +      pagex = my_round(pagex * sc);
    +      pagey = my_round(pagey * sc);
         }
    -    dbg(1, "dx=%g, dy=%g\n", dx, dy);
    -  
    -  
    -    if(fullzoom == 1) {
    -      /* save size and zoom factor */
    -      dbg(1, "create_ps: saving zoom\n");
    -      save_restore_zoom(1, &zi);
    -      /* this zoom only done to reset lw */
    -      zoom_full(0, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
    -      /* adjust aspect ratio to paper size */
    -      if(landscape) 
    -        xctx->xrect[0].height = (short unsigned int) (xctx->xrect[0].width * pagey / pagex);
    -      else
    -        xctx->xrect[0].width = (short unsigned int) (xctx->xrect[0].height * pagey / pagex);
    -      dbg(1, "xrect.width=%d, xrect.height=%d\n", xctx->xrect[0].width, xctx->xrect[0].height);
    -      xctx->areax1 = -2*INT_WIDTH(xctx->lw);
    -      xctx->areay1 = -2*INT_WIDTH(xctx->lw);
    -      xctx->areax2 = xctx->xrect[0].width+2*INT_WIDTH(xctx->lw);
    -      xctx->areay2 = xctx->xrect[0].height+2*INT_WIDTH(xctx->lw);
    -      xctx->areaw = xctx->areax2-xctx->areax1;
    -      xctx->areah = xctx->areay2 - xctx->areay1;
    -      dbg(1, "dx=%g, dy=%g\n", dx, dy);
    -      /* fit schematic into adjusted size */
    -      zoom_full(0, 0, 0 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
    -      boundbox.x1 = xctx->areax1;
    -      boundbox.x2 = xctx->areax2;
    -      boundbox.y1 = xctx->areay1;
    -      boundbox.y2 = xctx->areay2;
    -      dx=boundbox.x2-boundbox.x1;
    -      dy=boundbox.y2-boundbox.y1;
    -    }
    -  
    -    if(!landscape) { /* decide paper orientation for best schematic fit */
    -      double tmp;
    -      tmp = pagex;
    -      pagex = pagey;
    -      pagey = tmp;
    -    }
    -    if(fullzoom == 2) { /* set media size to bbox */
    -      double sc;
    -      my_strncpy(papername, "bbox", S(papername));
    -      pagex = xctx->xrect[0].width;
    -      pagey = xctx->xrect[0].height;
    -      if(pagex > pagey) {
    -        sc = 842. / pagex;
    -        pagex = my_round(pagex * sc);
    -        pagey = my_round(pagey * sc);
    -      } else {
    -        sc = 842. / pagey;
    -        pagex = my_round(pagex * sc);
    -        pagey = my_round(pagey * sc);
    -      }
    -      margin = 0.0;
    -    }
    -  } /* if(!(what & 4)) */
    +    margin = 0.0;
    +  }
         
       if(what & 1) {/* prolog */
         dbg(1, "ps_draw(): bbox: x1=%g y1=%g x2=%g y2=%g\n", boundbox.x1, boundbox.y1, boundbox.x2, boundbox.y2);
    @@ -1338,9 +1381,23 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
         fprintf(fd,"/C {closepath} bind def\n");
         fprintf(fd,"/F {fill} bind def\n");
         fprintf(fd,"/RF {rectfill} bind def\n");
    +    fprintf(fd,"/E {\n"); /* function for drawing ellipses */
    +    fprintf(fd,"/endangle exch def\n");
    +    fprintf(fd,"/startangle exch def\n");
    +    fprintf(fd,"/yrad exch def\n");
    +    fprintf(fd,"/xrad exch def\n");
    +    fprintf(fd,"/y exch def\n");
    +    fprintf(fd,"/x exch def\n");
    +    fprintf(fd,"/savematrix matrix currentmatrix def\n");
    +    fprintf(fd,"x y translate\n");
    +    fprintf(fd,"xrad yrad scale\n");
    +    fprintf(fd,"0 0 1 startangle endangle arcn\n");
    +    fprintf(fd,"savematrix setmatrix\n");
    +    fprintf(fd,"} def %% ellipse\n");
         fprintf(fd, "%%%%EndProlog\n");
       }
     
    +
       if(what & 2) { /* page */
         ++numpages;
     
    @@ -1381,6 +1438,7 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
           for(i=0;ilines[c]; ++i)
             ps_drawline(c, xctx->line[c][i].x1, xctx->line[c][i].y1,
               xctx->line[c][i].x2, xctx->line[c][i].y2, xctx->line[c][i].dash);
    +      if(xctx->rects[c]) fprintf(fd, "NP\n"); /* newpath */
           for(i=0;irects[c]; ++i)
           {
             
    @@ -1396,7 +1454,9 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
             }
             if(c != GRIDLAYER || !(xctx->rect[c][i].flags & 1) )  {
               ps_filledrect(c, xctx->rect[c][i].x1, xctx->rect[c][i].y1,
    -            xctx->rect[c][i].x2, xctx->rect[c][i].y2, xctx->rect[c][i].dash, xctx->rect[c][i].fill);
    +            xctx->rect[c][i].x2, xctx->rect[c][i].y2,
    +            xctx->rect[c][i].dash, xctx->rect[c][i].fill,
    +            xctx->rect[c][i].ellipse_a, xctx->rect[c][i].ellipse_b);
             }
           }
           if(xctx->arcs[c]) fprintf(fd, "NP\n"); /* newpath */
    @@ -1497,7 +1557,7 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
     
         dbg(1, "ps_draw(): INT_WIDTH(lw)=%d plotfile=%s\n",INT_WIDTH(xctx->lw), xctx->plotfile);
         fprintf(fd, "showpage\n\n");
    -  } /* if(what & 2) */
    +  }
       if(what & 4) { /* trailer */
         fprintf(fd, "%%%%trailer\n");
         fprintf(fd, "%%%%Pages: %d\n", numpages);
    @@ -1515,10 +1575,10 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
     
     
       /* restore original size and zoom factor */
    -  if(!(what & 4) && fullzoom == 1) {
    -    dbg(1, "create_ps: restoring zoom\n");
    +  if(fullzoom == 1) {
         save_restore_zoom(0, &zi);
       }
    +
     }
     
     int ps_draw(int what, int fullzoom, int eps)
    diff --git a/src/save.c b/src/save.c
    index 05638341..cefd1a04 100644
    --- a/src/save.c
    +++ b/src/save.c
    @@ -909,7 +909,7 @@ char *base64_from_file(const char *f, size_t *length)
       stat_res = stat(f, &st);
       if (stat_res == 0 && ( (st.st_mode & S_IFMT) == S_IFREG) ) {
         len = st.st_size;
    -    fd = fopen(f, fopen_read_mode);
    +    fd = my_fopen(f, fopen_read_mode);
         if(fd) {
           size_t bytes_read;
           s = my_malloc(_ALLOC_ID_, len);
    @@ -1023,7 +1023,7 @@ int raw_read(const char *f, Raw **rawptr, const char *type, int no_warning, doub
       raw->annot_sweep_idx = -1;
     
       int_hash_init(&raw->table, HASHSIZE);
    -  fd = fopen(f, fopen_read_mode);
    +  fd = my_fopen(f, fopen_read_mode);
       if(fd) {
         if((res = read_dataset(fd, rawptr, type, no_warning)) == 1) {
           int i;
    @@ -1038,6 +1038,18 @@ int raw_read(const char *f, Raw **rawptr, const char *type, int no_warning, doub
           dbg(0, "Raw file data read: %s\n", f);
           dbg(0, "points=%d, vars=%d, datasets=%d sim_type=%s\n", 
                  raw->allpoints, raw->nvars, raw->datasets, raw->sim_type ? raw->sim_type : "");
    +
    +      if(xctx->graph_flags & 4) { /* if cursor2 is enabled in first graph setup schematic annotation */
    +        if(xctx->rects[GRIDLAYER] > 0)  {
    +          xRect *r;
    +          r = &xctx->rect[GRIDLAYER][0];
    +          if(r->flags & 1) {
    +            setup_graph_data(0, 0, &xctx->graph_struct);
    +            backannotate_at_cursor_b_pos(r, &xctx->graph_struct);
    +          }
    +        }
    +      }
    +
         } else {
           /* free_rawfile(rawptr, 0, 0); */ /* do not free: already done in read_dataset()->extra_rawfile() */
           if(!no_warning) {
    @@ -1455,7 +1467,7 @@ int table_read(const char *f)
       close(ufd);
     
       int_hash_init(&raw->table, HASHSIZE);
    -  fd = fopen(f, fopen_read_mode);
    +  fd = my_fopen(f, fopen_read_mode);
       if(fd) {
         int nline = 0;
         int field;
    @@ -2840,11 +2852,11 @@ static void load_polygon(FILE *fd)
         load_ascii_string( &ptr[i].prop_ptr, fd);
         fill_ptr = get_tok_value(ptr[i].prop_ptr,"fill",0);
         if( !strcmp(fill_ptr, "full") )
    -      ptr[i].fill =3; /* bit 1: solid fill (not stippled) */
    +      ptr[i].fill = 2; /* bit 1: solid fill (not stippled) */
         else if( !strboolcmp(fill_ptr, "true") )
    -      ptr[i].fill =1;
    +      ptr[i].fill = 1;
         else
    -      ptr[i].fill =0;
    +      ptr[i].fill = 0;
         dash = get_tok_value(ptr[i].prop_ptr,"dash",0);
         if(strcmp(dash, "")) {
           int d = atoi(dash);
    @@ -2883,11 +2895,11 @@ static void load_arc(FILE *fd)
     
         fill_ptr = get_tok_value(ptr[i].prop_ptr,"fill",0);
         if( !strcmp(fill_ptr, "full") )
    -      ptr[i].fill =3; /* bit 1: solid fill (not stippled) */
    +      ptr[i].fill = 2; /* bit 1: solid fill (not stippled) */
         else if( !strboolcmp(fill_ptr, "true") )
    -      ptr[i].fill =1;
    +      ptr[i].fill = 1;
         else
    -      ptr[i].fill =0;
    +      ptr[i].fill = 0;
         dash = get_tok_value(ptr[i].prop_ptr,"dash",0);
         if(strcmp(dash, "")) {
           int d = atoi(dash);
    @@ -2927,11 +2939,11 @@ static void load_box(FILE *fd)
         load_ascii_string( &ptr[i].prop_ptr, fd);
         fill_ptr = get_tok_value(ptr[i].prop_ptr,"fill",0);
         if( !strcmp(fill_ptr, "full") )
    -      ptr[i].fill =3;
    +      ptr[i].fill = 2;
         else if( !strboolcmp(fill_ptr, "false") )
    -      ptr[i].fill =0;
    +      ptr[i].fill = 0;
         else
    -      ptr[i].fill =1;
    +      ptr[i].fill = 1;
         attr = get_tok_value(ptr[i].prop_ptr,"dash",0);
         if(strcmp(attr, "")) {
           int d = atoi(attr);
    @@ -3532,7 +3544,7 @@ int load_schematic(int load_symbols, const char *fname, int reset_undo, int aler
             my_free(_ALLOC_ID_, &cmd);
           } else fd = NULL;
         }
    -    else fd=fopen(name,fopen_read_mode);
    +    else fd=my_fopen(name,fopen_read_mode);
         if( fd == NULL) {
           size_t len;
           ret = 0;
    @@ -3545,7 +3557,7 @@ int load_schematic(int load_symbols, const char *fname, int reset_undo, int aler
           }
           len = strlen(name);
           if(!strcmp(name + len - 4, ".sym")) {
    -        xctx->save_netlist_type = xctx->netlist_type;
    +        if(xctx->netlist_type != CAD_SYMBOL_ATTRS) xctx->save_netlist_type = xctx->netlist_type;
             xctx->netlist_type = CAD_SYMBOL_ATTRS;
             set_tcl_netlist_type();
             xctx->loaded_symbol = 1;
    @@ -3564,7 +3576,7 @@ int load_schematic(int load_symbols, const char *fname, int reset_undo, int aler
           if(reset_undo) {
             tclvareval("is_xschem_file {", xctx->sch[xctx->currsch], "}", NULL);
             if(!strcmp(tclresult(), "SYMBOL") || xctx->instances == 0) {
    -          xctx->save_netlist_type = xctx->netlist_type;
    +          if(xctx->netlist_type != CAD_SYMBOL_ATTRS) xctx->save_netlist_type = xctx->netlist_type;
               xctx->netlist_type = CAD_SYMBOL_ATTRS;
               set_tcl_netlist_type();
               xctx->loaded_symbol = 1;
    @@ -3811,7 +3823,7 @@ void pop_undo(int redo, int set_modify_status)
       fd=fdopen(pd[0],"r");
       #else /* uncompressed undo */
       my_snprintf(diff_name, S(diff_name), "%s/undo%d", xctx->undo_dirname, xctx->cur_undo_ptr%MAX_UNDO);
    -  fd=fopen(diff_name, "r");
    +  fd=my_fopen(diff_name, fopen_read_mode);
       if(!fd) {
         fprintf(errfp, "pop_undo(): failed to open read pipe %s\n", diff_name);
         xctx->no_undo=1;
    @@ -3882,9 +3894,9 @@ static void get_sym_type(const char *symname, char **type,
       if( !found ) {
         dbg(1, "get_sym_type(): open file %s, pintable %s\n",name, pintable ? "set" : "");
         /* ... if not found open file and look for 'type' into the global attributes. */
    -
    +    
         if(embed_fd) fd = embed_fd;
    -    else fd=fopen(name,fopen_read_mode);
    +    else fd=my_fopen(name,fopen_read_mode);
     
         if(fd==NULL) {
           dbg(1, "get_sym_type(): Symbol not found: %s\n",name);
    @@ -4226,15 +4238,15 @@ int load_sym_def(const char *name, FILE *embed_fd)
         } else {
           my_strncpy(sympath, abs_sym_path(transl_name, ""), S(sympath));
         }
    -    if((lcc[level].fd=fopen(sympath,fopen_read_mode))==NULL) {
    +    if((lcc[level].fd=my_fopen(sympath,fopen_read_mode))==NULL) {
           /* not found: try web URL */
           if(is_from_web(xctx->current_dirname)) {
             my_snprintf(sympath, S(sympath), "%s/%s", xschem_web_dirname, get_cell_w_ext(transl_name, 0));
    -        if((lcc[level].fd=fopen(sympath,fopen_read_mode))==NULL) {
    +        if((lcc[level].fd=my_fopen(sympath,fopen_read_mode))==NULL) {
               /* not already cached in .../xschem_web_xxxxx/ so download */
               tclvareval("try_download_url {", xctx->current_dirname, "} {", transl_name, "}", NULL);
             }
    -        lcc[level].fd=fopen(sympath,fopen_read_mode);
    +        lcc[level].fd=my_fopen(sympath,fopen_read_mode);
           }
         }
         dbg(1, "l_s_d(): fopen1(%s), level=%d, fd=%p\n",sympath, level, lcc[level].fd);
    @@ -4246,7 +4258,7 @@ int load_sym_def(const char *name, FILE *embed_fd)
         /* issue warning only on top level symbol loading */
         if(recursion_counter == 1) dbg(0, "l_s_d(): Symbol not found: %s\n", transl_name);
         my_snprintf(sympath, S(sympath), "%s/%s", tclgetvar("XSCHEM_SHAREDIR"), "systemlib/missing.sym");
    -    if((lcc[level].fd=fopen(sympath, fopen_read_mode))==NULL)
    +    if((lcc[level].fd=my_fopen(sympath, fopen_read_mode))==NULL)
         {
          fprintf(errfp, "l_s_d(): systemlib/missing.sym missing, I give up\n");
          tcleval("exit");
    @@ -4441,11 +4453,11 @@ int load_sym_def(const char *name, FILE *embed_fd)
       
             fill_ptr = get_tok_value(pp[c][i].prop_ptr,"fill",0);
             if( !strcmp(fill_ptr, "full") )
    -          pp[c][i].fill =3; /* bit 1: solid fill (not stippled) */
    +          pp[c][i].fill = 2; /* bit 1: solid fill (not stippled) */
             else if( !strboolcmp(fill_ptr, "true") )
    -          pp[c][i].fill =1;
    +          pp[c][i].fill = 1;
             else
    -          pp[c][i].fill =0;
    +          pp[c][i].fill = 0;
       
             attr = get_tok_value(pp[c][i].prop_ptr,"dash", 0);
             if( strcmp(attr, "") ) {
    @@ -4507,11 +4519,11 @@ int load_sym_def(const char *name, FILE *embed_fd)
             }
             fill_ptr = get_tok_value(aa[c][i].prop_ptr,"fill",0);
             if( !strcmp(fill_ptr, "full") )
    -          aa[c][i].fill =3; /* bit 1: solid fill (not stiaaled) */
    +          aa[c][i].fill = 2; /* bit 1: solid fill (not stiaaled) */
             else if( !strboolcmp(fill_ptr, "true") )
    -          aa[c][i].fill =1;
    +          aa[c][i].fill = 1;
             else
    -          aa[c][i].fill =0;
    +          aa[c][i].fill = 0;
             attr = get_tok_value(aa[c][i].prop_ptr,"dash", 0);
             if( strcmp(attr, "") ) {
               int d = atoi(attr);
    @@ -4570,11 +4582,11 @@ int load_sym_def(const char *name, FILE *embed_fd)
             dbg(2, "l_s_d(): loaded rect: ptr=%lx\n", (unsigned long)bb[c]);
             fill_ptr = get_tok_value(bb[c][i].prop_ptr,"fill",0);
             if( !strcmp(fill_ptr, "full") )
    -          bb[c][i].fill =3;
    +          bb[c][i].fill = 2;
             else if( !strboolcmp(fill_ptr, "false") )
    -          bb[c][i].fill =0;
    +          bb[c][i].fill = 0;
             else
    -          bb[c][i].fill =1;
    +          bb[c][i].fill = 1;
             attr = get_tok_value(bb[c][i].prop_ptr,"dash", 0);
             if( strcmp(attr, "") ) {
               int d = atoi(attr);
    @@ -4787,6 +4799,7 @@ int load_sym_def(const char *name, FILE *embed_fd)
              dbg(1, "l_s_d(): level=%d, symname=%s symtype=%s\n", level, symname, symtype);
              
              if(  /* add here symbol types not to consider when loading schematic-as-symbol instances */
    +             !symtype ||
                  !strcmp(symtype, "logo") ||
                  !strcmp(symtype, "netlist_commands") ||
                  !strcmp(symtype, "netlist_options") ||
    @@ -4817,7 +4830,7 @@ int load_sym_def(const char *name, FILE *embed_fd)
       
              dbg(1, "l_s_d(): fopen2(%s), level=%d\n",sympath, level);
              /* find out if symbol is in an external file or embedded, set fd_tmp accordingly */
    -         if ((fd_tmp = fopen(sympath, fopen_read_mode)) == NULL) {
    +         if ((fd_tmp = my_fopen(sympath, fopen_read_mode)) == NULL) {
                char c;
                fprintf(errfp, "l_s_d(): unable to open file to read schematic: %s\n", sympath);
                if(!generator) {
    @@ -5107,6 +5120,7 @@ int descend_symbol(void)
       char name_embedded[PATH_MAX];
       int n = 0;
       struct stat buf;
    +  int save_netlist_type = xctx->netlist_type;
       if(xctx->currsch + 1 >= CADMAXHIER) {
         dbg(0, "descend_symbol(): max hierarchy depth reached: %d", CADMAXHIER);
         return 0;
    @@ -5216,6 +5230,10 @@ int descend_symbol(void)
         }
         my_free(_ALLOC_ID_, &sympath);
       }
    +  if(save_netlist_type != CAD_SYMBOL_ATTRS) xctx->save_netlist_type = save_netlist_type;
    +  xctx->loaded_symbol = 1;
    +  xctx->netlist_type = CAD_SYMBOL_ATTRS;
    +  set_tcl_netlist_type();
       zoom_full(1, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
       return 1;
     }
    diff --git a/src/scheduler.c b/src/scheduler.c
    index b5611a46..38e6866e 100644
    --- a/src/scheduler.c
    +++ b/src/scheduler.c
    @@ -1344,6 +1344,10 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
                 my_snprintf(res, S(res), "%g %g %g %g", boundbox.x1, boundbox.y1, boundbox.x2, boundbox.y2);
                 Tcl_SetResult(interp, res, TCL_VOLATILE);
               }
    +          else if(!strcmp(argv[2], "build_date")) { /* time and date this file was built. */
    +            char date[] =  __DATE__ " : "  __TIME__;
    +            Tcl_SetResult(interp, date,  TCL_STATIC);
    +          }
               break;
               case 'c':
               if(!strcmp(argv[2], "cadlayers")) { /* number of layers */
    @@ -2158,7 +2162,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
           if(argc > 2 ) {
             what = atoi(argv[2]);
           }
    -      if((xctx->semaphore == 0)) go_back(what);
    +      if(xctx->semaphore == 0) go_back(what);
           Tcl_ResetResult(interp);
         }
     
    @@ -3024,6 +3028,33 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
           else if(argc==2 && errfp != stderr) { fclose(errfp); errfp=stderr; }
         }
     
    +    /* load_symbol [symbol_file]
    +     *   Load specified symbol_file
    +     *   Returns:
    +     *     >= 0: symbol is already loaded or has been loaded
    +     *     <  0: symbol was not loaded
    +     */
    +    else if(!strcmp(argv[1], "load_symbol") )
    +    {
    +      int res = -2;
    +      struct stat buf;
    +      if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
    +      if(argc > 2) { 
    +        int i = get_symbol(rel_sym_path(argv[2]));
    +        if(i < 0 ) {
    +          if(!stat(argv[2], &buf)) { /* file exists */
    +            res = load_sym_def(rel_sym_path(argv[2]), NULL);
    +            if(res == 0) res = -1;
    +          } else {
    +            res = -3;
    +          }
    +        } else {
    +          res = 1;
    +        }
    +      }
    +      Tcl_SetResult(interp, my_itoa(res), TCL_VOLATILE);
    +    }
    +
         /* log_write text
          *   write given string to log file, so tcl can write messages on the log file
          */
    @@ -3356,7 +3387,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
                                 "-message {Please Set netlisting mode (Options menu)}");
             tclsetboolvar("keep_symbols", save_keep);
     
    -        if( (erc == 0) ) {
    +        if(erc == 0) {
               my_strncpy(xctx->netlist_name, "", S(xctx->netlist_name));
             }
           }
    @@ -5547,7 +5578,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
             set_rect_flags(r); /* set cached .flags bitmask from attributes */
             if(argc > 5 && !strcmp(argv[5], "fill")) {
               const char *attr = get_tok_value(r->prop_ptr,"fill", 0);
    -          if(!strcmp(attr, "full")) xctx->rect[c][n].fill = 3;
    +          if(!strcmp(attr, "full")) xctx->rect[c][n].fill = 2;
               else if(!strboolcmp(attr, "false")) xctx->rect[c][n].fill = 0;
               else xctx->rect[c][n].fill = 1;
             }
    diff --git a/src/select.c b/src/select.c
    index ca5105d2..620bac21 100644
    --- a/src/select.c
    +++ b/src/select.c
    @@ -439,7 +439,7 @@ static void del_rect_line_arc_poly()
        {
         ++j;
     
    -    if(xctx->arc[c][i].fill & 1) /* .fill: 1: stippled fill, 3: solid fill */
    +    if(xctx->arc[c][i].fill) /* .fill: 1: stippled fill, 2: solid fill */
           arc_bbox(xctx->arc[c][i].x, xctx->arc[c][i].y, xctx->arc[c][i].r, 0, 360,
                    &tmp.x1, &tmp.y1, &tmp.x2, &tmp.y2);
         else
    diff --git a/src/spice_netlist.c b/src/spice_netlist.c
    index c341895a..663a2a7d 100644
    --- a/src/spice_netlist.c
    +++ b/src/spice_netlist.c
    @@ -635,6 +635,11 @@ int spice_block_netlist(FILE *fd, int i, int alert)
              tclgetvar("netlist_dir"), get_cell(name, 0), getpid());
         dbg(1, "spice_block_netlist(): split_files: netl_filename=%s\n", netl_filename);
         fd=fopen(netl_filename, "w");
    +    if(!fd) {
    +      dbg(0, "spice_block_netlist(): unable to write file %s\n", netl_filename);
    +      err = 1;
    +      goto err;
    +    }
         my_snprintf(cellname, S(cellname), "%s.spice", get_cell(name, 0));
       }
       fprintf(fd, "\n* expanding   symbol:  %s # of pins=%d\n", name,xctx->sym[i].rects[PINLAYER] );
    @@ -689,6 +694,7 @@ int spice_block_netlist(FILE *fd, int i, int alert)
         set_tcl_netlist_type();
         if(debug_var==0) xunlink(netl_filename);
       }
    +  err:
       xctx->netlist_count++;
       my_free(_ALLOC_ID_, &name);
       return err;
    diff --git a/src/store.c b/src/store.c
    index e9fed4f1..ce02bdb6 100644
    --- a/src/store.c
    +++ b/src/store.c
    @@ -156,11 +156,11 @@ void store_arc(int pos, double x, double y, double r, double a, double b,
     
       fill_ptr = get_tok_value(xctx->arc[rectc][n].prop_ptr,"fill",0);
       if(!strcmp(fill_ptr, "full") )
    -    xctx->arc[rectc][n].fill =3; /* bit 1: solid fill (not stippled) */
    +    xctx->arc[rectc][n].fill = 2; /* bit 1: solid fill (not stippled) */
       else if(!strboolcmp(fill_ptr, "true") )
    -    xctx->arc[rectc][n].fill =1;
    +    xctx->arc[rectc][n].fill = 1;
       else
    -    xctx->arc[rectc][n].fill =0;
    +    xctx->arc[rectc][n].fill = 0;
       dash = get_tok_value(xctx->arc[rectc][n].prop_ptr,"dash",0);
       if( strcmp(dash, "") ) {
         int d = atoi(dash);
    @@ -206,11 +206,11 @@ void store_poly(int pos, double *x, double *y, int points, unsigned int rectc,
     
       fill_ptr = get_tok_value(xctx->poly[rectc][n].prop_ptr,"fill",0);
       if(!strcmp(fill_ptr, "full") )
    -    xctx->poly[rectc][n].fill =3; /* bit 1: solid fill (not stippled) */
    +    xctx->poly[rectc][n].fill = 2; /* bit 1: solid fill (not stippled) */
       else if(!strboolcmp(fill_ptr, "true") )
    -    xctx->poly[rectc][n].fill =1;
    +    xctx->poly[rectc][n].fill = 1;
       else
    -    xctx->poly[rectc][n].fill =0;
    +    xctx->poly[rectc][n].fill = 0;
       dash = get_tok_value(xctx->poly[rectc][n].prop_ptr,"dash",0);
       if( strcmp(dash, "") ) {
         int d = atoi(dash);
    @@ -307,11 +307,11 @@ int storeobject(int pos, double x1,double y1,double x2,double y2,
     
          fill_ptr = get_tok_value(xctx->rect[rectc][n].prop_ptr, "fill", 0);
          if(!strcmp(fill_ptr, "full") )
    -       xctx->rect[rectc][n].fill =3;
    +       xctx->rect[rectc][n].fill = 2;
          else if(!strboolcmp(fill_ptr,"false") )
    -       xctx->rect[rectc][n].fill =0;
    +       xctx->rect[rectc][n].fill = 0;
          else
    -       xctx->rect[rectc][n].fill =1;
    +       xctx->rect[rectc][n].fill = 1;
          set_rect_flags(&xctx->rect[rectc][n]); /* set cached .flags bitmask from on attributes */
          if(rectc == GRIDLAYER && (xctx->rect[rectc][n].flags & 1024)) {
             xRect *r = &xctx->rect[GRIDLAYER][n];
    diff --git a/src/svgdraw.c b/src/svgdraw.c
    index a6b8d885..601de7da 100644
    --- a/src/svgdraw.c
    +++ b/src/svgdraw.c
    @@ -62,7 +62,7 @@ static void svg_xfillrectangle(int layer, double x1, double y1, double x2, doubl
       if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 1.4*dash/xctx->zoom, 1.4*dash/xctx->zoom);
       if(fill == 0) {
         fprintf(fd,"style=\"fill:none;\" ");
    -  } else if(fill == 3) {
    +  } else if(fill == 2) {
        fprintf(fd, "style=\"fill-opacity:1.0;\" ");
       }
       fprintf(fd,"d=\"M%g %gL%g %gL%g %gL%g %gL%g %gz\"/>\n", x1, y1, x2, y1, x2, y2, x1, y2, x1, y1);
    @@ -135,7 +135,7 @@ static void svg_drawpolygon(int c, int what, double *x, double *y, int points, i
       if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 1.4*dash/xctx->zoom, 1.4*dash/xctx->zoom);
       if(fill == 0) {
         fprintf(fd,"style=\"fill:none;\" ");
    -  } else if(fill == 3) {
    +  } else if(fill == 2) {
        fprintf(fd, "style=\"fill-opacity:1.0;\" ");
       }
       bezier = flags && (points > 2);
    @@ -154,7 +154,8 @@ static void svg_drawpolygon(int c, int what, double *x, double *y, int points, i
       fprintf(fd, "\"/>\n");
     }
     
    -static void svg_filledrect(int gc, double rectx1,double recty1,double rectx2,double recty2, int dash, int fill)
    +static void svg_filledrect(int gc, double rectx1,double recty1,double rectx2,double recty2,
    +                           int dash, int fill, int e_a, int e_b)
     {
      double x1,y1,x2,y2;
     
    @@ -164,7 +165,41 @@ static void svg_filledrect(int gc, double rectx1,double recty1,double rectx2,dou
       y2=Y_TO_SCREEN(recty2);
       if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) )
       {
    -   svg_xfillrectangle(gc, x1,y1,x2,y2, dash, fill);
    +    if(e_a != -1) {
    +      double rx = (x2 - x1) / 2.0;
    +      double ry = (y2 - y1) / 2.0;
    +      double cx = (x2 + x1) / 2.0;
    +      double cy = (y2 + y1) / 2.0;
    +
    +      if(e_b == 360.) {
    +        fprintf(fd, "zoom, 1.4*dash/xctx->zoom);
    +        if(fill == 0) fprintf(fd, "style=\"fill:none;\" ");
    +        else if(fill == 2) fprintf(fd, "style=\"fill-opacity:1.0;\" ");
    +        fprintf(fd, "/>\n");
    +      } else {
    +        double xx1 = rx * cos(e_a * XSCH_PI / 180.) + cx;
    +        double yy1 = -ry * sin(e_a * XSCH_PI / 180.) + cy;
    +        double xx2 = rx * cos((e_a + e_b) * XSCH_PI / 180.) + cx;
    +        double yy2 = -ry * sin((e_a + e_b) * XSCH_PI / 180.) + cy;
    +        int fa = e_b > 180 ? 1 : 0;
    +        int fs = e_b > 0 ? 0 : 1;
    +
    +        fprintf(fd,"zoom, 1.4*dash/xctx->zoom);
    +        if(fill == 0) {
    +           fprintf(fd,"style=\"fill:none;\" ");
    +           fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %g\"/>\n", xx1, yy1, rx, ry, fa, fs, xx2, yy2);
    +        } else if(fill == 2) {
    +          fprintf(fd, "style=\"fill-opacity:1.0;\" ");
    +          fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %gL%g %gz\"/>\n", xx1, yy1, rx, ry, fa, fs, xx2, yy2, cx, cy);
    +        } else {
    +          fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %gL%g %gz\"/>\n", xx1, yy1, rx, ry, fa, fs, xx2, yy2, cx, cy);
    +        }
    +      }
    +    } else {
    +      svg_xfillrectangle(gc, x1,y1,x2,y2, dash, fill);
    +    }
       }
     }
     
    @@ -210,7 +245,7 @@ static void svg_drawarc(int gc, int fillarc, double x,double y,double r,double a
           fprintf(fd, "zoom, 1.4*dash/xctx->zoom);
           if(fillarc == 0) fprintf(fd, "style=\"fill:none;\" ");
    -      else if(fillarc == 3) fprintf(fd, "style=\"fill-opacity:1.0;\" ");
    +      else if(fillarc == 2) fprintf(fd, "style=\"fill-opacity:1.0;\" ");
     
           fprintf(fd, "/>\n");
         } else {
    @@ -226,12 +261,12 @@ static void svg_drawarc(int gc, int fillarc, double x,double y,double r,double a
           if(fillarc == 0) {
              fprintf(fd,"style=\"fill:none;\" ");
              fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %g\"/>\n", xx1, yy1, rr, rr, fa, fs, xx2, yy2);
    -      } else if(fillarc == 3) {
    +      } else if(fillarc == 2) {
             fprintf(fd, "style=\"fill-opacity:1.0;\" ");
             fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %gL%g %gz\"/>\n", xx1, yy1, rr, rr, fa, fs, xx2, yy2, xx, yy);
           } else {
             fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %gL%g %gz\"/>\n", xx1, yy1, rr, rr, fa, fs, xx2, yy2, xx, yy);
    -     }
    +      }
         }
       }
     }
    @@ -478,6 +513,7 @@ static int svg_embedded_image(xRect *r, double rx1, double ry1, double rx2, doub
       double alpha = 1.0;
       unsigned char *buffer = NULL;
       size_t buffer_size;
    +  double xorig, yorig; /* image anchor point, upper left corner in SVG */
     
       x1=X_TO_SCREEN(rx1);
       y1=Y_TO_SCREEN(ry1);
    @@ -488,7 +524,6 @@ static int svg_embedded_image(xRect *r, double rx1, double ry1, double rx2, doub
       if(RECT_OUTSIDE(x1, y1, x2, y2,
                       xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2)) return 0;
          
    -
       if(rot == 1 || rot == 3) {
         w = fabs(y2 - y1);
         h = fabs(x2 - x1);
    @@ -498,7 +533,8 @@ static int svg_embedded_image(xRect *r, double rx1, double ry1, double rx2, doub
       }
     
       if(flip && (rot == 0 || rot == 2)) scalex = -1.0;
    -  else if(flip && (rot == 1 || rot == 3)) scaley = -1.0;
    +  else if(flip && (rot == 1 || rot == 3)) scalex = -1.0;
    +
       alpha_str = get_tok_value(r->prop_ptr, "alpha", 0);
       if(alpha_str[0]) alpha = atof(alpha_str);
       attr_len = my_strdup2(_ALLOC_ID_, &attr, get_tok_value(r->prop_ptr, "image_data", 0));
    @@ -523,8 +559,32 @@ static int svg_embedded_image(xRect *r, double rx1, double ry1, double rx2, doub
         my_free(_ALLOC_ID_, &attr);
         return 0;
       }
    +
    +  xorig = x1;
    +  yorig = y1;
    +  if(rot == 0) {
    +    if(flip) xorig += w;
    +  } else if(rot == 1) {
    +    if(flip) {
    +      xorig += h;
    +      yorig += w;
    +    } else xorig += h;
    +  } else if(rot == 2) {
    +    if(flip) {
    +      yorig += h;
    +    } else {
    +      xorig += w;
    +      yorig += h;
    +    }
    +  } else if(rot == 3) {
    +    if(flip) {
    +    } else {
    +      yorig += w;
    +    }
    +  }
    +
       my_snprintf(transform, S(transform), 
    -    "transform=\"translate(%g,%g) scale(%g,%g) rotate(%d)\"", x1, y1, scalex, scaley, rot * 90);
    +    "transform=\"translate(%g,%g) rotate(%d) scale(%g,%g)\"", xorig, yorig, rot * 90, scalex, scaley);
       if(alpha == 1.0)  strcpy(opacity, "");
       else my_snprintf(opacity, S(opacity), "style=\"opacity:%g;\"", alpha);
       /*    png         jpg */
    @@ -603,7 +663,7 @@ static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot,
         }
         else if((xctx->inst[n].x2 - xctx->inst[n].x1) * xctx->mooz < 3 &&
                            (xctx->inst[n].y2 - xctx->inst[n].y1) * xctx->mooz < 3) {
    -      svg_filledrect(c, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 0, 0);
    +      svg_filledrect(c, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 0, 0, -1, -1);
           xctx->inst[n].flags|=1;
           return;
         }
    @@ -612,7 +672,7 @@ static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot,
         }
         if(hide) {
           int color = (disabled==1) ? GRIDLAYER : (disabled == 2) ? PINLAYER : SYMLAYER;
    -      svg_filledrect(color, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 2, 0);
    +      svg_filledrect(color, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 2, 0, -1, -1);
         }
       }
       else if(xctx->inst[n].flags&1) {
    @@ -692,9 +752,27 @@ static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot,
             double xx2 = x0 + x2;
             double yy2 = y0 + y2;
             svg_embedded_image(rect, xx1, yy1, xx2, yy2, rot, flip);
    -        continue;
    +      } else {
    +        int ellipse_a = rect->ellipse_a;
    +        int ellipse_b = rect->ellipse_b;
    +
    +        if(ellipse_a != -1 && ellipse_b != 360) {
    +          if(flip) {
    +            ellipse_a = 180 - ellipse_a - ellipse_b;
    +          }
    +          if(rot) {
    +            if(rot == 3) {
    +              ellipse_a += 90;
    +            } else if(rot == 2) {
    +              ellipse_a += 180;
    +            } else if(rot == 1) {
    +              ellipse_a += 270;
    +            }
    +            ellipse_a %= 360;
    +          }
    +        }
    +        svg_filledrect(c, x0+x1, y0+y1, x0+x2, y0+y2, dash, rect->fill, ellipse_a, ellipse_b);
           }
    -      svg_filledrect(c, x0+x1, y0+y1, x0+x2, y0+y2, dash, rect->fill);
         }
       }
     
    @@ -916,8 +994,8 @@ void svg_draw(void)
        * 2 : solid fill
        * fill_type[i]: 
        * 0 : no fill
    -   * 1 : solid fill
    -   * 2 : patterned (stippled) fill
    +   * 1 : patterned (stippled) fill
    +   * 2 : solid fill
        */
       for(i=0;ifill_pattern == 2 && xctx->fill_type[i]) 
           fprintf(fd, "  fill: #%02x%02x%02x;\n", svg_colors[i].red, svg_colors[i].green, svg_colors[i].blue);
    -    else if( xctx->fill_pattern && xctx->fill_type[i] == 1) 
    +    else if( xctx->fill_pattern && xctx->fill_type[i] == 2) 
           fprintf(fd, "  fill: #%02x%02x%02x;\n", svg_colors[i].red, svg_colors[i].green, svg_colors[i].blue);
         else 
           fprintf(fd, "  fill: #%02x%02x%02x; fill-opacity: 0.5;\n", 
    @@ -976,7 +1054,8 @@ void svg_draw(void)
          } else {
            svg_filledrect(c, xctx->rect[c][i].x1, xctx->rect[c][i].y1,
                              xctx->rect[c][i].x2, xctx->rect[c][i].y2,
    -                         xctx->rect[c][i].dash,  xctx->rect[c][i].fill);
    +                         xctx->rect[c][i].dash,  xctx->rect[c][i].fill,
    +                         xctx->rect[c][i].ellipse_a, xctx->rect[c][i].ellipse_b);
          }
        }
        for(i=0;iarcs[c]; ++i)
    diff --git a/src/token.c b/src/token.c
    index 4a067718..ee6a1a55 100644
    --- a/src/token.c
    +++ b/src/token.c
    @@ -1174,26 +1174,41 @@ static void print_vhdl_primitive(FILE *fd, int inst) /* netlist  primitives, 200
     
       if(c=='\0')
       {
    -   /* do one level of substitutions to resolve remaining @params and/or tcl expr/code */
    -   if(result) {
    -     dbg(1, "print_vhdl_primitive(): before translate() result=%s\n", result);
    -     if(!strcmp(xctx->sym[xctx->inst[inst].ptr].type, "netlist_commands")) {
    -        /* since netlist_commands often have @ characters in spice node save / plot commands, do
    -        * not pass through translate, unless a tcleval(...) is present */
    -       if(strstr(result, "tcleval(")== result) {
    -         my_strdup(_ALLOC_ID_, &result, translate(inst, result));
    -       }
    -     } else {
    -       my_strdup(_ALLOC_ID_, &result, translate(inst, result));
    -     }
    -     dbg(1, "print_vhdl_primitive(): after  translate() result=%s\n", result);
    -   }
    -   if(result) fprintf(fd, "%s", result);
    -   fputc('\n',fd);
    -   fprintf(fd, "---- end primitive\n");
    -   break ;
    +    char *parent_prop_ptr = NULL;
    +
    +    if(xctx->currsch > 0) {
    +      parent_prop_ptr = xctx->hier_attr[xctx->currsch - 1].prop_ptr;
    +    }
    +    /* if result is like: 'tcleval(some_string)' pass it thru tcl evaluation so expressions
    +     * can be calculated. Before that do also a round of translation to remove remaining @params */
    +    if(result) {
    +      dbg(1, "print_vhdl_primitive(): before translate3() result=%s\n", result);
    +      if(strchr(result, '@')) { 
    +        /* netlist_commands often have @ characters due to ngspice syntax. Do not translate */
    +        if(strcmp(xctx->sym[xctx->inst[inst].ptr].type, "netlist_commands")) {
    +          my_strdup2(_ALLOC_ID_, &result,
    +            translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, NULL, NULL));
    +          /* can not put template in above translate3: -----------------------^^^^
    +           * if instance has VHI=VHI, format string has VHI=@VHI, and symbol template has VHI=3
    +           * we do not want token @VHI to resolve to 3, but stop at VHI as specified in instance */
    +          if(strchr(result, '@')) { 
    +             my_strdup2(_ALLOC_ID_, &result,
    +                translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL));
    +          }
    +        } 
    +      }
    +      my_strdup2(_ALLOC_ID_, &result, tcl_hook2(result)); /* tcl evaluation if tcleval(....) */
    +      if(strstr(result, "expr(") ) {
    +        result = eval_expr(result);
    +      }
    +      dbg(1, "print_vhdl_primitive(): after  translate3() result=%s\n", result);
    +    } 
    +    if(result) fprintf(fd, "%s", result);
    +    fputc('\n',fd);
    +    fprintf(fd, "---- end primitive\n");
    +    break ;
       }
    - }
    + } /* while(1) */
      my_free(_ALLOC_ID_, &result);
      my_free(_ALLOC_ID_, &template);
      my_free(_ALLOC_ID_, &format);
    @@ -2398,7 +2413,14 @@ int print_spice_element(FILE *fd, int inst)
              *           model=nfet_01v8
              */
             my_strdup2(_ALLOC_ID_, &val, 
    -               translate3(token, 2, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL));
    +               translate3(token, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, NULL, NULL));
    +        /* can not put template in above translate3: ---------------------------^^^^
    +         * if instance has VHI=VHI, format string has VHI=@VHI, and symbol template has VHI=3
    +         * we do not want token @VHI to resolve to 3, but stop at VHI as specified in instance */
    +        if(strchr(val, '@')) {
    +           my_strdup2(_ALLOC_ID_, &val,
    +              translate3(val, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL));
    +        }
             /* nmos instance format string: @model --> @modeln */
             dbg(1, "print_spice_element(): 1st round: val: |%s|\n", val);
             if(strchr(val, '@')) {
    @@ -2428,12 +2450,10 @@ int print_spice_element(FILE *fd, int inst)
               }
               dbg(1, "print_spice_element(): final: val: |%s|\n", val);
             }
    -        value = val;
    -        /* xctx->tok_size==0 (set in translate3()) indicates that token(+1) does not exist
    -         *  in instance attributes so try to get from symbol template */
    -        dbg(1, "print_spice_element(): val: %s\n", val);
    +        /* still unresolved: set to empty */
    +        if(val[0] == '@') value = "";
    +        else value = val;
             token_exists = xctx->tok_size;
    -        value = val;
             tok_val_len = strlen(value);
             /* @spiceprefix needs a special tag for postprocessing */
             if(!strcmp(token, "@spiceprefix") && value[0]) {
    @@ -3109,26 +3129,42 @@ static void print_verilog_primitive(FILE *fd, int inst) /* netlist switch level
        }
        if(c=='\0')
        {
    -    /* do one level of substitutions to resolve remaining @params and/or tcl expr/code */
    +    char *parent_prop_ptr = NULL;
    +                   
    +    if(xctx->currsch > 0) {
    +      parent_prop_ptr = xctx->hier_attr[xctx->currsch - 1].prop_ptr;
    +    }   
    +
    +    /* if result is like: 'tcleval(some_string)' pass it thru tcl evaluation so expressions
    +     * can be calculated. Before that do also a round of translation to remove remaining @params */
         if(result) {
    -      dbg(1, "print_verilog_primitive(): before translate() result=%s\n", result);
    -      if(!strcmp(xctx->sym[xctx->inst[inst].ptr].type, "netlist_commands")) {
    -         /* since netlist_commands often have @ characters in spice node save / plot commands, do
    -         * not pass through translate, unless a tcleval(...) is present */
    -        if(strstr(result, "tcleval(")== result) {
    -          my_strdup(_ALLOC_ID_, &result, translate(inst, result));
    +      dbg(1, "print_verilog_primitive(): before translate3() result=%s\n", result);
    +      if(strchr(result, '@')) { 
    +        /* netlist_commands often have @ characters due to ngspice syntax. Do not translate */
    +        if(strcmp(xctx->sym[xctx->inst[inst].ptr].type, "netlist_commands")) {
    +          my_strdup2(_ALLOC_ID_, &result,
    +            translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, NULL, NULL));
    +          /* can not put template in above translate3: -----------------------^^^^
    +           * if instance has VHI=VHI, format string has VHI=@VHI, and symbol template has VHI=3
    +           * we do not want token @VHI to resolve to 3, but stop at VHI as specified in instance */
    +          if(strchr(result, '@')) {
    +             my_strdup2(_ALLOC_ID_, &result,
    +                translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL));
    +          }
             }
    -      } else {
    -        my_strdup(_ALLOC_ID_, &result, translate(inst, result));
           }
    -      dbg(1, "print_verilog_primitive(): after  translate() result=%s\n", result);
    +      my_strdup2(_ALLOC_ID_, &result, tcl_hook2(result)); /* tcl evaluation if tcleval(....) */
    +      if(strstr(result, "expr(") ) {
    +        result = eval_expr(result);
    +      }
    +      dbg(1, "print_verilog_primitive(): after  translate3() result=%s\n", result);
         }
         if(result) fprintf(fd, "%s", result);
         fputc('\n',fd);
         fprintf(fd, "---- end primitive\n");
         break ;
        }
    -  }
    +  } /* while(1) */
       my_free(_ALLOC_ID_, &result);
       my_free(_ALLOC_ID_, &template);
       my_free(_ALLOC_ID_, &format);
    @@ -3748,7 +3784,9 @@ const char *spice_get_node(const char *token)
     /* if s==NULL return emty string */
     const char *translate(int inst, const char* s)
     {
    +  #ifdef __unix__
       static regex_t *get_sp_cur = NULL; 
    +  #endif
       static const char *empty="";
       static char *result=NULL; /* safe to keep even with multiple schematics */
       size_t size=0;
    @@ -3773,24 +3811,28 @@ const char *translate(int inst, const char* s)
      
       if(!s && inst == -1) {
         if(result) my_free(_ALLOC_ID_, &result);
    +    #ifdef __unix__
         if(get_sp_cur) {
           regfree(get_sp_cur);
           get_sp_cur = NULL;
         }
    +    #endif
       }
      
       if(!s || !xctx || !xctx->inst) {
         return empty;
       }
      
    +  #ifdef __unix__
       if(!get_sp_cur) {
         get_sp_cur = my_malloc(_ALLOC_ID_, sizeof(regex_t));
    -    /* @spice_get_current_param(...) or @spice_get_modelparam_param(...) */
    +    /* @spice_get_current_(...) or @spice_get_modelparam_(...) */
         /* @spice_get_current(...) or @spice_get_modelparam(...) */
    -    /* @spice_get_modelvoltage(...) or @spice_get_modelvoltage_param(...) */
    +    /* @spice_get_modelvoltage(...) or @spice_get_modelvoltage_(...) */
         regcomp(get_sp_cur,
             "^@spice_get_(current|modelparam|modelvoltage)(_[a-zA-Z][a-zA-Z0-9_]*)*\\(", REG_NOSUB | REG_EXTENDED);
       }
    +  #endif
      
       sp_prefix = tclgetboolvar("spiceprefix");
      
    @@ -4116,13 +4158,17 @@ const char *translate(int inst, const char* s)
               }
             }
           }
    -      /* @spice_get_current(...) or @spice_get_current_param(...)
    -       * @spice_get_modelparam(...) or @spice_get_modelparam_param(...)
    -       * @spice_get_modelvoltage(...) or @spice_get_modelvoltage_param(...)
    +      /* @spice_get_current(...) or @spice_get_current_(...)
    +       * @spice_get_modelparam(...) or @spice_get_modelparam_(...)
    +       * @spice_get_modelvoltage(...) or @spice_get_modelvoltage_(...)
            * 
    -       * Only @spice_get_current(...) and @spice_get_current_param(...) are processed
    +       * Only @spice_get_current(...) and @spice_get_current_(...) are processed
            * the other types are ignored */
    +      #ifdef __unix__
           else if(!regexec(get_sp_cur, token, 0 , NULL, 0) )
    +      # else
    +      else if ((win_regexec(NULL/*options*/, "^@spice_get_(current|modelparam|modelvoltage)(_[a-zA-Z][a-zA-Z0-9_]*)*\\(", token)))
    +      #endif
           {
             int start_level; /* hierarchy level where waves were loaded */
             int live = tclgetboolvar("live_cursor2_backannotate");
    @@ -4148,7 +4194,8 @@ const char *translate(int inst, const char* s)
                   n = sscanf(token + 19, "%[^)]", dev);
                 } else {
                   param = my_malloc(_ALLOC_ID_, tmp);
    -              n = sscanf(token, "@spice_get_current_%s(%[^)]", param, dev);
    +              n = sscanf(token, "@spice_get_current_%[^(](%[^)]", param, dev);
    +              dbg(1, "token=%s, param=%s, dev=%s\n", token, param, dev);
                   if(n < 2) {
                     my_free(_ALLOC_ID_, ¶m);
                     n = sscanf(token, "@spice_get_current[^(](%[^)]", dev);
    @@ -4173,6 +4220,7 @@ const char *translate(int inst, const char* s)
                       my_snprintf(fqdev, len, "i(@%c.%s%s.%s[%s])", prefix, path, instname, dev, param ? param : "ic");
                     } else if(prefix == 'd' || prefix == 'm') {
                       my_snprintf(fqdev, len, "i(@%c.%s%s.%s[%s])", prefix, path, instname, dev, param ? param : "id");
    +                  dbg(1, "translate(): fqdev=%s\n", fqdev);
                     } else if(prefix == 'i') {
                       my_snprintf(fqdev, len, "i(@%c.%s%s.%s[current])", prefix, path, instname, dev);
                     } else {
    @@ -4605,7 +4653,6 @@ const char *translate2(Lcc *lcc, int level, char* s)
           }
           else if(strcmp(token,"@path")==0) {
             char *path = NULL;
    -        here(level);
             my_strdup2(_ALLOC_ID_, &path, "@path@name\\.");
             if(level > 1) { /* add parent LCC instance names (X1, Xinv etc) */
               int i;
    diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c
    index bb675e55..630acc58 100644
    --- a/src/verilog_netlist.c
    +++ b/src/verilog_netlist.c
    @@ -453,6 +453,11 @@ int verilog_block_netlist(FILE *fd, int i, int alert)
            tclgetvar("netlist_dir"),  get_cell(name, 0), getpid());
         dbg(1, "global_vhdl_netlist(): split_files: netl_filename=%s\n", netl_filename);
         fd=fopen(netl_filename, "w");
    +    if(!fd) {
    +      dbg(0, "verilog_block_netlist(): unable to write file %s\n", netl_filename);
    +      err = 1;
    +      goto err;
    +    }
         my_snprintf(cellname, S(cellname), "%s.v", get_cell(name, 0));
     
       }
    @@ -619,6 +624,7 @@ int verilog_block_netlist(FILE *fd, int i, int alert)
         set_tcl_netlist_type();
         if(debug_var==0) xunlink(netl_filename);
       }
    +  err:
       xctx->netlist_count++;
       my_free(_ALLOC_ID_, &name);
       return err;
    diff --git a/src/vhdl_netlist.c b/src/vhdl_netlist.c
    index 5db254b2..c7d218c4 100644
    --- a/src/vhdl_netlist.c
    +++ b/src/vhdl_netlist.c
    @@ -538,6 +538,11 @@ int vhdl_block_netlist(FILE *fd, int i, int alert)
            tclgetvar("netlist_dir"), get_cell(xctx->sym[i].name, 0), getpid());
         dbg(1, "vhdl_block_netlist(): split_files: netl_filename=%s\n", netl_filename);
         fd=fopen(netl_filename, "w");
    +    if(!fd) {
    +      dbg(0, "vhdl_block_netlist(): unable to write file %s\n", netl_filename);
    +      err = 1;
    +      goto err;
    +    }
         my_snprintf(cellname, S(cellname), "%s.vhdl", get_cell(xctx->sym[i].name, 0) );
       }
     
    @@ -721,6 +726,7 @@ int vhdl_block_netlist(FILE *fd, int i, int alert)
         set_tcl_netlist_type();
         if(debug_var==0) xunlink(netl_filename);
       }
    +  err:
       xctx->netlist_count++;
       return err;
     }
    diff --git a/src/xinit.c b/src/xinit.c
    index 5e1a83f3..288b4e8c 100644
    --- a/src/xinit.c
    +++ b/src/xinit.c
    @@ -361,10 +361,10 @@ void init_pixdata()/* populate xctx->fill_type array that is used in create_gc()
          if(pixdata[i][j]!=0xff) full=0;
          if(pixdata[i][j]!=0x00) empty=0;
        }
    -   if(full) xctx->fill_type[i] = 1;
    +   if(full) xctx->fill_type[i] = 2;
        else if(empty) xctx->fill_type[i] = 0;
    -   else xctx->fill_type[i]=2;
    -   if(rainbow_colors && i>5) xctx->fill_type[i]=1; /* 20171212 solid fill style */
    +   else xctx->fill_type[i]=1;
    +   if(rainbow_colors && i>5) xctx->fill_type[i]=2; /* 20171212 solid fill style */
        /*fprintf(errfp, "fill_type[%d]= %d\n", i, xctx->fill_type[i]); */
      }
     }
    @@ -434,7 +434,7 @@ void create_gc(void)
         xctx->gc[i] = XCreateGC(display,xctx->window,0L,NULL);
         xctx->gcstipple[i] = XCreateGC(display,xctx->window,0L,NULL);
         XSetStipple(display,xctx->gcstipple[i],pixmap[i]);
    -    if(xctx->fill_type[i]==1)  XSetFillStyle(display,xctx->gcstipple[i],FillSolid);
    +    if(xctx->fill_type[i]==2)  XSetFillStyle(display,xctx->gcstipple[i],FillSolid);
         else XSetFillStyle(display,xctx->gcstipple[i],FillStippled);
       }
     }
    @@ -1177,12 +1177,20 @@ static int source_tcl_file(char *s)
       if(Tcl_EvalFile(interp, s)==TCL_ERROR) {
         
         fprintf(errfp, "Tcl_AppInit() error: can not execute %s, please fix:\n", s);
    -    fprintf(errfp, "Line No: %d\n", Tcl_GetErrorLine(interp));
         fprintf(errfp, "%s", tclresult());
    +    #if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >=6
    +    fprintf(errfp, "Line No: %d\n", Tcl_GetErrorLine(interp));
    +    #endif
         fprintf(errfp, "\n");
    +    #if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >=6
         my_snprintf(tmp, S(tmp), "tk_messageBox -icon error -type ok -message \
            {Tcl_AppInit() err 1: can not execute %s, please fix:\n%s\nLine No: %d\n}",
            s, tclresult(), Tcl_GetErrorLine(interp));
    +    #else
    +    my_snprintf(tmp, S(tmp), "tk_messageBox -icon error -type ok -message \
    +       {Tcl_AppInit() err 1: can not execute %s, please fix:\n%s\n}",
    +       s, tclresult());
    +    #endif
         if(has_x) {
           tcleval( "wm withdraw .");
           tcleval( tmp);
    diff --git a/src/xschem.h b/src/xschem.h
    index 59802adf..27700e9f 100644
    --- a/src/xschem.h
    +++ b/src/xschem.h
    @@ -491,7 +491,7 @@ typedef struct
       unsigned short sel;
       char *prop_ptr;
       void *extraptr; /* generic data pointer (images) */
    -  short fill;
    +  short fill; /* 0: no fill, 1: stippled fill, 2: solid fill */
       short dash;
       int ellipse_a, ellipse_b;
       /* bit0=1 for graph function, bit1=1 for unlocked x axis
    @@ -1648,6 +1648,7 @@ extern char *my_free(int id, void *ptr);
     extern size_t my_strcat(int id, char **, const char *);
     extern size_t my_strcat2(int id, char **, const char *);
     extern size_t my_mstrcat(int id, char **str, const char *append_str, ...);
    +extern FILE * my_fopen(const char *f, const char *m);
     extern void *my_memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen);
     extern char *my_itoa(int i);
     extern double atof_spice(const char *s);
    @@ -1764,4 +1765,5 @@ extern const char *create_tmpdir(char *prefix);
     extern FILE *open_tmpfile(char *prefix, char *suffix, char **filename);
     extern void create_ps(char** psfile, int what, int fullzoom, int eps);
     extern void MyXCopyArea(Display* display, Drawable src, Drawable dest, GC gc, int src_x, int src_y, unsigned int width, unsigned int height, int dest_x, int dest_y);
    +extern int win_regexec(const char *options, const char *pattern, const char *name);
     #endif /*CADGLOBALS */
    diff --git a/src/xschem.tcl b/src/xschem.tcl
    index 6b7c26bb..8311eaab 100644
    --- a/src/xschem.tcl
    +++ b/src/xschem.tcl
    @@ -693,6 +693,72 @@ proc spaces {n {indent 4}} {
       return [string repeat { } $n]
     }
     
    +# complex number operators
    +# a + b
    +proc cadd {a b} {
    +  lassign $a ra ia
    +  lassign $b rb ib
    +  set c [list [expr {$ra + $rb}] [expr {$ia + $ib}]]
    +  return $c
    +}
    +
    +# a - b
    +proc csub {a b} {
    +  lassign $a ra ia
    +  lassign $b rb ib
    +  set c [list [expr {$ra - $rb}] [expr {$ia - $ib}]]
    +  return $c
    +}
    +
    +# a * b
    +proc cmul {a b} {
    +  lassign $a ra ia
    +  lassign $b rb ib
    +  set c [list [expr {$ra * $rb - $ia * $ib}] [expr {$ra * $ib + $rb * $ia}]]
    +  return $c
    +}
    +
    +# a / b
    +proc cdiv {a b} {
    +  lassign $a ra ia
    +  lassign $b rb ib
    +  set ra [expr {double($ra)}]
    +  set ia [expr {double($ia)}]
    +  set rb [expr {double($rb)}]
    +  set ib [expr {double($ib)}]
    +  set m [expr {$rb * $rb + $ib * $ib}]
    +  set c [list [expr {($ra * $rb + $ia * $ib) / $m}] [expr {($rb * $ia - $ra * $ib) / $m}]]
    +  return $c
    +}
    +
    +# 1/b
    +proc cinv {b} {
    +
    +  lassign $b rb ib
    +  set rb [expr {double($rb)}]
    +  set ib [expr {double($ib)}]
    +  set m [expr {$rb * $rb + $ib * $ib}]
    +  set c [list [expr {$rb / $m}] [expr {-$ib / $m}]]
    +  return $c
    +}
    +
    +# return real component
    +proc creal {a} {
    +  lassign $a ra ia
    +  return $ra
    +}
    +
    +# return imaginary component
    +proc cimag {a} {
    +  lassign $a ra ia
    +  return $ia
    +}
    +
    +# return resulting impedance of parallel connected impedances a and b
    +proc cparallel {a b} {
    +  return [cdiv [cmul $a $b] [cadd $a $b]]
    +}
    +
     # wraps provided table formatted text into a nice looking bordered table 
     # sep is the list of characters used as separators, default are { }, {,}, {\t}
     # if you want to tabulate data with spaces use only {,} as separator or any other character.
    @@ -6021,6 +6087,50 @@ proc edit_prop {txtlabel} {
       return $tctx::rcode
     }
     
    +# reads metadata tokens from header component of the symbol inside `v {data}` element
    +# and returns dictionary in name of the token as key and value of the token as value in dictionary
    +# Courtesy @georgtree
    +proc symbolParse {file} {
    +    try {
    +        set file [open $file r]
    +    } on error {errmsg erropts} {
    +        puts stderr "Error while reading symbol file '$file': $errmsg"
    +        return
    +    }
    +    set data [read $file]
    +    close $file
    +    # pattern to find v {} and extract content inside brackets
    +    set pattern {(?:^|\n)v\s+\{((?:[^{}]|\\[{}])*)\}}
    +    if {![regexp $pattern $data -> content]} {
    +        return
    +    }
    +    # outer braces {...} are not part of content, so remove escaping of inner {, } and \ .
    +    set content [string map { \\\{ \{ \\\} \} \\\\ \\ } $content]
    +    # pattern to find: name="value" or name=value or name = "value" or name = value
    +    set pattern {(\w+)\s*=\s*(?:"((?:[^"]|\\["])*)"|(\S+))}
    +    set start 0
    +    # 'match' variable holds the complete matched pattern, used for searching next one
    +    while {[regexp -start $start $pattern $content -> name quotedValue unquotedValue]} {
    +        # Determine the value (quoted or unquoted)
    +        if {[string length $quotedValue] > 0} {
    +            set value $quotedValue
    +            # outer quotes are removed from value,
    +            # remove escaping of internal backslashes and doublequotes
    +            dict append tokens $name [string map {\\\\ \\ \\\" \" } $value] 
    +        } else {
    +            set value $unquotedValue
    +            dict append tokens $name $value
    +        }
    +        # Update the start index to continue searching after this match
    +        set start [expr {[string first $value $content $start] + [string length $value]}]
    +        # Safety check to prevent infinite loops
    +        if {$start <= 0} {
    +            break
    +        }
    +    }
    +    return $tokens
    +}
    +
     proc read_data_nonewline {f} {
       set fid [open $f r]
       set data [read -nonewline $fid]
    @@ -6631,8 +6741,12 @@ proc try_download_url {dirname sch_or_sym} {
     # Example: rel_sym_path /home/schippes/share/xschem/xschem_library/devices/iopin.sym
     #          devices/iopin.sym
     proc rel_sym_path {symbol} {
    -  global OS pathlist
    +  global OS pathlist env
     
    +  regsub {^~/} $symbol ${env(HOME)}/ symbol
    +  if {![regexp {^/} $symbol]} {
    +    set symbol [pwd]/$symbol
    +  }
       set curr_dirname [pwd]
       set name {}
       foreach path_elem $pathlist {
    @@ -7768,7 +7882,8 @@ set tctx::global_list {
       toolbar_visible top_is_subckt transparent_svg undo_type use_lab_wire unselect_partial_sel_wires
       use_label_prefix use_tclreadline
       user_wants_copy_cell verilog_2001 verilog_bitblast viewdata_fileid viewdata_filename viewdata_w
    -  tctx::vsize xschem_libs xschem_listen_port zoom_full_center
    +  tctx::vsize xschem_libs xschem_listen_port zoom_full_center orthogonal_wiring snap_cursor
    +  snap_cursor_size cadence_compat use_cursor_for_selection
     }
     
     ## list of global arrays to save/restore on context switching
    @@ -8056,7 +8171,7 @@ proc pack_widgets { { topwin {} } } {
         pack $topwin.statusbar.6 -side left 
         pack $topwin.statusbar.7 -side left 
         pack $topwin.statusbar.10 -side left 
    -    pack $topwin.statusbar.11 -side left
    +    pack $topwin.statusbar.11 -side left 
         pack $topwin.statusbar.9 -side left 
         pack $topwin.statusbar.8 -side left 
         pack $topwin.statusbar.1 -side left -fill x
    @@ -9228,6 +9343,7 @@ set_ne big_grid_points 0
     set_ne draw_grid_axes 1
     set_ne persistent_command 0
     set_ne intuitive_interface 1
    +set_ne use_cursor_for_selection 0
     set_ne autotrim_wires 0
     set_ne cadence_compat 0
     set_ne infix_interface 1
    diff --git a/src/xschemrc b/src/xschemrc
    index 092298dd..fd5feedc 100644
    --- a/src/xschemrc
    +++ b/src/xschemrc
    @@ -294,6 +294,19 @@
     #### set cadence_compat; Default: 0 (Cadence-style keybinds are not used by default)
     # set cadence_compat 1
     
    +#### enable drawing a diamond-shaped cursor at the closest circuit endpoint. Default: disabled (0)
    +# set snap_cursor 1
    +
    +#### set snap_cursor_size; Default: 6 (Diamond-shaped cursor that snaps to nearest circuit endpoint)
    +# set snap_cursor_size 6
    +
    +#### set cadence_compat; Default: 0 (Cadence-style keybinds are not used by default)
    +# set cadence_compat 1
    +
    +#### if set, then, when cursor (regardless of style) is on an object, and user clicks (though mouse pointer is not on the object),
    +#### the object is selected. Default: 0
    +# set use_cursor_for_selection 1
    +
     #### enable to scale grid point size as done with lines at close zoom, default: 0
     # set big_grid_points 0
     
    @@ -647,3 +660,6 @@
     #### Default: not enabled (0)
     # set fix_mouse_coord 0
     
    +#### redefine some variables to emulate Cadence UI / bindkeys
    +# source /home/schippes/share/xschem/cadence_style_rc
    +
    diff --git a/xschem_library/devices/ind.sym b/xschem_library/devices/ind.sym
    index b645c028..913da636 100644
    --- a/xschem_library/devices/ind.sym
    +++ b/xschem_library/devices/ind.sym
    @@ -1,4 +1,4 @@
    -v {xschem version=3.4.5 file_version=1.2
    +v {xschem version=3.4.6 file_version=1.2
     *
     * This file is part of XSCHEM,
     * a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
    @@ -47,7 +47,7 @@ T {@#0:pinnumber} -10 -27.5 0 1 0.2 0.2 {layer=13}
     T {@#1:pinnumber} -10 17.5 0 1 0.2 0.2 {layer=13}
     T {@#0:net_name} 5 -42.5 0 0 0.15 0.15 {layer=15 hide=instance}
     T {@#1:net_name} 5 32.5 0 0 0.15 0.15 {layer=15 hide=instance}
    -T {@name} 15 -18.75 0 0 0.2 0.2 {}
    -T {@value} 15 -3.75 0 0 0.2 0.2 {}
    -T {m=@m} 15 11.25 0 0 0.2 0.2 {}
     T {@spice_get_current} -12.5 5 0 1 0.2 0.2 {layer=17}
    +T {@name} 15 -18.75 0 0 0.2 0.2 {}
    +T {@value} 15 -6.25 0 0 0.2 0.2 {}
    +T {m=@m} 15 6.25 0 0 0.2 0.2 {}
    diff --git a/xschem_library/ngspice/diff_amp.sym b/xschem_library/ngspice/diff_amp.sym
    index 1d16a1d0..93676b81 100644
    --- a/xschem_library/ngspice/diff_amp.sym
    +++ b/xschem_library/ngspice/diff_amp.sym
    @@ -21,21 +21,21 @@ v {xschem version=3.4.6 file_version=1.2
     }
     G {}
     K {type=opamp_va
    -format="@name @@OUT @@IN1 @@IN2 @model"
    +format="@name @@OUT @@IN1 @@IN2 @model gain=@gain amplitude=@amplitude offset=@offset"
     
    -template="name=X1 model=diff_amp_cell"
    +template="name=X1 model=diff_amp_cell gain=40 amplitude=3 offset=1.5"
     
     device_model="tcleval(
    -.subckt diff_amp_cell OUT IN1 IN2
    -N1 out in1 in2 diff_amp_model
    -.ends diff_amp_cell
    -
    -.model diff_amp_model diff_amp
    -
     .control
     * following line specifies the location for the .osdi file so ngspice can use it.
     pre_osdi $USER_CONF_DIR/xschem_library/diff_amp.osdi
     .endc
    +
    +.model diff_amp_model diff_amp $ gain=40 amplitude=3 offset=1.5
    +
    +.subckt diff_amp_cell OUT IN1 IN2 gain=40 amplitude=3 offset=1.5
    +N1 out in1 in2 diff_amp_model gain=gain amplitude=amplitude offset=offset
    +.ends diff_amp_cell
     )"
     }
     V {}
    diff --git a/xschem_library/ngspice/tb_diff_amp.sch b/xschem_library/ngspice/tb_diff_amp.sch
    index 3c0fc396..3d02e9a5 100644
    --- a/xschem_library/ngspice/tb_diff_amp.sch
    +++ b/xschem_library/ngspice/tb_diff_amp.sch
    @@ -25,8 +25,8 @@ V {}
     S {}
     E {}
     B 2 840 -580 1640 -170 {flags=graph
    -y1=0
    -y2=6
    +y1=6.3e-14
    +y2=5
     ypos1=0
     ypos2=2
     divy=5
    @@ -49,7 +49,7 @@ logy=0
     }
     B 2 840 -990 1640 -580 {flags=graph
     y1=0
    -y2=40
    +y2=100
     ypos1=0
     ypos2=2
     divy=5
    @@ -68,10 +68,9 @@ unitx=1
     logx=0
     logy=0
     }
    -P 4 5 140 -600 140 -880 710 -880 710 -600 140 -600 {}
    +P 4 5 30 -600 30 -880 740 -880 740 -600 30 -600 {}
     P 4 7 410 -600 410 -560 420 -560 410 -540 400 -560 410 -560 410 -600 {}
     T {// importing libs
    -
     `include "discipline.h"
     
     module diff_amp(
    @@ -79,17 +78,17 @@ module diff_amp(
       input electrical in1,
       input electrical in2);
     
    -parameter real gain = 40; // setting gain to 40 of the differential amplifier
    -parameter real vcc = 3;   // swing from -vcc/2 to +vcc/2
    -parameter real offset = 3;// added offset
    +(* desc="gain", units="", type="instance" *)   parameter real gain = 40 from [-inf: inf];
    +(* desc="amplitude", units="", type="instance" *)    parameter real amplitude = 3 from [-inf: inf];
    +(* desc="offset", units="", type="instance" *) parameter real offset = 1.5 from [-inf: inf];
     
     analog begin
     
    -    V(out) <+ offset / 2 + vcc / 2 * tanh( gain / vcc * 2 * V(in1, in2));
    +    V(out) <+ offset + amplitude / 2 * tanh( gain / amplitude * 2 * V(in1, in2));
     
     end
     endmodule
    -} 150 -870 0 0 0.2 0.2 {font=monospace}
    +} 40 -870 0 0 0.2 0.2 {font=monospace}
     T {create a diff_amp.va file with following code 
     and compile it into a .osdi file with openvaf.} 190 -940 0 0 0.4 0.4 {}
     N 180 -450 320 -450 {lab=B}
    @@ -100,7 +99,6 @@ N 180 -330 180 -290 {lab=0}
     N 80 -330 80 -290 {lab=0}
     N 80 -530 80 -390 {lab=A}
     N 180 -450 180 -390 {lab=B}
    -C {diff_amp.sym} 420 -490 0 0 {name=X1}
     C {lab_pin.sym} 640 -490 0 1 {name=p1 sig_type=std_logic lab=Z}
     C {lab_pin.sym} 80 -530 0 0 {name=p2 sig_type=std_logic lab=A}
     C {lab_pin.sym} 180 -450 0 0 {name=p3 sig_type=std_logic lab=B}
    @@ -118,7 +116,7 @@ C {code_shown.sym} 240 -320 0 0 {name=COMMANDS only_toplevel=false value="
       set appendwrite
       remzerovec
       write tb_diff_amp.raw
    -  quit 0
    +  * quit 0
     .endc
     "}
     C {launcher.sym} 670 -120 0 0 {name=h5
    @@ -130,3 +128,4 @@ C {launcher.sym} 670 -170 0 0 {name=h1
     descr="OP annotate" 
     tclcommand="xschem annotate_op"
     }
    +C {diff_amp.sym} 420 -490 0 0 {name=X1 model=diff_amp_cell gain=100 amplitude=5 offset=2.5}