When saving a schematic issue a warning if disk file has been changed since opening
This commit is contained in:
parent
9ceb25716e
commit
a495ada2ed
|
|
@ -373,6 +373,7 @@ char *strtoupper(char* s) {
|
|||
return s;
|
||||
}
|
||||
|
||||
/* call hash_all_names() (once) before (repeatedly) using this function */
|
||||
void set_inst_prop(int i)
|
||||
{
|
||||
char *ptr;
|
||||
|
|
|
|||
35
src/save.c
35
src/save.c
|
|
@ -928,8 +928,9 @@ void make_symbol(void)
|
|||
void make_schematic(const char *schname)
|
||||
{
|
||||
FILE *fd=NULL;
|
||||
|
||||
rebuild_selected_array();
|
||||
if (!xctx->lastsel) return;
|
||||
if(!xctx->lastsel) return;
|
||||
if (!(fd = fopen(schname, "w")))
|
||||
{
|
||||
fprintf(errfp, "make_schematic(): problems opening file %s \n", schname);
|
||||
|
|
@ -965,6 +966,7 @@ int save_schematic(const char *schname) /* 20171020 added return value */
|
|||
FILE *fd;
|
||||
char name[PATH_MAX]; /* overflow safe 20161122 */
|
||||
char *top_path;
|
||||
struct stat buf;
|
||||
|
||||
top_path = xctx->top_path[0] ? xctx->top_path : ".";
|
||||
|
||||
|
|
@ -978,6 +980,17 @@ int save_schematic(const char *schname) /* 20171020 added return value */
|
|||
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);
|
||||
}
|
||||
|
||||
if(!stat(name, &buf)) {
|
||||
if(xctx->time_last_modify && xctx->time_last_modify != buf.st_mtime) {
|
||||
Tcl_VarEval(interp, "ask_save \"Schematic file: ", name,
|
||||
" has been changed since opening.\nSave anyway?\" 0", NULL);
|
||||
if(strcmp(tclresult(), "yes") ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!(fd=fopen(name,"w")))
|
||||
{
|
||||
fprintf(errfp, "save_schematic(): problems opening file %s \n",name);
|
||||
|
|
@ -987,6 +1000,10 @@ int save_schematic(const char *schname) /* 20171020 added return value */
|
|||
unselect_all();
|
||||
write_xschem_file(fd);
|
||||
fclose(fd);
|
||||
/* update time stamp */
|
||||
if(!stat(name)) {
|
||||
xctx->time_last_modify = buf.st_mtime;
|
||||
}
|
||||
my_strncpy(xctx->current_name, rel_sym_path(name), S(xctx->current_name));
|
||||
/* <<<<< >>>> why clear all these? */
|
||||
xctx->prep_hi_structs=0;
|
||||
|
|
@ -1058,6 +1075,12 @@ void load_schematic(int load_symbols, const char *filename, int reset_undo) /* 2
|
|||
dbg(1, "load_schematic(): opening file for loading:%s, filename=%s\n", name, filename);
|
||||
dbg(1, "load_schematic(): sch[currsch]=%s\n", xctx->sch[xctx->currsch]);
|
||||
if(!name[0]) return;
|
||||
|
||||
if(!stat(name, &buf)) { /* file exists */
|
||||
xctx->time_last_modify = buf.st_mtime;
|
||||
} else {
|
||||
xctx->time_last_modify = 0;
|
||||
}
|
||||
if( (fd=fopen(name,fopen_read_mode))== NULL) {
|
||||
fprintf(errfp, "load_schematic(): unable to open file: %s, filename=%s\n",
|
||||
name, filename ? filename : "<NULL>");
|
||||
|
|
@ -2208,7 +2231,6 @@ void create_sch_from_sym(void)
|
|||
char *dir = NULL;
|
||||
char *prop = NULL;
|
||||
char schname[PATH_MAX];
|
||||
char *savecmd=NULL;
|
||||
char *sub_prop;
|
||||
char *sub2_prop=NULL;
|
||||
char *str=NULL;
|
||||
|
|
@ -2235,12 +2257,9 @@ void create_sch_from_sym(void)
|
|||
my_strncpy(schname, add_ext(abs_sym_path(xctx->inst[xctx->sel_array[0].n].name, ""), ".sch"), S(schname));
|
||||
}
|
||||
if( !stat(schname, &buf) ) {
|
||||
my_strdup(353, &savecmd, "ask_save \" create schematic file: ");
|
||||
my_strcat(354, &savecmd, schname);
|
||||
my_strcat(355, &savecmd, " ?\nWARNING: This schematic file already exists, it will be overwritten\"");
|
||||
tcleval(savecmd);
|
||||
Tcl_VarEval(interp, "ask_save \"Create schematic file: ", schname,
|
||||
"?\nWARNING: This schematic file already exists, it will be overwritten\"", NULL);
|
||||
if(strcmp(tclresult(), "yes") ) {
|
||||
my_free(914, &savecmd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -2248,7 +2267,6 @@ void create_sch_from_sym(void)
|
|||
{
|
||||
fprintf(errfp, "create_sch_from_sym(): problems opening file %s \n",schname);
|
||||
tcleval("alert_ {file opening for write failed!} {}");
|
||||
my_free(915, &savecmd);
|
||||
return;
|
||||
}
|
||||
fprintf(fd, "v {xschem version=%s file_version=%s}\n", XSCHEM_VERSION, XSCHEM_FILE_VERSION);
|
||||
|
|
@ -2311,7 +2329,6 @@ void create_sch_from_sym(void)
|
|||
} /* if(xctx->lastsel...) */
|
||||
my_free(916, &dir);
|
||||
my_free(917, &prop);
|
||||
my_free(918, &savecmd);
|
||||
my_free(919, &sub2_prop);
|
||||
my_free(920, &str);
|
||||
}
|
||||
|
|
|
|||
19
src/token.c
19
src/token.c
|
|
@ -32,7 +32,7 @@ struct inst_hashentry {
|
|||
};
|
||||
|
||||
|
||||
static struct inst_hashentry *table[HASHSIZE];
|
||||
static struct inst_hashentry *table[HASHSIZE]; /* safe with multiple schematics, hash rebuilt before usage */
|
||||
|
||||
enum status {TOK_BEGIN, TOK_TOKEN, TOK_SEP, TOK_VALUE, TOK_END, TOK_ENDTOK};
|
||||
|
||||
|
|
@ -670,7 +670,7 @@ void new_prop_string(int i, const char *old_prop, int fast, int dis_uniq_names)
|
|||
const char *tmp;
|
||||
const char *tmp2;
|
||||
int q,qq;
|
||||
static int last[256];
|
||||
static int last[256]; /* safe to keep with multiple schematics, reset on 1st invocation */
|
||||
int old_name_len;
|
||||
int new_name_len;
|
||||
int n;
|
||||
|
|
@ -1690,8 +1690,7 @@ int print_spice_element(FILE *fd, int inst)
|
|||
/* fputs(value,fd); */
|
||||
}
|
||||
}
|
||||
else if (strcmp(token,"@symname")==0) /* of course symname must not be present */
|
||||
/* in hash table */
|
||||
else if (strcmp(token,"@symname")==0) /* of course symname must not be present in attributes */
|
||||
{
|
||||
const char *s = skip_dir(xctx->inst[inst].name);
|
||||
tmp = strlen(s) +100 ; /* always make room for some extra chars
|
||||
|
|
@ -1700,8 +1699,7 @@ int print_spice_element(FILE *fd, int inst)
|
|||
result_pos += my_snprintf(result + result_pos, tmp, "%s", s);
|
||||
/* fputs(s,fd); */
|
||||
}
|
||||
else if (strcmp(token,"@symname_ext")==0) /* of course symname must not be present */
|
||||
/* in hash table */
|
||||
else if (strcmp(token,"@symname_ext")==0) /* of course symname must not be present in attributes */
|
||||
{
|
||||
const char *s = get_cell_w_ext(xctx->inst[inst].name, 0);
|
||||
tmp = strlen(s) +100 ; /* always make room for some extra chars
|
||||
|
|
@ -1710,8 +1708,7 @@ int print_spice_element(FILE *fd, int inst)
|
|||
result_pos += my_snprintf(result + result_pos, tmp, "%s", s);
|
||||
/* fputs(s,fd); */
|
||||
}
|
||||
else if(strcmp(token,"@schname")==0) /* of course schname must not be present */
|
||||
/* in hash table */
|
||||
else if(strcmp(token,"@schname")==0) /* of course schname must not be present in attributes */
|
||||
{
|
||||
tmp = strlen(xctx->current_name) +100 ; /* always make room for some extra chars
|
||||
* so 1-char writes to result do not need reallocs */
|
||||
|
|
@ -1720,8 +1717,8 @@ int print_spice_element(FILE *fd, int inst)
|
|||
/* fputs(xctx->current_name, fd); */
|
||||
|
||||
}
|
||||
else if(strcmp(token,"@pinlist")==0) /* of course pinlist must not be present */
|
||||
/* in hash table. print multiplicity */
|
||||
else if(strcmp(token,"@pinlist")==0) /* of course pinlist must not be present in attributes */
|
||||
/* print multiplicity */
|
||||
{ /* and node number: m1 n1 m2 n2 .... */
|
||||
for(i=0;i<no_of_pins;i++)
|
||||
{
|
||||
|
|
@ -2758,7 +2755,7 @@ const char *find_nth(const char *str, char sep, int n)
|
|||
const char *translate(int inst, const char* s)
|
||||
{
|
||||
static const char empty[]="";
|
||||
static char *result=NULL;
|
||||
static char *result=NULL; /* safe to keep even with multiple schematics */
|
||||
int size=0, tmp;
|
||||
register int c, state=TOK_BEGIN, space;
|
||||
char *token=NULL;
|
||||
|
|
|
|||
|
|
@ -584,6 +584,7 @@ void alloc_xschem_data(const char *top_path)
|
|||
#ifdef IN_MEMORY_UNDO
|
||||
xctx->initialized = 0; /* in_memory_undo */
|
||||
#endif
|
||||
xctx->time_last_modify = 0;
|
||||
}
|
||||
|
||||
void delete_schematic_data(void)
|
||||
|
|
|
|||
|
|
@ -709,6 +709,7 @@ typedef struct {
|
|||
int *fill_type; /* for every layer: 0: no fill, 1, solid fill, 2: stipple fill */
|
||||
int fill_pattern;
|
||||
int draw_window;
|
||||
time_t time_last_modify;
|
||||
} Xschem_ctx;
|
||||
|
||||
struct Lcc { /* used for symbols containing schematics as instances (LCC, Local Custom Cell) */
|
||||
|
|
|
|||
|
|
@ -2270,7 +2270,7 @@ proc attach_labels_to_inst {} {
|
|||
return {}
|
||||
}
|
||||
|
||||
proc ask_save { {ask {save file?}} } {
|
||||
proc ask_save { {ask {save file?}} {cancel 1}} {
|
||||
global rcode wm_fix
|
||||
set rcode {}
|
||||
if { [winfo exists .dialog] } return
|
||||
|
|
@ -2290,10 +2290,12 @@ proc ask_save { {ask {save file?}} } {
|
|||
set rcode {yes}
|
||||
destroy .dialog
|
||||
}
|
||||
button .dialog.f1.b2 -text {Cancel} -command\
|
||||
{
|
||||
set rcode {}
|
||||
destroy .dialog
|
||||
if {$cancel} {
|
||||
button .dialog.f1.b2 -text {Cancel} -command\
|
||||
{
|
||||
set rcode {}
|
||||
destroy .dialog
|
||||
}
|
||||
}
|
||||
button .dialog.f1.b3 -text {No} -command\
|
||||
{
|
||||
|
|
@ -2301,8 +2303,14 @@ proc ask_save { {ask {save file?}} } {
|
|||
destroy .dialog
|
||||
}
|
||||
pack .dialog.l1 .dialog.f1 -side top -fill x
|
||||
pack .dialog.f1.b1 .dialog.f1.b2 .dialog.f1.b3 -side left -fill x -expand yes
|
||||
bind .dialog <Escape> {.dialog.f1.b2 invoke}
|
||||
pack .dialog.f1.b1 -side left -fill x -expand yes
|
||||
if { $cancel} {
|
||||
pack .dialog.f1.b2 -side left -fill x -expand yes
|
||||
}
|
||||
pack .dialog.f1.b3 -side left -fill x -expand yes
|
||||
if {$cancel} {
|
||||
bind .dialog <Escape> {.dialog.f1.b2 invoke}
|
||||
}
|
||||
# needed, otherwise problems when descending with double clixk 23012004
|
||||
tkwait visibility .dialog
|
||||
grab set .dialog
|
||||
|
|
|
|||
Loading…
Reference in New Issue