LCOV - code coverage report
Current view: top level - gi - enumeration.cpp (source / functions) Coverage Total Hit
Test: gjs-1.87.90 Code Coverage Lines: 82.1 % 39 32
Test Date: 2026-04-07 00:59:09 Functions: 100.0 % 4 4
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 65.0 % 20 13

             Branch data     Line data    Source code
       1                 :             : /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
       2                 :             : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
       3                 :             : // SPDX-FileCopyrightText: 2008 litl, LLC
       4                 :             : 
       5                 :             : #include <config.h>
       6                 :             : 
       7                 :             : #include <stddef.h>  // for size_t
       8                 :             : #include <inttypes.h>
       9                 :             : 
      10                 :             : #include <algorithm>
      11                 :             : 
      12                 :             : #include <glib-object.h>
      13                 :             : #include <glib.h>
      14                 :             : 
      15                 :             : #include <js/PropertyAndElement.h>
      16                 :             : #include <js/RootingAPI.h>
      17                 :             : #include <js/TypeDecls.h>
      18                 :             : #include <jsapi.h>  // for JS_NewPlainObject
      19                 :             : 
      20                 :             : #include "gi/cwrapper.h"
      21                 :             : #include "gi/enumeration.h"
      22                 :             : #include "gi/info.h"
      23                 :             : #include "gi/wrapperutils.h"
      24                 :             : #include "gjs/auto.h"
      25                 :             : #include "gjs/jsapi-util.h"
      26                 :             : #include "gjs/macros.h"
      27                 :             : #include "util/log.h"
      28                 :             : 
      29                 :             : GJS_JSAPI_RETURN_CONVENTION
      30                 :        2192 : static bool gjs_define_enum_value(JSContext* cx, JS::HandleObject in_object,
      31                 :             :                                   const GI::ValueInfo& info) {
      32                 :        2192 :     const char* value_name = info.name();
      33                 :        2192 :     int64_t value_val = info.value();
      34                 :             : 
      35                 :             :     /* g-i converts enum members such as GDK_GRAVITY_SOUTH_WEST to
      36                 :             :      * Gdk.GravityType.south-west (where 'south-west' is value_name) Convert
      37                 :             :      * back to all SOUTH_WEST.
      38                 :             :      */
      39                 :        2192 :     Gjs::AutoChar fixed_name{g_ascii_strup(value_name, -1)};
      40         [ +  + ]:       23922 :     for (size_t i = 0; fixed_name[i]; ++i) {
      41                 :       21730 :         char c = fixed_name[i];
      42   [ +  +  +  + ]:       21730 :         if (!(g_ascii_isupper(c) || g_ascii_isdigit(c)))
      43                 :        1524 :             fixed_name[i] = '_';
      44                 :             :     }
      45                 :             : 
      46                 :        2192 :     gjs_debug(GJS_DEBUG_GENUM,
      47                 :             :               "Defining enum value %s (fixed from %s) %" PRId64,
      48                 :             :               fixed_name.get(), value_name, value_val);
      49                 :             : 
      50         [ -  + ]:        2192 :     if (!JS_DefineProperty(cx, in_object, fixed_name,
      51                 :             :                            static_cast<double>(value_val),
      52                 :             :                            GJS_MODULE_PROP_FLAGS)) {
      53                 :           0 :         gjs_throw(cx,
      54                 :             :                   "Unable to define enumeration value %s %" PRId64
      55                 :             :                   " (no memory most likely)",
      56                 :             :                   fixed_name.get(), value_val);
      57                 :           0 :         return false;
      58                 :             :     }
      59                 :             : 
      60                 :        2192 :     return true;
      61                 :        2192 : }
      62                 :             : 
      63                 :         239 : bool gjs_define_enum_values(JSContext* cx, JS::HandleObject in_object,
      64                 :             :                             const GI::EnumInfo& info) {
      65                 :             :     /* Fill in enum values first, so we don't define the enum itself until we're
      66                 :             :      * sure we can finish successfully.
      67                 :             :      */
      68                 :         239 :     auto iter = info.values();
      69                 :         239 :     return std::all_of(iter.begin(), iter.end(),
      70                 :        2192 :                        [cx, in_object](const GI::AutoValueInfo& value_info) {
      71                 :        2192 :                            return gjs_define_enum_value(cx, in_object,
      72                 :        4384 :                                                         value_info);
      73                 :         239 :                        });
      74                 :             : }
      75                 :             : 
      76                 :         225 : bool gjs_define_enumeration(JSContext* cx, JS::HandleObject in_object,
      77                 :             :                             const GI::EnumInfo& info) {
      78                 :             :     /* An enumeration is simply an object containing integer attributes for each
      79                 :             :      * enum value. It does not have a special JSClass.
      80                 :             :      *
      81                 :             :      * We could make this more typesafe and also print enum values as strings if
      82                 :             :      * we created a class for each enum and made the enum values instances of
      83                 :             :      * that class. However, it would have a lot more overhead and just be more
      84                 :             :      * complicated in general. I think this is fine.
      85                 :             :      */
      86                 :             : 
      87                 :         225 :     const char* enum_name = info.name();
      88                 :             : 
      89                 :         225 :     JS::RootedObject enum_obj{cx, JS_NewPlainObject(cx)};
      90         [ -  + ]:         225 :     if (!enum_obj) {
      91                 :           0 :         gjs_throw(cx, "Could not create enumeration %s.%s", info.ns(),
      92                 :             :                   enum_name);
      93                 :           0 :         return false;
      94                 :             :     }
      95                 :             : 
      96                 :         225 :     GType gtype = info.gtype();
      97                 :             : 
      98                 :         225 :     if (!gjs_define_enum_values(cx, enum_obj, info) ||
      99   [ +  -  +  - ]:         450 :         !gjs_define_static_methods(cx, enum_obj, gtype, info) ||
     100   [ -  +  -  + ]:         450 :         !gjs_wrapper_define_gtype_prop(cx, enum_obj, gtype))
     101                 :           0 :         return false;
     102                 :             : 
     103                 :         225 :     gjs_debug(GJS_DEBUG_GENUM, "Defining %s.%s as %p", info.ns(), enum_name,
     104                 :         225 :               enum_obj.get());
     105                 :             : 
     106         [ -  + ]:         225 :     if (!JS_DefineProperty(cx, in_object, enum_name, enum_obj,
     107                 :             :                            GJS_MODULE_PROP_FLAGS)) {
     108                 :           0 :         gjs_throw(
     109                 :             :             cx,
     110                 :             :             "Unable to define enumeration property (no memory most likely)");
     111                 :           0 :         return false;
     112                 :             :     }
     113                 :             : 
     114                 :         225 :     return true;
     115                 :         225 : }
        

Generated by: LCOV version 2.0-1