summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--struct.c28
-rw-r--r--txr.111
2 files changed, 27 insertions, 12 deletions
diff --git a/struct.c b/struct.c
index 066b6f44..f42c685b 100644
--- a/struct.c
+++ b/struct.c
@@ -605,20 +605,24 @@ val clear_struct(val strct, val value)
val replace_struct(val target, val source)
{
const val self = lit("replace-struct");
- struct struct_inst *tsi = struct_handle(target, self);
- struct struct_inst *ssi = struct_handle(source, self);
- struct struct_type *sst = ssi->type;
- cnum nslots = sst->nslots;
- size_t size = offsetof(struct struct_inst, slot) + sizeof (val) * nslots;
- struct struct_inst *ssi_copy = coerce(struct struct_inst *, chk_malloc(size));
- check_init_lazy_struct(source, ssi);
- check_init_lazy_struct(target, tsi);
+ if (target != source) {
+ struct struct_inst *tsi = struct_handle(target, self);
+ struct struct_inst *ssi = struct_handle(source, self);
+ struct struct_type *sst = ssi->type;
+ cnum nslots = sst->nslots;
+ size_t size = offsetof(struct struct_inst, slot) + sizeof (val) * nslots;
+ struct struct_inst *ssi_copy = coerce(struct struct_inst *, chk_malloc(size));
+
+ check_init_lazy_struct(source, ssi);
+ check_init_lazy_struct(target, tsi);
+
+ memcpy(ssi_copy, ssi, size);
+ free(tsi);
+ target->co.handle = coerce(mem_t *, ssi_copy);
+ target->co.cls = source->co.cls;
+ }
- memcpy(ssi_copy, ssi, size);
- free(tsi);
- target->co.handle = coerce(mem_t *, ssi_copy);
- target->co.cls = source->co.cls;
return target;
}
diff --git a/txr.1 b/txr.1
index c1fc78ce..c7fde830 100644
--- a/txr.1
+++ b/txr.1
@@ -21521,6 +21521,17 @@ prior to using
.codn replace-struct ,
or to take other measures to handle the situation.
+If the
+.meta target-obj
+and
+.meta source-obj
+arguments are the same object,
+.code replace-struct
+has no effect.
+
+The return value is
+.metn target-obj .
+
.coNP Function @ method
.synb
.mets (method < struct-obj << slot-name )