diff --git a/docs/GLM/General/Inherit.md b/docs/GLM/General/Inherit.md new file mode 100644 index 000000000..425368490 --- /dev/null +++ b/docs/GLM/General/Inherit.md @@ -0,0 +1,38 @@ +[[/GLM/General/Inherit.md]] -- Inherit property values + +# Synopsis + +GLM: + +~~~ +object +{ + inherit; + @; +} +~~~ + +# Description + +The `inherit` property value causes the value to be copied from the parent object. This requires that the parent already be defined. The alternative syntax `@` inherits the property value from the named object. + +# Example + +This example copies the value of `x` from object `test1` into object `test2`: + +~~~ +class test +{ + double x; +} +object test +{ + name test1; + x 1.23; +} +object test +{ + name test2; + x @test1; +} +~~~ diff --git a/gldcore/autotest/test_inherit.glm b/gldcore/autotest/test_inherit.glm new file mode 100644 index 000000000..4b6b28ba6 --- /dev/null +++ b/gldcore/autotest/test_inherit.glm @@ -0,0 +1,21 @@ +module assert; + +class test + { + double x; + } + object test + { + name test1; + x 8.88; + } + object test + { + name test2; + x @test1; + object assert{ + target x; + relation "=="; + value 8.88; + }; + } \ No newline at end of file diff --git a/gldcore/load.cpp b/gldcore/load.cpp index 88e96336d..aba8725a9 100755 --- a/gldcore/load.cpp +++ b/gldcore/load.cpp @@ -4100,6 +4100,7 @@ int GldLoader::json_block(PARSER, OBJECT *obj, const char *propname) int GldLoader::object_properties(PARSER, CLASS *oclass, OBJECT *obj) { char propname[64]; + char parentname[64]; static char propval[65536*10]; double dval; complex cval; @@ -4228,12 +4229,41 @@ int GldLoader::object_properties(PARSER, CLASS *oclass, OBJECT *obj) syntax_error(filename,linenum,"unable to get value of inherit property '%s'", propname); REJECT; } - if ( object_set_value_by_name(obj,propname,value)<=0 ) + else if ( object_set_value_by_name(obj,propname,value) <= 0 ) { syntax_error(filename,linenum,"unable to set value of inherit property '%s'", propname); REJECT; } - // DPC 3/28/20: is SAVE/ACCEPT needed here? + else + { + SAVETERM; + ACCEPT; + } + } + else if ( prop != NULL && LITERAL("@") && TERM(name(HERE,parentname,sizeof(parentname))) ) + { + OBJECT *parent = object_find_name(parentname); + char value[1024]; + if ( parent == NULL ) + { + syntax_error(filename,linenum,"cannot inherit from unknown object '%s'",parentname); + REJECT; + } + else if ( ! object_get_value_by_name(parent,propname,value,sizeof(value)) ) + { + syntax_error(filename,linenum,"unable to get value of inherit property '%s' from object '%s'", propname,parentname); + REJECT; + } + else if ( object_set_value_by_name(obj,propname,value) <= 0 ) + { + syntax_error(filename,linenum,"unable to set value of inherit property '%s'", propname); + REJECT; + } + else + { + SAVETERM; + ACCEPT; + } } else if ( prop != NULL && prop->ptype == PT_complex && MARK && TERM(complex_unit(HERE,&cval,&unit))) @@ -4243,7 +4273,7 @@ int GldLoader::object_properties(PARSER, CLASS *oclass, OBJECT *obj) syntax_error(filename,linenum,"units of value are incompatible with units of property, cannot convert from %s to %s", unit->name,prop->unit->name); REJECT; } - else if (object_set_complex_by_name(obj,propname,cval)==0) + else if ( object_set_complex_by_name(obj,propname,cval) == 0 ) { syntax_error(filename,linenum,"complex property %s of %s %s could not be set to complex value '%g%+gi'", propname, format_object(obj).c_str(), cval.Re(), cval.Im()); REJECT; @@ -4262,7 +4292,7 @@ int GldLoader::object_properties(PARSER, CLASS *oclass, OBJECT *obj) syntax_error(filename,linenum,"units of value are incompatible with units of property, cannot convert from %s to %s", unit->name,prop->unit->name); REJECT; } - else if (object_set_double_by_name(obj,propname,dval)==0) + else if ( object_set_double_by_name(obj,propname,dval) == 0 ) { syntax_error(filename,linenum,"double property %s of %s %s could not be set to expression evaluating to '%g'", propname, format_object(obj).c_str(), dval); REJECT;