cJSON_Duplicate: goto fail error handling

Simplify error handling using goto fail and improve some names.
This commit is contained in:
Max Bruckner 2017-02-07 00:24:21 +01:00
parent 021b174ee1
commit cc514583cc
1 changed files with 25 additions and 19 deletions

44
cJSON.c
View File

@ -2316,20 +2316,20 @@ cJSON *cJSON_CreateStringArray(const char **strings, int count)
cJSON *cJSON_Duplicate(const cJSON *item, cjbool recurse) cJSON *cJSON_Duplicate(const cJSON *item, cjbool recurse)
{ {
cJSON *newitem = NULL; cJSON *newitem = NULL;
cJSON *cptr = NULL; cJSON *child = NULL;
cJSON *nptr = NULL; cJSON *next = NULL;
cJSON *newchild = NULL; cJSON *newchild = NULL;
/* Bail on bad ptr */ /* Bail on bad ptr */
if (!item) if (!item)
{ {
return NULL; goto fail;
} }
/* Create new item */ /* Create new item */
newitem = cJSON_New_Item(); newitem = cJSON_New_Item();
if (!newitem) if (!newitem)
{ {
return NULL; goto fail;
} }
/* Copy over all vars */ /* Copy over all vars */
newitem->type = item->type & (~cJSON_IsReference); newitem->type = item->type & (~cJSON_IsReference);
@ -2340,8 +2340,7 @@ cJSON *cJSON_Duplicate(const cJSON *item, cjbool recurse)
newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring); newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring);
if (!newitem->valuestring) if (!newitem->valuestring)
{ {
cJSON_Delete(newitem); goto fail;
return NULL;
} }
} }
if (item->string) if (item->string)
@ -2349,8 +2348,7 @@ cJSON *cJSON_Duplicate(const cJSON *item, cjbool recurse)
newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string); newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string);
if (!newitem->string) if (!newitem->string)
{ {
cJSON_Delete(newitem); goto fail;
return NULL;
} }
} }
/* If non-recursive, then we're done! */ /* If non-recursive, then we're done! */
@ -2359,31 +2357,39 @@ cJSON *cJSON_Duplicate(const cJSON *item, cjbool recurse)
return newitem; return newitem;
} }
/* Walk the ->next chain for the child. */ /* Walk the ->next chain for the child. */
cptr = item->child; child = item->child;
while (cptr) while (child != NULL)
{ {
newchild = cJSON_Duplicate(cptr, 1); /* Duplicate (with recurse) each item in the ->next chain */ newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */
if (!newchild) if (!newchild)
{ {
cJSON_Delete(newitem); goto fail;
return NULL;
} }
if (nptr) if (next != NULL)
{ {
/* If newitem->child already set, then crosswire ->prev and ->next and move on */ /* If newitem->child already set, then crosswire ->prev and ->next and move on */
nptr->next = newchild; next->next = newchild;
newchild->prev = nptr; newchild->prev = next;
nptr = newchild; next = newchild;
} }
else else
{ {
/* Set newitem->child and move to it */ /* Set newitem->child and move to it */
newitem->child = newchild; nptr = newchild; newitem->child = newchild;
next = newchild;
} }
cptr = cptr->next; child = child->next;
} }
return newitem; return newitem;
fail:
if (newitem != NULL)
{
cJSON_Delete(newitem);
}
return NULL;
} }
void cJSON_Minify(char *json) void cJSON_Minify(char *json)