Repository: jerryscript-project/jerryscript
File: jerry-ext/handler/handler-register.c (C)

Code before:
} /* jerryx_handler_register_global */

/**
 * Set multiple properties on a target object.
 *
 * The properties are an array of (name, property value) pairs and
 * this list must end with a (NULL, 0) entry.
 *
 * Notes:
 *  - Each property value in the input array is released after a successful property registration.
 *  - The property name must be a zero terminated UTF-8 string.
 *  - There should be no '\0' (NULL) character in the name excluding the string terminator.
 *  - The method `jerryx_release_property_entry` must be called if there is any failed registration
 *    to release the values in the entries array.
 *
 * @return `jerryx_register_result` struct - if everything is ok with the (undefined, property entry count) values.
 *         In case of error the (error object, registered property count) pair.
 */
jerryx_register_result
jerryx_set_properties (const jerry_value_t target_object, /**< target object */
                       const jerryx_property_entry entries[]) /**< array of method entries */
{
#define JERRYX_SET_PROPERTIES_RESULT(VALUE, IDX) ((jerryx_register_result) { VALUE, IDX })
  uint32_t idx = 0;
  /* cppcheck-suppress pointerAdditionResultNotNull */
  for (; ((entries + idx) != NULL) && (entries[idx].name != NULL); idx++)
  {
    const jerryx_property_entry *entry = &entries[idx];

    jerry_value_t prop_name = jerry_create_string_from_utf8 ((const jerry_char_t *) entry->name);
    jerry_value_t result = jerry_set_property (target_object, prop_name, entry->value);

    jerry_release_value (prop_name);

    // By API definition:
    // The jerry_set_property returns TRUE if there is no problem
    // and error object if there is any problem.
    // Thus there is no need to check if the boolean value is false or not.
    if (!jerry_value_is_boolean (result))
    {
      return JERRYX_SET_PROPERTIES_RESULT (result, idx);
    }

    jerry_release_value (entry->value);
    jerry_release_value (result);
  }

  return JERRYX_SET_PROPERTIES_RESULT (jerry_create_undefined (), idx);
#undef JERRYX_SET_PROPERTIES_RESULT
} /* jerryx_set_properties */


Review comment (suggestion):
This is a strange one. When can the first part of the predicate (`(entries + idx) != NULL`) turn out as false? I.e., when can `entries + idx` be `NULL`? Doesn't it only happen if `entries` was `NULL`, and then it doesn't even allow the loop to execute? But in that case `if (entries != NULL) { for (; entries[idx].name != NULL; idx++) {...} }` might be more intuitive. And this will not execute the first part of the predicate on every loop iteration either.

Code after:
} /* jerryx_handler_register_global */

/**
 * Set multiple properties on a target object.
 *
 * The properties are an array of (name, property value) pairs and
 * this list must end with a (NULL, 0) entry.
 *
 * Notes:
 *  - Each property value in the input array is released after a successful property registration.
 *  - The property name must be a zero terminated UTF-8 string.
 *  - There should be no '\0' (NULL) character in the name excluding the string terminator.
 *  - The method `jerryx_release_property_entry` must be called if there is any failed registration
 *    to release the values in the entries array.
 *
 * @return `jerryx_register_result` struct - if everything is ok with the (undefined, property entry count) values.
 *         In case of error the (error object, registered property count) pair.
 */
jerryx_register_result
jerryx_set_properties (const jerry_value_t target_object, /**< target object */
                       const jerryx_property_entry entries[]) /**< array of method entries */
{
#define JERRYX_SET_PROPERTIES_RESULT(VALUE, IDX) ((jerryx_register_result) { VALUE, IDX })
  uint32_t idx = 0;

  if (entries == NULL)
  {
    return JERRYX_SET_PROPERTIES_RESULT (jerry_create_undefined (), 0);
  }

  for (; (entries[idx].name != NULL); idx++)
  {
    const jerryx_property_entry *entry = &entries[idx];

    jerry_value_t prop_name = jerry_create_string_from_utf8 ((const jerry_char_t *) entry->name);
    jerry_value_t result = jerry_set_property (target_object, prop_name, entry->value);

    jerry_release_value (prop_name);

    // By API definition:
    // The jerry_set_property returns TRUE if there is no problem
    // and error object if there is any problem.
    // Thus there is no need to check if the boolean value is false or not.
    if (!jerry_value_is_boolean (result))
    {
      return JERRYX_SET_PROPERTIES_RESULT (result, idx);
    }

    jerry_release_value (entry->value);
    jerry_release_value (result);
  }