esx: Simplify goto usage

Eliminate almost all backward jumps by replacing this common pattern:

int
some_random_function(void)
{
    int result = 0;
    ...

  cleanup:
    <unconditional cleanup code>
    return result;

  failure:
    <cleanup code in case of an error>
    result = -1;
    goto cleanup
}

with this simpler pattern:

int
some_random_function(void)
{
    int result = -1;
    ...
    result = 0;

  cleanup:
    if (result < 0) {
        <cleanup code in case of an error>
    }

    <unconditional cleanup code>
    return result;
}

Add a bool success variable in functions that don't have a int result
that can be used for the new pattern.

Also remove some unnecessary memsets in error paths.
This commit is contained in:
Matthias Bolte 2010-05-19 22:59:32 +02:00
parent 8b0cd87696
commit 041aac8648
7 changed files with 813 additions and 978 deletions

File diff suppressed because it is too large Load Diff

View File

@ -467,10 +467,6 @@ esxStoragePoolGetInfo(virStoragePoolPtr pool, virStoragePoolInfoPtr info)
result = 0; result = 0;
cleanup: cleanup:
if (result < 0) {
memset(info, 0, sizeof (*info));
}
esxVI_String_Free(&propertyNameList); esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&datastore); esxVI_ObjectContent_Free(&datastore);

View File

