---
 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
Gnustep-dev@gnu.org
https://lists.gnu.org/mailman/listinfo/gnustep-dev

Reply via email to