/* File: scheduler.c * * This file is part of XSCHEM, * a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit * simulation. * Copyright (C) 1998-2021 Stefan Frederik Schippers * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "xschem.h" extern char yytext[]; extern int yylex (void); typedef struct yy_buffer_state *YY_BUFFER_STATE; YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); void statusmsg(char str[],int n) { if(!has_x) return; tclsetvar("infowindow_text", str); if(n==2) { dbg(3, "statusmsg(): n = 2, str = %s\n", str); tcleval("infowindow"); } else { Tcl_VarEval(interp, xctx->top_path, ".statusbar.1 configure -text $infowindow_text", NULL); dbg(3, "statusmsg(str, %d): -> $infowindow_text = %s\n", n, tclgetvar("infowindow_text")); } } int get_instance(const char *s) { int i, found=0; for(i=0;iinstances;i++) { if(!strcmp(xctx->inst[i].instname, s)) { found=1; break; } } dbg(1, "get_instance(): found=%d, i=%d\n", found, i); if(!found) { if(!isonlydigit(s)) return -1; i=atol(s); } if(i<0 || i>xctx->instances) { return -1; } return i; } /* can be used to reach C functions from the Tk shell. */ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * argv[]) { int i; char name[1024]; /* overflow safe 20161122 */ int cmd_found = 0; Tcl_ResetResult(interp); if(argc<2) { Tcl_SetResult(interp, "Missing arguments.", TCL_STATIC); return TCL_ERROR; } if(debug_var>=2) { int i; fprintf(errfp, "xschem():"); for(i=0; imousex_snap-2.5, xctx->mousey_snap-2.5, xctx->mousex_snap+2.5, xctx->mousey_snap+2.5, xRECT, PINLAYER, SELECTED, "name=XXX\ndir=inout"); xctx->need_reb_sel_arr=1; rebuild_selected_array(); move_objects(START,0,0,0); xctx->ui_state |= START_SYMPIN; Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"align")) { cmd_found = 1; push_undo(); round_schematic_to_grid(tclgetdoublevar("cadsnap")); if(tclgetvar("autotrim_wires")) trim_wires(); set_modify(1); xctx->prep_hash_inst=0; xctx->prep_hash_wires=0; xctx->prep_net_structs=0; xctx->prep_hi_structs=0; draw(); } else if(!strcmp(argv[1],"arc")) { cmd_found = 1; xctx->ui_state |= MENUSTARTARC; } else if(!strcmp(argv[1],"attach_pins")) /* attach pins to selected component 20171005 */ { cmd_found = 1; attach_labels_to_inst(); Tcl_ResetResult(interp); } } else if(argv[1][0] == 'b') { if(!strcmp(argv[1], "bbox")) { cmd_found = 1; if(argc == 3) { if(!strcmp(argv[2], "end")) { bbox(SET , 0.0 , 0.0 , 0.0 , 0.0); draw(); bbox(END , 0.0 , 0.0 , 0.0 , 0.0); } else if(!strcmp(argv[2], "begin")) { bbox(START,0.0, 0.0, 0.0, 0.0); } } Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"break_wires")) { cmd_found = 1; break_wires_at_pins(); Tcl_ResetResult(interp); } } else if(argv[1][0] == 'c') { if(!strcmp(argv[1],"callback") ) { cmd_found = 1; callback( argv[2], atoi(argv[3]), atoi(argv[4]), atoi(argv[5]), (KeySym)atol(argv[6]), atoi(argv[7]), atoi(argv[8]), atoi(argv[9]) ); dbg(2, "callback %s %s %s %s %s %s %s %s\n", argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]); Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"change_colors")) { cmd_found = 1; build_colors(tclgetdoublevar("dim_value"), tclgetdoublevar("dim_bg")); Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"check_unique_names")) { cmd_found = 1; if(!strcmp(argv[2],"1")) { check_unique_names(1); } else { check_unique_names(0); } Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"circle")) { cmd_found = 1; xctx->ui_state |= MENUSTARTCIRCLE; } else if(!strcmp(argv[1],"clear")) { int cancel; cmd_found = 1; cancel=save(1); if(!cancel){ char name[PATH_MAX]; struct stat buf; int i; xctx->currsch = 0; unselect_all(); remove_symbols(); clear_drawing(); if(argc>=3 && !strcmp(argv[2],"SYMBOL")) { xctx->netlist_type = CAD_SYMBOL_ATTRS; set_tcl_netlist_type(); for(i=0;;i++) { if(i == 0) my_snprintf(name, S(name), "%s.sym", "untitled"); else my_snprintf(name, S(name), "%s-%d.sym", "untitled", i); if(stat(name, &buf)) break; } my_snprintf(xctx->sch[xctx->currsch], S(xctx->sch[xctx->currsch]), "%s/%s", pwd_dir, name); my_strncpy(xctx->current_name, name, S(xctx->current_name)); } else { xctx->netlist_type = CAD_SPICE_NETLIST; set_tcl_netlist_type(); for(i=0;;i++) { if(i == 0) my_snprintf(name, S(name), "%s.sch", "untitled"); else my_snprintf(name, S(name), "%s-%d.sch", "untitled", i); if(stat(name, &buf)) break; } my_snprintf(xctx->sch[xctx->currsch], S(xctx->sch[xctx->currsch]), "%s/%s", pwd_dir, name); my_strncpy(xctx->current_name, name, S(xctx->current_name)); } draw(); set_modify(0); xctx->prep_hash_inst=0; xctx->prep_hash_wires=0; xctx->prep_net_structs=0; xctx->prep_hi_structs=0; if(has_x) { char *top_path; top_path = xctx->top_path[0] ? xctx->top_path : "."; Tcl_VarEval(interp, "wm title ", top_path, " \"xschem - [file tail [xschem get schname]]\"", NULL); Tcl_VarEval(interp, "wm iconname ", top_path, " \"xschem - [file tail [xschem get schname]]\"", NULL); } } Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"clear_drawing")) { cmd_found = 1; if(argc==2) clear_drawing(); Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"clear_netlist_dir") ) { cmd_found = 1; my_strdup(373, &netlist_dir, ""); } else if(!strcmp(argv[1], "color_dim")) { cmd_found = 1; if(argc > 2) { tclsetvar("dim_value", argv[2]); if(tclgetboolvar("enable_dim_bg") ) { tclsetvar("dim_bg", argv[2]); } } build_colors(tclgetdoublevar("dim_value"), tclgetdoublevar("dim_bg")); draw(); Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"connected_nets")) /* selected nets connected to currently selected ones */ { int stop_at_junction = 0; cmd_found = 1; if(argc>=3 && argv[2][0] == '1') stop_at_junction = 1; select_connected_wires(stop_at_junction); Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"copy")) { cmd_found = 1; rebuild_selected_array(); save_selection(2); Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"copy_objects")) { cmd_found = 1; copy_objects(START); Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"create_plot_cmd") ) { cmd_found = 1; create_plot_cmd(); Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"cut")) { cmd_found = 1; rebuild_selected_array(); save_selection(2); delete(1/*to_push_undo*/); Tcl_ResetResult(interp); } } else if(argv[1][0] == 'd') { if(!strcmp(argv[1],"debug")) { cmd_found = 1; if(argc==3) { debug_var=atoi(argv[2]); tclsetvar("debug_var",argv[2]); } Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"delete")) { cmd_found = 1; if(argc==2) delete(1/*to_push_undo*/); Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"delete_files")) { cmd_found = 1; delete_files(); } else if(!strcmp(argv[1],"descend")) { cmd_found = 1; if(argc >=3) { int n = atoi(argv[2]); descend_schematic(n); } else { descend_schematic(0); } Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"descend_symbol")) { cmd_found = 1; descend_symbol(); Tcl_ResetResult(interp); } else if(!strcmp(argv[1], "display_hilights")) { char *str = NULL; cmd_found = 1; display_hilights(&str); Tcl_SetResult(interp, str, TCL_VOLATILE); my_free(1161, &str); } } else if(argv[1][0] == 'e') { if(!strcmp(argv[1],"edit_file") ) { cmd_found = 1; rebuild_selected_array(); if(xctx->lastsel==0 ) { save_schematic(xctx->sch[xctx->currsch]); /* sync data with disk file before editing file */ my_snprintf(name, S(name), "edit_file {%s}", abs_sym_path(xctx->sch[xctx->currsch], "")); tcleval(name); } else if(xctx->sel_array[0].type==ELEMENT) { my_snprintf(name, S(name), "edit_file {%s}", abs_sym_path(xctx->inst[xctx->sel_array[0].n].name, "")); tcleval(name); } } else if(!strcmp(argv[1],"edit_prop")) { cmd_found = 1; edit_property(0); Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"edit_vi_prop")) { cmd_found = 1; edit_property(1); Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"enable_layers")) { cmd_found = 1; enable_layers(); Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"exit")) { char * top_path; cmd_found = 1; top_path = xctx->top_path[0] ? xctx->top_path : "."; if(!strcmp(top_path, ".")) { if(has_x) { tcleval("new_window destroy_all"); /* close child schematics */ if(tclresult()[0] == '1') { if(xctx->modified) { tcleval("tk_messageBox -type okcancel -message \"" "[get_cell [xschem get schname] 0]" ": UNSAVED data: want to exit?\""); } if(!xctx->modified || !strcmp(tclresult(),"ok")) tcleval("exit"); } } else tcleval("exit"); /* if has_x == 0 there are no additional windows to close */ } else { Tcl_VarEval(interp, "xschem new_schematic destroy ", top_path, " ", xctx->top_path, ".drw {}" , NULL); } Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"expandlabel") && argc == 3) { int tmp, llen; char *result=NULL; const char *l; cmd_found = 1; l = expandlabel(argv[2], &tmp); llen = strlen(l); result = my_malloc(378, llen + 30); my_snprintf(result, llen + 30, "%s %d", l, tmp); Tcl_SetResult(interp, result, TCL_VOLATILE); my_free(927, &result); } } else if(argv[1][0] == 'f') { if(!strcmp(argv[1],"find_nth") ) { cmd_found = 1; if(argc>4) { char *r = NULL; my_strdup(1202, &r, find_nth(argv[2], argv[3][0], atoi(argv[4]))); Tcl_SetResult(interp, r ? r : "", TCL_VOLATILE); my_free(1203, &r); } } else if(!strcmp(argv[1],"flip")) { cmd_found = 1; if(! (xctx->ui_state & (STARTMOVE | STARTCOPY) ) ) { rebuild_selected_array(); move_objects(START,0,0,0); move_objects(FLIP|ROTATELOCAL,0,0,0); move_objects(END,0,0,0); } Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"fullscreen")) { cmd_found = 1; toggle_fullscreen(argv[2]); Tcl_ResetResult(interp); } } else if(argv[1][0] == 'g') { /* * ********** xschem get subcommands */ if(argc >= 3 && !strcmp(argv[1],"get") && !strcmp(argv[2],"schname")) { /* allows to retrieve name of n-th parent schematic */ int x; cmd_found = 1; if(argc >= 4) x = atoi(argv[3]); else x = xctx->currsch; if(x<0 && xctx->currsch+x>=0) { Tcl_SetResult(interp, xctx->sch[xctx->currsch+x], TCL_VOLATILE); } else if(x<=xctx->currsch) { Tcl_SetResult(interp, xctx->sch[x], TCL_VOLATILE); } } else if( argc >= 3 && !strcmp(argv[1],"get") && !strcmp(argv[2],"sch_path")) { int x; cmd_found = 1; if(argc == 4) x = atoi(argv[3]); else x = xctx->currsch; if(x<0 && xctx->currsch+x>=0) { Tcl_SetResult(interp, xctx->sch_path[xctx->currsch+x], TCL_VOLATILE); } else if(x<=xctx->currsch) { Tcl_SetResult(interp, xctx->sch_path[x], TCL_VOLATILE); } } else if(!strcmp(argv[1],"get") && argc==3) { cmd_found = 1; if(!strcmp(argv[2],"backlayer")) { char s[30]; /* overflow safe 20161122 */ my_snprintf(s, S(s), "%d",BACKLAYER); Tcl_SetResult(interp, s,TCL_VOLATILE); } else if(!strcmp(argv[2],"bbox_hilighted")) { xRect boundbox; char res[2048]; calc_drawing_bbox(&boundbox, 2); 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],"bbox_selected")) { xRect boundbox; char res[2048]; calc_drawing_bbox(&boundbox, 1); 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],"cadlayers")) { char s[30]; /* overflow safe 20161212 */ my_snprintf(s, S(s), "%d",cadlayers); Tcl_SetResult(interp, s,TCL_VOLATILE); } else if(!strcmp(argv[2],"color_ps")) { if( color_ps != 0 ) Tcl_SetResult(interp, "1",TCL_STATIC); else Tcl_SetResult(interp, "0",TCL_STATIC); } else if(!strcmp(argv[2],"current_dirname")) { Tcl_SetResult(interp, xctx->current_dirname, TCL_VOLATILE); } else if(!strcmp(argv[2],"currsch")) { char s[30]; /* overflow safe 20161122 */ my_snprintf(s, S(s), "%d",xctx->currsch); Tcl_SetResult(interp, s,TCL_VOLATILE); } else if(!strcmp(argv[2],"debug_var")) { char s[30]; /* overflow safe 20161122 */ my_snprintf(s, S(s), "%d",debug_var); Tcl_SetResult(interp, s,TCL_VOLATILE); } else if(!strcmp(argv[2],"draw_window")) { char s[30]; /* overflow safe 20161122 */ my_snprintf(s, S(s), "%d",xctx->draw_window); Tcl_SetResult(interp, s,TCL_VOLATILE); } else if(!strcmp(argv[2],"flat_netlist")) { if( flat_netlist != 0 ) Tcl_SetResult(interp, "1",TCL_STATIC); else Tcl_SetResult(interp, "0",TCL_STATIC); } else if(!strcmp(argv[2],"gridlayer")) { char s[30]; /* overflow safe 20161122 */ my_snprintf(s, S(s), "%d",GRIDLAYER); Tcl_SetResult(interp, s,TCL_VOLATILE); } else if(!strcmp(argv[2],"help")) { if( help != 0 ) Tcl_SetResult(interp, "1",TCL_STATIC); else Tcl_SetResult(interp, "0",TCL_STATIC); } else if(!strcmp(argv[2],"instances")) { char s[30]; /* overflow safe 20161122 */ my_snprintf(s, S(s), "%d",xctx->instances); Tcl_SetResult(interp, s,TCL_VOLATILE); } else if(!strcmp(argv[2],"lastsel")) { rebuild_selected_array(); if( xctx->lastsel != 0 ) Tcl_SetResult(interp, "1",TCL_STATIC); else Tcl_SetResult(interp, "0",TCL_STATIC); } else if(!strcmp(argv[2],"line_width")) { char s[40]; my_snprintf(s, S(s), "%g", xctx->lw); Tcl_SetResult(interp, s, TCL_VOLATILE); } else if(!strcmp(argv[2],"netlist_dir")) { Tcl_SetResult(interp, netlist_dir,TCL_VOLATILE); } else if(!strcmp(argv[2],"netlist_name")) { Tcl_SetResult(interp, xctx->netlist_name, TCL_VOLATILE); } else if(!strcmp(argv[2],"netlist_type")) { if(xctx->netlist_type == CAD_SPICE_NETLIST) { Tcl_SetResult(interp, "spice", TCL_STATIC); } else if(xctx->netlist_type == CAD_VHDL_NETLIST) { Tcl_SetResult(interp, "vhdl", TCL_STATIC); } else if(xctx->netlist_type == CAD_VERILOG_NETLIST) { Tcl_SetResult(interp, "verilog", TCL_STATIC); } else if(xctx->netlist_type == CAD_TEDAX_NETLIST) { Tcl_SetResult(interp, "tedax", TCL_STATIC); } else if(xctx->netlist_type == CAD_SYMBOL_ATTRS) { Tcl_SetResult(interp, "symbol", TCL_STATIC); } else { Tcl_SetResult(interp, "unknown", TCL_STATIC); } } else if(!strcmp(argv[2],"no_draw")) { if( xctx->no_draw != 0 ) Tcl_SetResult(interp, "1",TCL_STATIC); else Tcl_SetResult(interp, "0",TCL_STATIC); } else if(!strcmp(argv[2],"pinlayer")) { char s[30]; /* overflow safe 20161122 */ my_snprintf(s, S(s), "%d",PINLAYER); Tcl_SetResult(interp, s,TCL_VOLATILE); } else if(!strcmp(argv[2],"rectcolor")) { char s[30]; /* overflow safe 20161122 */ my_snprintf(s, S(s), "%d",xctx->rectcolor); Tcl_SetResult(interp, s,TCL_VOLATILE); } else if(!strcmp(argv[2],"sellayer")) { char s[30]; /* overflow safe 20161122 */ my_snprintf(s, S(s), "%d",SELLAYER); Tcl_SetResult(interp, s,TCL_VOLATILE); } else if(!strcmp(argv[2],"semaphore")) { char s[30]; /* overflow safe 20161122 */ my_snprintf(s, S(s), "%d",xctx->semaphore); Tcl_SetResult(interp, s,TCL_VOLATILE); } #ifndef __unix__ else if(!strcmp(argv[2], "temp_dir")) { if(win_temp_dir[0] != '\0') Tcl_SetResult(interp, win_temp_dir, TCL_VOLATILE); else { TCHAR tmp_buffer_path[MAX_PATH]; DWORD ret_val = GetTempPath(MAX_PATH, tmp_buffer_path); if(ret_val > MAX_PATH || (ret_val == 0)) { Tcl_SetResult(interp, "xschem get temp_dir failed\n", TCL_STATIC); fprintf(errfp, "xschem get temp_dir: path error\n"); tcleval("exit"); } else { char s[MAX_PATH]; size_t num_char_converted; int err = wcstombs_s(&num_char_converted, s, MAX_PATH, tmp_buffer_path, MAX_PATH); /*unicode TBD*/ if(err != 0) { Tcl_SetResult(interp, "xschem get temp_dir conversion failed\n", TCL_STATIC); fprintf(errfp, "xschem get temp_dir: conversion error\n"); tcleval("exit"); } else { change_to_unix_fn(s); int slen = strlen(s); if(s[slen - 1] == '/') s[slen - 1] = '\0'; my_strncpy(win_temp_dir, s, S(win_temp_dir)); dbg(2, "scheduler(): win_temp_dir is %s\n", win_temp_dir); Tcl_SetResult(interp, s, TCL_VOLATILE); } } } } #endif else if(!strcmp(argv[2],"text_svg")) { if( text_svg != 0 ) Tcl_SetResult(interp, "1",TCL_STATIC); else Tcl_SetResult(interp, "0",TCL_STATIC); } else if(!strcmp(argv[2],"textlayer")) { char s[30]; /* overflow safe 20161122 */ my_snprintf(s, S(s), "%d",TEXTLAYER); Tcl_SetResult(interp, s,TCL_VOLATILE); } else if(!strcmp(argv[2],"version")) { char s[30]; /* overflow safe 20161122 */ my_snprintf(s, S(s), "XSCHEM V%s",XSCHEM_VERSION); Tcl_SetResult(interp, s,TCL_VOLATILE); } else if(!strcmp(argv[2],"wirelayer")) { char s[30]; /* overflow safe 20161122 */ my_snprintf(s, S(s), "%d",WIRELAYER); Tcl_SetResult(interp, s,TCL_VOLATILE); } else { fprintf(errfp, "xschem get %s: invalid command.\n", argv[2]); } } else if(!strcmp(argv[1],"get_tok") ) { char *s=NULL; int t; cmd_found = 1; if(argc < 4) {Tcl_SetResult(interp, "Missing arguments", TCL_STATIC);return TCL_ERROR;} if(argc == 5) t = atoi(argv[4]); else t = 0; my_strdup(648, &s, get_tok_value(argv[2], argv[3], t)); Tcl_SetResult(interp, s, TCL_VOLATILE); my_free(649, &s); } else if(!strcmp(argv[1],"get_tok_size") ) { char s[30]; cmd_found = 1; my_snprintf(s, S(s), "%d", (int)xctx->get_tok_size); Tcl_SetResult(interp, s, TCL_VOLATILE); } else if(!strcmp(argv[1],"getprop")) { cmd_found = 1; if( argc > 2 && !strcmp(argv[2], "instance")) { int i; const char *tmp; if(argc!=5 && argc !=4) { Tcl_SetResult(interp, "'xschem getprop instance' needs 1 or 2 additional arguments", TCL_STATIC); return TCL_ERROR; } if( (i = get_instance(argv[3])) < 0 ) { Tcl_SetResult(interp, "xschem getprop: instance not found", TCL_STATIC); return TCL_ERROR; } if(argc == 4) { Tcl_SetResult(interp, xctx->inst[i].prop_ptr, TCL_VOLATILE); } else if(!strcmp(argv[4],"cell::name")) { tmp = xctx->inst[i].name; Tcl_SetResult(interp, (char *) tmp, TCL_VOLATILE); } else if(strstr(argv[4], "cell::") ) { tmp = get_tok_value( (xctx->inst[i].ptr+ xctx->sym)->prop_ptr, argv[4]+6, 0); dbg(1, "scheduler(): xschem getprop: looking up instance %d prop cell::|%s| : |%s|\n", i, argv[4]+6, tmp); Tcl_SetResult(interp, (char *) tmp, TCL_VOLATILE); } else { Tcl_SetResult(interp, (char *)get_tok_value(xctx->inst[i].prop_ptr, argv[4], 0), TCL_VOLATILE); } } else if(argc > 2 && !strcmp(argv[2], "instance_pin")) { /* 0 1 2 3 4 5 */ /* xschem getprop instance_pin X10 PLUS [pin_attr] */ /* xschem getprop instance_pin X10 1 [pin_attr] */ int inst, n=-1, tmp; char *subtok=NULL; const char *value=NULL; if(argc != 6 && argc != 5) { Tcl_SetResult(interp, "xschem getprop instance_pin needs 2 or 3 additional arguments", TCL_STATIC); return TCL_ERROR; } if( (inst = get_instance(argv[3])) < 0 ) { Tcl_SetResult(interp, "xschem getprop: instance not found", TCL_STATIC); return TCL_ERROR; } if(isonlydigit(argv[4])) { n = atoi(argv[4]); } else { xSymbol *ptr = xctx->inst[inst].ptr+ xctx->sym; for(n = 0; n < ptr->rects[PINLAYER]; n++) { char *prop = ptr->rect[PINLAYER][n].prop_ptr; if(!strcmp(get_tok_value(prop, "name",0), argv[4])) break; } } if(n>=0 && n < (xctx->inst[inst].ptr+ xctx->sym)->rects[PINLAYER]) { if(argc == 5) { Tcl_SetResult(interp, (xctx->inst[inst].ptr+ xctx->sym)->rect[PINLAYER][n].prop_ptr, TCL_VOLATILE); } else { tmp = 100 + strlen(argv[4]) + strlen(argv[5]); subtok = my_malloc(83,tmp); my_snprintf(subtok, tmp, "%s(%s)", argv[5], argv[4]); value = get_tok_value(xctx->inst[inst].prop_ptr,subtok,0); if(!value[0]) { my_snprintf(subtok, tmp, "%s(%d)", argv[5], n); value = get_tok_value(xctx->inst[inst].prop_ptr,subtok,0); } if(!value[0]) { value = get_tok_value((xctx->inst[inst].ptr+ xctx->sym)->rect[PINLAYER][n].prop_ptr,argv[5],0); } if(value[0] != 0) { char *ss; int slot; if( (ss = strchr(xctx->inst[inst].instname, ':')) ) { sscanf(ss + 1, "%d", &slot); if(strstr(value, ":")) value = find_nth(value, ':', slot); } Tcl_SetResult(interp, (char *)value, TCL_VOLATILE); } my_free(924, &subtok); } } /* xschem getprop symbol lm358.sym [type] */ } else if( !strcmp(argv[2],"symbol")) { int i, found=0; if(argc!=5 && argc !=4) { Tcl_SetResult(interp, "xschem getprop needs 2 or 3 additional arguments", TCL_STATIC); return TCL_ERROR; } for(i=0; isymbols; i++) { if(!strcmp(xctx->sym[i].name,argv[3])){ found=1; break; } } if(!found) { Tcl_SetResult(interp, "Symbol not found", TCL_STATIC); return TCL_ERROR; } if(argc == 4) Tcl_SetResult(interp, xctx->sym[i].prop_ptr, TCL_VOLATILE); else Tcl_SetResult(interp, (char *)get_tok_value(xctx->sym[i].prop_ptr, argv[4], 0), TCL_VOLATILE); } } else if(!strcmp(argv[1],"globals")) { cmd_found = 1; printf("*******global variables:*******\n"); printf("netlist_dir=%s\n", netlist_dir? netlist_dir: ""); printf("INT_WIDTH(lw)=%d\n", INT_WIDTH(xctx->lw)); printf("wires=%d\n", xctx->wires); printf("instances=%d\n", xctx->instances); printf("symbols=%d\n", xctx->symbols); printf("lastsel=%d\n", xctx->lastsel); printf("texts=%d\n", xctx->texts); printf("maxt=%d\n", xctx->maxt); printf("maxw=%d\n", xctx->maxw); printf("maxi=%d\n", xctx->maxi); printf("maxsel=%d\n", xctx->maxsel); printf("zoom=%.16g\n", xctx->zoom); printf("xorigin=%.16g\n", xctx->xorigin); printf("yorigin=%.16g\n", xctx->yorigin); for(i=0;i<8;i++) { printf("rects[%d]=%d\n", i, xctx->rects[i]); printf("lines[%d]=%d\n", i, xctx->lines[i]); printf("maxr[%d]=%d\n", i, xctx->maxr[i]); printf("maxl[%d]=%d\n", i, xctx->maxl[i]); } printf("current_name=%s\n", xctx->current_name); printf("currsch=%d\n", xctx->currsch); for(i=0;i<=xctx->currsch;i++) { printf("previous_instance[%d]=%d\n",i,xctx->previous_instance[i]); printf("sch_path[%d]=%s\n",i,xctx->sch_path[i]? xctx->sch_path[i]:""); printf("sch[%d]=%s\n",i,xctx->sch[i]); } printf("modified=%d\n", xctx->modified); printf("areaw=%d\n", xctx->areaw); printf("areah=%d\n", xctx->areah); printf("color_ps=%d\n", color_ps); printf("hilight_nets=%d\n", xctx->hilight_nets); printf("semaphore=%d\n", xctx->semaphore); printf("prep_net_structs=%d\n", xctx->prep_net_structs); printf("prep_hi_structs=%d\n", xctx->prep_hi_structs); printf("prep_hash_inst=%d\n", xctx->prep_hash_inst); printf("prep_hash_wires=%d\n", xctx->prep_hash_wires); printf("need_reb_sel_arr=%d\n", xctx->need_reb_sel_arr); printf("******* end global variables:*******\n"); } else if(!strcmp(argv[1],"go_back")) { cmd_found = 1; go_back(1); Tcl_ResetResult(interp); } } else if(argv[1][0] == 'h') { if(!strcmp(argv[1],"help")) { cmd_found = 1; printf("xschem : function used to communicate with the C program\n"); printf("Usage:\n"); printf(" xschem callback X-event_type mousex mousey Xkeysym mouse_button Xstate\n"); printf(" can be used to send any event to the application\n"); printf(" xschem netlist\n"); printf(" generates a netlist in the selected format for the current schematic\n"); printf(" xschem simulate\n"); printf(" launches the currently set simulator on the generated netlist\n"); printf(" xschem redraw\n"); printf(" Redraw the window\n"); printf(" xschem new_window library/cell\n"); printf(" start a new window optionally with specified cell\n"); printf(" xschem schematic_in_new_window \n"); printf(" start a new window with selected element schematic\n"); printf(" xschem symbol_in_new_window \n"); printf(" start a new window with selected element schematic\n"); printf(" xschem globals\n"); printf(" print information about global variables\n"); printf(" xschem inst_ptr n\n"); printf(" return inst_ptr of inst[n]\n"); printf(" xschem netlist\n"); printf(" perform a global netlist on current schematic\n"); printf(" xschem netlist_type type\n"); printf(" set netlist type to , currently spice, vhdl, verilog or tedax\n"); printf(" xschem save [library/name]\n"); printf(" save current schematic, optionally a lib/name can be given\n"); printf(" xschem saveas\n"); printf(" save current schematic, asking for a filename\n"); printf(" xschem load library/cell\n"); printf(" load specified cell from library\n"); printf(" xschem load_symbol library/cell\n"); printf(" load specified cell symbol view from library\n"); printf(" xschem reload\n"); printf(" reload current cell from library\n"); printf(" xschem instance library/cell x y rot flip [property string]\n"); printf(" place instance cell of the given library at x,y, rot, flip\n"); printf(" can also be given a property string\n"); printf(" xschem rect x1 y1 x2 y2 [pos]\n"); printf(" place rectangle, optionally at pos (position in database)\n"); printf(" xschem line x1 y1 x2 y2 [pos]\n"); printf(" place line, optionally at pos (position in database)\n"); printf(" xschem wire x1 y1 x2 y2 [pos]\n"); printf(" place wire, optionally at pos (position in database)\n"); printf(" xschem select instance|wire|text n\n"); printf(" select instance or text or wire number n\n"); printf(" xschem select_all\n"); printf(" select all objects\n"); printf(" xschem descend\n"); printf(" descend into schematic of selected element\n"); printf(" xschem descend_symbol\n"); printf(" descend into symbol of selected element\n"); printf(" xschem go_back\n"); printf(" back from selected element\n"); printf(" xschem unselect\n"); printf(" unselect selected objects\n"); printf(" xschem zoom_out\n"); printf(" zoom out\n"); printf(" xschem zoom_in\n"); printf(" zoom in\n"); printf(" xschem zoom_full\n"); printf(" zoom full\n"); printf(" xschem zoom_box\n"); printf(" zoom box\n"); printf(" xschem paste\n"); printf(" paste selection from clipboard\n"); printf(" xschem merge\n"); printf(" merge external file into current schematic\n"); printf(" xschem cut\n"); printf(" cut selection to clipboard\n"); printf(" xschem copy\n"); printf(" copy selection to clipboard\n"); printf(" xschem copy_objects\n"); printf(" duplicate selected objects\n"); printf(" xschem move_objects [deltax deltay]\n"); printf(" move selected objects\n"); printf(" xschem line_width n\n"); printf(" set line width to (float) n\n"); printf(" xschem delete\n"); printf(" delete selected objects\n"); printf(" xschem unhilight\n"); printf(" unlight selected nets/pins\n"); printf(" xschem hilight\n"); printf(" hilight selected nets/pins\n"); printf(" xschem clear_hilights\n"); printf(" unhilight all nets/pins\n"); printf(" xschem print [color]\n"); printf(" print schematic (optionally in color)\n"); printf(" xschem search regex|exact