---
properties.h | 19 ++++++++
properties.m | 154 +++++++++++++++++++++++++++++++++++------------------------
2 files changed, 110 insertions(+), 63 deletions(-)
diff --git a/properties.h b/properties.h
index 069e206..33db750 100644
--- a/properties.h
+++ b/properties.h
@@ -122,6 +122,25 @@ struct objc_property_list
struct objc_property properties[];
};
+/**
+ * Structure used for copying property attributes.
+ */
+struct objc_property_attribute
+{
+ /**
+ * Name of the attribute.
+ */
+ const char *name;
+ /**
+ * Value of the attribute.
+ */
+ const char *value;
+ /**
+ * Length of value string.
+ */
+ size_t length;
+};
+
PRIVATE BOOL initPropertyFromAttributesList(struct objc_property *property,
const char *name,
const objc_property_attribute_t *attributes,
diff --git a/properties.m b/properties.m
index 2c28971..a5b69d3 100644
--- a/properties.m
+++ b/properties.m
@@ -367,80 +367,111 @@ const char *property_getAttributes(objc_property_t property)
objc_property_attribute_t *property_copyAttributeList(objc_property_t property,
unsigned int *outCount)
{
- if (NULL == property) { return NULL; }
- objc_property_attribute_t attrs[10];
- int count = 0;
+ if (NULL == property) { if (outCount) *outCount = 0; return NULL; }
+ struct objc_property_attribute attrs[10];
+ size_t attrcount = 0;
+ size_t stringslen = 0;
if (property->type_encoding != NULL)
{
- attrs[count].name = "T";
- attrs[count].value = property->type_encoding;
- count++;
+ attrs[attrcount].name = "T";
+ attrs[attrcount].value = property->type_encoding;
+ attrs[attrcount].length = strlen(property->type_encoding);
+ stringslen += attrs[attrcount].length + 3;
+ attrcount++;
}
if ((property->attributes & OBJC_PR_readonly) == OBJC_PR_readonly)
{
- attrs[count].name = "R";
- attrs[count].value = "";
- count++;
+ attrs[attrcount].name = "R";
+ attrs[attrcount].value = "";
+ attrs[attrcount].length = 0;
+ stringslen += 3;
+ attrcount++;
}
- else
+ if ((property->attributes & OBJC_PR_retain) == OBJC_PR_retain
+ || (property->attributes & OBJC_PR_strong) == OBJC_PR_strong)
{
- if ((property->attributes & OBJC_PR_retain) == OBJC_PR_retain
- || (property->attributes & OBJC_PR_strong) == OBJC_PR_strong)
- {
- attrs[count].name = "&";
- attrs[count].value = "";
- count++;
- }
- else if ((property->attributes & OBJC_PR_copy) == OBJC_PR_copy)
- {
- attrs[count].name = "C";
- attrs[count].value = "";
- count++;
- }
- else if ((property->attributes & OBJC_PR_weak) == OBJC_PR_weak)
- {
- attrs[count].name = "W";
- attrs[count].value = "";
- count++;
- }
+ attrs[attrcount].name = "&";
+ attrs[attrcount].value = "";
+ attrs[attrcount].length = 0;
+ stringslen += 3;
+ attrcount++;
+ }
+ if ((property->attributes & OBJC_PR_copy) == OBJC_PR_copy)
+ {
+ attrs[attrcount].name = "C";
+ attrs[attrcount].value = "";
+ attrs[attrcount].length = 0;
+ stringslen += 3;
+ attrcount++;
+ }
+ if ((property->attributes & OBJC_PR_weak) == OBJC_PR_weak)
+ {
+ attrs[attrcount].name = "W";
+ attrs[attrcount].value = "";
+ attrs[attrcount].length = 0;
+ stringslen += 3;
+ attrcount++;
}
if ((property->attributes & OBJC_PR_dynamic) == OBJC_PR_dynamic)
{
- attrs[count].name = "D";
- attrs[count].value = "";
- count++;
+ attrs[attrcount].name = "D";
+ attrs[attrcount].value = "";
+ attrs[attrcount].length = 0;
+ stringslen += 3;
+ attrcount++;
}
if ((property->attributes & OBJC_PR_nonatomic) == OBJC_PR_nonatomic)
{
- attrs[count].name = "N";
- attrs[count].value = "";
- count++;
+ attrs[attrcount].name = "N";
+ attrs[attrcount].value = "";
+ attrs[attrcount].length = 0;
+ stringslen += 3;
+ attrcount++;
}
- if ((property->attributes & OBJC_PR_getter) == OBJC_PR_getter)
+ if (property->getter_name != NULL)
{
- attrs[count].name = "G";
- attrs[count].value = property->getter_name;
- count++;
+ attrs[attrcount].name = "G";
+ attrs[attrcount].value = property->getter_name;
+ attrs[attrcount].length = strlen(property->getter_name);
+ stringslen += attrs[attrcount].length + 3;
+ attrcount++;
}
- if ((property->attributes & OBJC_PR_setter) == OBJC_PR_setter)
+ if (property->setter_name != NULL)
{
- attrs[count].name = "S";
- attrs[count].value = property->setter_name;
- count++;
+ attrs[attrcount].name = "S";
+ attrs[attrcount].value = property->setter_name;
+ attrs[attrcount].length = strlen(property->setter_name);
+ stringslen += attrs[attrcount].length + 3;
+ attrcount++;
}
if (property->ivar_name != NULL)
{
- attrs[count].name = "V";
- attrs[count].value = property->ivar_name;
- count++;
+ attrs[attrcount].name = "V";
+ attrs[attrcount].value = property->ivar_name;
+ attrs[attrcount].length = strlen(property->ivar_name);
+ stringslen += attrs[attrcount].length + 3;
+ attrcount++;
}
- objc_property_attribute_t *propAttrs = calloc(sizeof(objc_property_attribute_t), count);
- memcpy(propAttrs, attrs, count * sizeof(objc_property_attribute_t));
+ if (attrcount == 0) { if (outCount) *outCount = 0; return NULL; }
+
+ objc_property_attribute_t *propAttrs = calloc(1, (attrcount+1) * sizeof(objc_property_attribute_t) + stringslen);
+ objc_property_attribute_t *ra = propAttrs;
+ char *rs = (char *)(ra+attrcount+1);
+ for (size_t a = 0; a < attrcount; a++)
+ {
+ ra->name = rs;
+ memcpy(rs, attrs[a].name, 2);
+ rs += 2;
+ ra->value = rs;
+ memcpy(rs, attrs[a].value, attrs[a].length + 1);
+ rs += attrs[a].length + 1;
+ ra ++;
+ }
if (NULL != outCount)
{
- *outCount = count;
+ *outCount = attrcount;
}
return propAttrs;
}
@@ -570,21 +601,18 @@ BOOL initPropertyFromAttributesList(struct objc_property *p,
{
s = stpcpy(s, "R,");
}
- else
+ if ((p->attributes & OBJC_PR_retain) == OBJC_PR_retain
+ || (p->attributes & OBJC_PR_strong) == OBJC_PR_strong)
{
- if ((p->attributes & OBJC_PR_retain) == OBJC_PR_retain
- || (p->attributes & OBJC_PR_strong) == OBJC_PR_strong)
- {
- s = stpcpy(s, "&,");
- }
- else if ((p->attributes & OBJC_PR_copy) == OBJC_PR_copy)
- {
- s = stpcpy(s, "C,");
- }
- else if ((p->attributes & OBJC_PR_weak) == OBJC_PR_weak)
- {
- s = stpcpy(s, "W,");
- }
+ s = stpcpy(s, "&,");
+ }
+ if ((p->attributes & OBJC_PR_copy) == OBJC_PR_copy)
+ {
+ s = stpcpy(s, "C,");
+ }
+ if ((p->attributes & OBJC_PR_weak) == OBJC_PR_weak)
+ {
+ s = stpcpy(s, "W,");
}
if ((p->attributes & OBJC_PR_dynamic) == OBJC_PR_dynamic)
{
_______________________________________________
Gnustep-dev mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/gnustep-dev