@ -43,7 +43,7 @@ int
esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter, esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter,
int *noVerify, int *autoAnswer) int *noVerify, int *autoAnswer)
{ {
int result = 0; int result = -1;
int i; int i;
struct qparam_set *queryParamSet = NULL; struct qparam_set *queryParamSet = NULL;
struct qparam *queryParam = NULL; struct qparam *queryParam = NULL;
@ -71,7 +71,7 @@ esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter,
#endif #endif
if (queryParamSet == NULL) { if (queryParamSet == NULL) {
goto failure; return -1;
} }
for (i = 0; i < queryParamSet->n; i++) { for (i = 0; i < queryParamSet->n; i++) {
@ -86,14 +86,14 @@ esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter,
if (*transport == NULL) { if (*transport == NULL) {
virReportOOMError(); virReportOOMError();
goto failure; goto cleanup;
} }
if (STRNEQ(*transport, "http") && STRNEQ(*transport, "https")) { if (STRNEQ(*transport, "http") && STRNEQ(*transport, "https")) {
ESX_ERROR(VIR_ERR_INVALID_ARG, ESX_ERROR(VIR_ERR_INVALID_ARG,
_("Query parameter 'transport' has unexpected value " _("Query parameter 'transport' has unexpected value "
"'%s' (should be http|https)"), *transport); "'%s' (should be http|https)"), *transport);
goto failure; goto cleanup;
} }
} else if (STRCASEEQ(queryParam->name, "vcenter")) { } else if (STRCASEEQ(queryParam->name, "vcenter")) {
if (vCenter == NULL) { if (vCenter == NULL) {
@ -104,7 +104,7 @@ esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter,
if (*vCenter == NULL) { if (*vCenter == NULL) {
virReportOOMError(); virReportOOMError();
goto failure; goto cleanup;
} }
} else if (STRCASEEQ(queryParam->name, "no_verify")) { } else if (STRCASEEQ(queryParam->name, "no_verify")) {
if (noVerify == NULL) { if (noVerify == NULL) {
@ -116,7 +116,7 @@ esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter,
ESX_ERROR(VIR_ERR_INVALID_ARG, ESX_ERROR(VIR_ERR_INVALID_ARG,
_("Query parameter 'no_verify' has unexpected value " _("Query parameter 'no_verify' has unexpected value "
"'%s' (should be 0 or 1)"), queryParam->value); "'%s' (should be 0 or 1)"), queryParam->value);
goto failure; goto cleanup;
} }
} else if (STRCASEEQ(queryParam->name, "auto_answer")) { } else if (STRCASEEQ(queryParam->name, "auto_answer")) {
if (autoAnswer == NULL) { if (autoAnswer == NULL) {
@ -128,7 +128,7 @@ esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter,
ESX_ERROR(VIR_ERR_INVALID_ARG, ESX_ERROR(VIR_ERR_INVALID_ARG,
_("Query parameter 'auto_answer' has unexpected " _("Query parameter 'auto_answer' has unexpected "
"value '%s' (should be 0 or 1)"), queryParam->value); "value '%s' (should be 0 or 1)"), queryParam->value);
goto failure; goto cleanup;
} }
} else { } else {
VIR_WARN("Ignoring unexpected query parameter '%s'", VIR_WARN("Ignoring unexpected query parameter '%s'",
@ -141,29 +141,28 @@ esxUtil_ParseQuery(xmlURIPtr uri, char **transport, char **vCenter,
if (*transport == NULL) { if (*transport == NULL) {
virReportOOMError(); virReportOOMError();
goto failure; goto cleanup;
} }
} }
result = 0;
cleanup: cleanup:
if (result < 0) {
if (transport != NULL) {
VIR_FREE(*transport);
}
if (vCenter != NULL) {
VIR_FREE(*vCenter);
}
}
if (queryParamSet != NULL) { if (queryParamSet != NULL) {
free_qparam_set(queryParamSet); free_qparam_set(queryParamSet);
} }
return result; return result;
failure:
if (transport != NULL) {
VIR_FREE(*transport);
}
if (vCenter != NULL) {
VIR_FREE(*vCenter);
}
result = -1;
goto cleanup;
} }
@ -196,7 +195,7 @@ esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
char **datastoreName, char **datastoreName,
char **directoryName, char **fileName) char **directoryName, char **fileName)
{ {
int result = 0; int result = -1;
char *copyOfDatastoreRelatedPath = NULL; char *copyOfDatastoreRelatedPath = NULL;
char *tmp = NULL; char *tmp = NULL;
char *saveptr = NULL; char *saveptr = NULL;
@ -213,7 +212,7 @@ esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
if (esxVI_String_DeepCopyValue(&copyOfDatastoreRelatedPath, if (esxVI_String_DeepCopyValue(&copyOfDatastoreRelatedPath,
datastoreRelatedPath) < 0) { datastoreRelatedPath) < 0) {
goto failure; goto cleanup;
} }
/* Expected format: '[<datastore>] <path>' */ /* Expected format: '[<datastore>] <path>' */
@ -223,12 +222,12 @@ esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Datastore related path '%s' doesn't have expected format " _("Datastore related path '%s' doesn't have expected format "
"'[<datastore>] <path>'"), datastoreRelatedPath); "'[<datastore>] <path>'"), datastoreRelatedPath);
goto failure; goto cleanup;
} }
if (esxVI_String_DeepCopyValue(datastoreName, if (esxVI_String_DeepCopyValue(datastoreName,
preliminaryDatastoreName) < 0) { preliminaryDatastoreName) < 0) {
goto failure; goto cleanup;
} }
directoryAndFileName += strspn(directoryAndFileName, " "); directoryAndFileName += strspn(directoryAndFileName, " ");
@ -243,33 +242,32 @@ esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Datastore related path '%s' doesn't reference a file"), _("Datastore related path '%s' doesn't reference a file"),
datastoreRelatedPath); datastoreRelatedPath);
goto failure; goto cleanup;
} }
if (esxVI_String_DeepCopyValue(directoryName, if (esxVI_String_DeepCopyValue(directoryName,
directoryAndFileName) < 0 || directoryAndFileName) < 0 ||
esxVI_String_DeepCopyValue(fileName, separator) < 0) { esxVI_String_DeepCopyValue(fileName, separator) < 0) {
goto failure; goto cleanup;
} }
} else { } else {
if (esxVI_String_DeepCopyValue(fileName, directoryAndFileName) < 0) { if (esxVI_String_DeepCopyValue(fileName, directoryAndFileName) < 0) {
goto failure; goto cleanup;
} }
} }
result = 0;
cleanup: cleanup:
if (result < 0) {
VIR_FREE(*datastoreName);
VIR_FREE(*directoryName);
VIR_FREE(*fileName);
}
VIR_FREE(copyOfDatastoreRelatedPath); VIR_FREE(copyOfDatastoreRelatedPath);
return result; return result;
failure:
VIR_FREE(*datastoreName);
VIR_FREE(*directoryName);
VIR_FREE(*fileName);
result = -1;
goto cleanup;
} }
@ -282,7 +280,7 @@ esxUtil_ResolveHostname(const char *hostname,
struct addrinfo *result = NULL; struct addrinfo *result = NULL;
int errcode; int errcode;
memset(&hints, 0, sizeof(struct addrinfo)); memset(&hints, 0, sizeof (hints));
hints.ai_flags = AI_ADDRCONFIG; hints.ai_flags = AI_ADDRCONFIG;
hints.ai_family = AF_INET; hints.ai_family = AF_INET;

File diff suppressed because it is too large Load Diff

View File

@ -74,14 +74,14 @@
#define ESX_VI__METHOD__DESERIALIZE_OUTPUT__RequiredItem(_type) \ #define ESX_VI__METHOD__DESERIALIZE_OUTPUT__RequiredItem(_type) \
if (esxVI_##_type##_Deserialize(response->node, output) < 0) { \ if (esxVI_##_type##_Deserialize(response->node, output) < 0) { \
goto failure; \ goto cleanup; \
} }
#define ESX_VI__METHOD__DESERIALIZE_OUTPUT__RequiredList(_type) \ #define ESX_VI__METHOD__DESERIALIZE_OUTPUT__RequiredList(_type) \
if (esxVI_##_type##_DeserializeList(response->node, output) < 0) { \ if (esxVI_##_type##_DeserializeList(response->node, output) < 0) { \
goto failure; \ goto cleanup; \
} }
@ -89,7 +89,7 @@
#define ESX_VI__METHOD__DESERIALIZE_OUTPUT__OptionalItem(_type) \ #define ESX_VI__METHOD__DESERIALIZE_OUTPUT__OptionalItem(_type) \
if (response->node != NULL && \ if (response->node != NULL && \
esxVI_##_type##_Deserialize(response->node, output) < 0) { \ esxVI_##_type##_Deserialize(response->node, output) < 0) { \
goto failure; \ goto cleanup; \
} }
@ -97,7 +97,7 @@
#define ESX_VI__METHOD__DESERIALIZE_OUTPUT__OptionalList(_type) \ #define ESX_VI__METHOD__DESERIALIZE_OUTPUT__OptionalList(_type) \
if (response->node != NULL && \ if (response->node != NULL && \
esxVI_##_type##_DeserializeList(response->node, output) < 0) { \ esxVI_##_type##_DeserializeList(response->node, output) < 0) { \
goto failure; \ goto cleanup; \
} }
@ -107,7 +107,7 @@
int \ int \
esxVI_##_name _parameters \ esxVI_##_name _parameters \
{ \ { \
int result = 0; \ int result = -1; \
const char *methodName = #_name; \ const char *methodName = #_name; \
virBuffer buffer = VIR_BUFFER_INITIALIZER; \ virBuffer buffer = VIR_BUFFER_INITIALIZER; \
char *request = NULL; \ char *request = NULL; \
@ -129,30 +129,29 @@
\ \
if (virBufferError(&buffer)) { \ if (virBufferError(&buffer)) { \
virReportOOMError(); \ virReportOOMError(); \
goto failure; \ goto cleanup; \
} \ } \
\ \
request = virBufferContentAndReset(&buffer); \ request = virBufferContentAndReset(&buffer); \
\ \
if (esxVI_Context_Execute(ctx, methodName, request, &response, \ if (esxVI_Context_Execute(ctx, methodName, request, &response, \
esxVI_Occurrence_##_occurrence) < 0) { \ esxVI_Occurrence_##_occurrence) < 0) { \
goto failure; \ goto cleanup; \
} \ } \
\ \
ESX_VI__METHOD__DESERIALIZE_OUTPUT__##_occurrence(_output_type) \ ESX_VI__METHOD__DESERIALIZE_OUTPUT__##_occurrence(_output_type) \
\ \
result = 0; \
\
cleanup: \ cleanup: \
if (result < 0) { \
virBufferFreeAndReset(&buffer); \
} \
\
VIR_FREE(request); \ VIR_FREE(request); \
esxVI_Response_Free(&response); \ esxVI_Response_Free(&response); \
\ \
return result; \ return result; \
\
failure: \
virBufferFreeAndReset(&buffer); \
\
result = -1; \
\
goto cleanup; \
} }
@ -216,21 +215,21 @@
#define ESX_VI__METHOD__PARAMETER__SERIALIZE(_type, _name) \ #define ESX_VI__METHOD__PARAMETER__SERIALIZE(_type, _name) \
if (esxVI_##_type##_Serialize(_name, #_name, &buffer) < 0) { \ if (esxVI_##_type##_Serialize(_name, #_name, &buffer) < 0) { \
goto failure; \ goto cleanup; \
} }
#define ESX_VI__METHOD__PARAMETER__SERIALIZE_LIST(_type, _name) \ #define ESX_VI__METHOD__PARAMETER__SERIALIZE_LIST(_type, _name) \
if (esxVI_##_type##_SerializeList(_name, #_name, &buffer) < 0) { \ if (esxVI_##_type##_SerializeList(_name, #_name, &buffer) < 0) { \
goto failure; \ goto cleanup; \
} }
#define ESX_VI__METHOD__PARAMETER__SERIALIZE_VALUE(_type, _name) \ #define ESX_VI__METHOD__PARAMETER__SERIALIZE_VALUE(_type, _name) \
if (esxVI_##_type##_SerializeValue(_name, #_name, &buffer) < 0) { \ if (esxVI_##_type##_SerializeValue(_name, #_name, &buffer) < 0) { \
goto failure; \ goto cleanup; \
} }
@ -243,7 +242,7 @@ int
esxVI_RetrieveServiceContent(esxVI_Context *ctx, esxVI_RetrieveServiceContent(esxVI_Context *ctx,
esxVI_ServiceContent **serviceContent) esxVI_ServiceContent **serviceContent)
{ {
int result = 0; int result = -1;
const char *request = ESX_VI__SOAP__REQUEST_HEADER const char *request = ESX_VI__SOAP__REQUEST_HEADER
"<RetrieveServiceContent xmlns=\"urn:vim25\">" "<RetrieveServiceContent xmlns=\"urn:vim25\">"
"<_this xmlns=\"urn:vim25\" " "<_this xmlns=\"urn:vim25\" "
@ -263,18 +262,15 @@ esxVI_RetrieveServiceContent(esxVI_Context *ctx,
if (esxVI_Context_Execute(ctx, "RetrieveServiceContent", request, if (esxVI_Context_Execute(ctx, "RetrieveServiceContent", request,
&response, esxVI_Occurrence_RequiredItem) < 0 || &response, esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_ServiceContent_Deserialize(response->node, serviceContent) < 0) { esxVI_ServiceContent_Deserialize(response->node, serviceContent) < 0) {
goto failure; goto cleanup;
} }
result = 0;
cleanup: cleanup:
esxVI_Response_Free(&response); esxVI_Response_Free(&response);
return result; return result;
failure:
result = -1;
goto cleanup;
} }

View File

@ -297,7 +297,7 @@
int \ int \
esxVI_##_type##_Deserialize(xmlNodePtr node, esxVI_##_type **number) \ esxVI_##_type##_Deserialize(xmlNodePtr node, esxVI_##_type **number) \
{ \ { \
int result = 0; \ int result = -1; \
char *string; \ char *string; \
long long value; \ long long value; \
\ \
@ -317,35 +317,34 @@
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, \ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, \
"XML node doesn't contain text, expecting an " \ "XML node doesn't contain text, expecting an " \
_xsdType" value"); \ _xsdType" value"); \
goto failure; \ goto cleanup; \
} \ } \
\ \
if (virStrToLong_ll(string, NULL, 10, &value) < 0) { \ if (virStrToLong_ll(string, NULL, 10, &value) < 0) { \
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, \ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, \
"Unknown value '%s' for "_xsdType, string); \ "Unknown value '%s' for "_xsdType, string); \
goto failure; \ goto cleanup; \
} \ } \
\ \
if (value < (_min) || value > (_max)) { \ if (value < (_min) || value > (_max)) { \
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, \ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, \
"Value '%s' is not representable as "_xsdType, \ "Value '%s' is not representable as "_xsdType, \
(const char *)string); \ (const char *)string); \
goto failure; \ goto cleanup; \
} \ } \
\ \
(*number)->value = value; \ (*number)->value = value; \
\ \
result = 0; \
\
cleanup: \ cleanup: \
if (result < 0) { \
esxVI_##_type##_Free(number); \
} \
\
VIR_FREE(string); \ VIR_FREE(string); \
\ \
return result; \ return result; \
\
failure: \
esxVI_##_type##_Free(number); \
\
result = -1; \
\
goto cleanup; \
} }
@ -930,7 +929,7 @@ esxVI_String_AppendValueToList(esxVI_String **stringList, const char *value)
esxVI_String *string = NULL; esxVI_String *string = NULL;
if (esxVI_String_Alloc(&string) < 0) { if (esxVI_String_Alloc(&string) < 0) {
goto failure; return -1;
} }
string->value = strdup(value); string->value = strdup(value);

File diff suppressed because it is too large Load Diff