LCOV - code coverage report
Current view: top level - modules/core/overrides - GLib.js (source / functions) Hit Total Coverage
Test: gjs- Code Coverage Lines: 281 317 88.6 %
Date: 2023-09-17 02:39:54 Functions: 36 45 80.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 165 202 81.7 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
       2                 :            : // SPDX-FileCopyrightText: 2011 Giovanni Campagna
       3                 :            : 
       4                 :         47 : const ByteArray = imports._byteArrayNative;
       5                 :         47 : const {setMainLoopHook} = imports._promiseNative;
       6                 :            : 
       7                 :         47 : let GLib;
       8                 :            : 
       9                 :         47 : const SIMPLE_TYPES = ['b', 'y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd', 's', 'o', 'g'];
      10                 :            : 
      11                 :        359 : function _readSingleType(signature, forceSimple) {
      12                 :        359 :     let char = signature.shift();
      13                 :        359 :     let isSimple = false;
      14                 :            : 
      15         [ +  + ]:        359 :     if (!SIMPLE_TYPES.includes(char)) {
      16         [ +  - ]:        218 :         if (forceSimple)
      17                 :          0 :             throw new TypeError('Invalid GVariant signature (a simple type was expected)');
      18                 :            :     } else {
      19                 :        141 :         isSimple = true;
      20                 :            :     }
      21                 :            : 
      22 [ -  + ][ +  + ]:        359 :     if (char === 'm' || char === 'a')
      23                 :          2 :         return [char].concat(_readSingleType(signature, false));
      24         [ +  + ]:        357 :     if (char === '{') {
      25                 :        107 :         let key = _readSingleType(signature, true);
      26                 :        107 :         let val = _readSingleType(signature, false);
      27                 :        107 :         let close = signature.shift();
      28         [ +  - ]:        107 :         if (close !== '}')
      29                 :          0 :             throw new TypeError('Invalid GVariant signature for type DICT_ENTRY (expected "}"');
      30                 :        107 :         return [char].concat(key, val, close);
      31                 :            :     }
      32         [ +  + ]:        250 :     if (char === '(') {
      33                 :          2 :         let res = [char];
      34         [ -  + ]:          6 :         while (true) {
      35         [ +  - ]:          6 :             if (signature.length === 0)
      36                 :          0 :                 throw new TypeError('Invalid GVariant signature for type TUPLE (expected ")")');
      37                 :          6 :             let next = signature[0];
      38         [ +  + ]:          6 :             if (next === ')') {
      39                 :          2 :                 signature.shift();
      40                 :          2 :                 return res.concat(next);
      41                 :            :             }
      42                 :          4 :             let el = _readSingleType(signature);
      43                 :          4 :             res = res.concat(el);
      44                 :            :         }
      45                 :            :     }
      46                 :            : 
      47                 :            :     // Valid types are simple types, arrays, maybes, tuples, dictionary entries and variants
      48 [ +  + ][ +  - ]:        248 :     if (!isSimple && char !== 'v')
      49                 :          0 :         throw new TypeError(`Invalid GVariant signature (${char} is not a valid type)`);
      50                 :            : 
      51                 :        248 :     return [char];
      52                 :        359 : }
      53                 :            : 
      54                 :       1200 : function _packVariant(signature, value) {
      55         [ +  - ]:       1200 :     if (signature.length === 0)
      56                 :          0 :         throw new TypeError('GVariant signature cannot be empty');
      57                 :            : 
      58                 :       1200 :     let char = signature.shift();
      59 [ +  + ][ +  + ]:       1200 :     switch (char) {
         [ -  + ][ -  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  - ]
      60                 :            :     case 'b':
      61                 :          3 :         return GLib.Variant.new_boolean(value);
      62                 :            :     case 'y':
      63                 :         12 :         return GLib.Variant.new_byte(value);
      64                 :            :     case 'n':
      65                 :          0 :         return GLib.Variant.new_int16(value);
      66                 :            :     case 'q':
      67                 :          0 :         return GLib.Variant.new_uint16(value);
      68                 :            :     case 'i':
      69                 :         35 :         return GLib.Variant.new_int32(value);
      70                 :            :     case 'u':
      71                 :          3 :         return GLib.Variant.new_uint32(value);
      72                 :            :     case 'x':
      73                 :          5 :         return GLib.Variant.new_int64(value);
      74                 :            :     case 't':
      75                 :          4 :         return GLib.Variant.new_uint64(value);
      76                 :            :     case 'h':
      77                 :         12 :         return GLib.Variant.new_handle(value);
      78                 :            :     case 'd':
      79                 :          7 :         return GLib.Variant.new_double(value);
      80                 :            :     case 's':
      81                 :        443 :         return GLib.Variant.new_string(value);
      82                 :            :     case 'o':
      83                 :          1 :         return GLib.Variant.new_object_path(value);
      84                 :            :     case 'g':
      85                 :          1 :         return GLib.Variant.new_signature(value);
      86                 :            :     case 'v':
      87                 :        217 :         return GLib.Variant.new_variant(value);
      88                 :            :     case 'm':
      89         [ +  + ]:          2 :         if (value !== null) {
      90                 :          1 :             return GLib.Variant.new_maybe(null, _packVariant(signature, value));
      91                 :            :         } else {
      92                 :          3 :             return GLib.Variant.new_maybe(new GLib.VariantType(
      93                 :          2 :                 _readSingleType(signature, false).join('')), null);
      94                 :            :         }
      95                 :        138 :     case 'a': {
      96                 :        138 :         let arrayType = _readSingleType(signature, false);
      97         [ +  + ]:        138 :         if (arrayType[0] === 's') {
      98                 :            :             // special case for array of strings
      99                 :         13 :             return GLib.Variant.new_strv(value);
     100                 :            :         }
     101         [ +  + ]:        125 :         if (arrayType[0] === 'y') {
     102                 :            :             // special case for array of bytes
     103         [ +  + ]:         13 :             if (typeof value === 'string') {
     104                 :          2 :                 value = ByteArray.fromString(value);
     105         [ -  + ]:          2 :                 if (value[value.length - 1] !== 0)
     106         [ +  + ]:          2 :                     value = Uint8Array.of(...value, 0);
     107                 :            :             }
     108                 :         13 :             const bytes = new GLib.Bytes(value);
     109                 :         26 :             return GLib.Variant.new_from_bytes(new GLib.VariantType('ay'),
     110                 :         13 :                 bytes, true);
     111                 :            :         }
     112                 :            : 
     113                 :        112 :         let arrayValue = [];
     114         [ +  + ]:        112 :         if (arrayType[0] === '{') {
     115                 :            :             // special case for dictionaries
     116         [ +  + ]:        317 :             for (let key in value) {
     117                 :        210 :                 let copy = [].concat(arrayType);
     118                 :        210 :                 let child = _packVariant(copy, [key, value[key]]);
     119                 :        210 :                 arrayValue.push(child);
     120                 :            :             }
     121                 :            :         } else {
     122         [ +  + ]:         15 :             for (let i = 0; i < value.length; i++) {
     123                 :         10 :                 let copy = [].concat(arrayType);
     124                 :         10 :                 let child = _packVariant(copy, value[i]);
     125                 :         10 :                 arrayValue.push(child);
     126                 :            :             }
     127                 :            :         }
     128                 :        112 :         return GLib.Variant.new_array(new GLib.VariantType(arrayType.join('')), arrayValue);
     129                 :            :     }
     130                 :            : 
     131                 :        107 :     case '(': {
     132                 :        107 :         let children = [];
     133         [ +  + ]:        219 :         for (let i = 0; i < value.length; i++) {
     134                 :        114 :             let next = signature[0];
     135         [ +  - ]:        114 :             if (next === ')')
     136                 :          0 :                 break;
     137                 :        114 :             children.push(_packVariant(signature, value[i]));
     138                 :            :         }
     139                 :            : 
     140         [ +  - ]:        105 :         if (signature[0] !== ')')
     141                 :          0 :             throw new TypeError('Invalid GVariant signature for type TUPLE (expected ")")');
     142                 :        105 :         signature.shift();
     143                 :        105 :         return GLib.Variant.new_tuple(children);
     144                 :            :     }
     145                 :        210 :     case '{': {
     146                 :        210 :         let key = _packVariant(signature, value[0]);
     147                 :        210 :         let child = _packVariant(signature, value[1]);
     148                 :            : 
     149         [ +  - ]:        210 :         if (signature[0] !== '}')
     150                 :          0 :             throw new TypeError('Invalid GVariant signature for type DICT_ENTRY (expected "}")');
     151                 :        210 :         signature.shift();
     152                 :            : 
     153                 :        210 :         return GLib.Variant.new_dict_entry(key, child);
     154                 :            :     }
     155                 :            :     default:
     156                 :          0 :         throw new TypeError(`Invalid GVariant signature (unexpected character ${char})`);
     157                 :            :     }
     158                 :       1196 : }
     159                 :            : 
     160         [ +  + ]:       1348 : function _unpackVariant(variant, deep, recursive = false) {
     161 [ +  + ][ +  + ]:       1348 :     switch (String.fromCharCode(variant.classify())) {
         [ -  + ][ -  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  - ]
     162                 :            :     case 'b':
     163                 :          3 :         return variant.get_boolean();
     164                 :            :     case 'y':
     165                 :         12 :         return variant.get_byte();
     166                 :            :     case 'n':
     167                 :          0 :         return variant.get_int16();
     168                 :            :     case 'q':
     169                 :          0 :         return variant.get_uint16();
     170                 :            :     case 'i':
     171                 :         36 :         return variant.get_int32();
     172                 :            :     case 'u':
     173                 :          2 :         return variant.get_uint32();
     174                 :            :     case 'x':
     175                 :          3 :         return variant.get_int64();
     176                 :            :     case 't':
     177                 :          2 :         return variant.get_uint64();
     178                 :            :     case 'h':
     179                 :          8 :         return variant.get_handle();
     180                 :            :     case 'd':
     181                 :          6 :         return variant.get_double();
     182                 :            :     case 'o':
     183                 :            :     case 'g':
     184                 :            :     case 's':
     185                 :            :         // g_variant_get_string has length as out argument
     186                 :        284 :         return variant.get_string()[0];
     187                 :        213 :     case 'v': {
     188                 :        213 :         const ret = variant.get_variant();
     189 [ +  + ][ +  + ]:        213 :         if (deep && recursive && ret instanceof GLib.Variant)
                 [ +  + ]
     190                 :        192 :             return _unpackVariant(ret, deep, recursive);
     191                 :         25 :         return ret;
     192                 :            :     }
     193                 :        185 :     case 'm': {
     194                 :        185 :         let val = variant.get_maybe();
     195 [ -  + ][ +  + ]:        185 :         if (deep && val)
     196                 :        184 :             return _unpackVariant(val, deep, recursive);
     197                 :            :         else
     198                 :          1 :             return val;
     199                 :            :     }
     200                 :            :     case 'a':
     201         [ +  + ]:        285 :         if (variant.is_of_type(new GLib.VariantType('a{?*}'))) {
     202                 :            :             // special case containers
     203                 :         75 :             let ret = { };
     204                 :         75 :             let nElements = variant.n_children();
     205         [ +  + ]:        286 :             for (let i = 0; i < nElements; i++) {
     206                 :            :                 // always unpack the dictionary entry, and always unpack
     207                 :            :                 // the key (or it cannot be added as a key)
     208                 :        422 :                 let val = _unpackVariant(variant.get_child_value(i), deep,
     209                 :        211 :                     recursive);
     210                 :        211 :                 let key;
     211         [ +  - ]:        211 :                 if (!deep)
     212                 :          0 :                     key = _unpackVariant(val[0], true);
     213                 :            :                 else
     214                 :        211 :                     key = val[0];
     215                 :        211 :                 ret[key] = val[1];
     216                 :            :             }
     217                 :         75 :             return ret;
     218                 :            :         }
     219         [ +  + ]:        216 :         if (variant.is_of_type(new GLib.VariantType('ay'))) {
     220                 :            :             // special case byte arrays
     221                 :        199 :             return variant.get_data_as_bytes().toArray();
     222                 :            :         }
     223                 :            : 
     224                 :            :         // fall through
     225                 :            :     case '(':
     226                 :        326 :     case '{': {
     227                 :        326 :         let ret = [];
     228                 :        326 :         let nElements = variant.n_children();
     229         [ +  + ]:        888 :         for (let i = 0; i < nElements; i++) {
     230                 :        561 :             let val = variant.get_child_value(i);
     231         [ -  + ]:        561 :             if (deep)
     232                 :        561 :                 ret.push(_unpackVariant(val, deep, recursive));
     233                 :            :             else
     234                 :          0 :                 ret.push(val);
     235                 :            :         }
     236                 :        327 :         return ret;
     237                 :            :     }
     238                 :            :     }
     239                 :            : 
     240                 :          0 :     throw new Error('Assertion failure: this code should not be reached');
     241                 :        804 : }
     242                 :            : 
     243                 :            : function _notIntrospectableError(funcName, replacement) {
     244                 :         30 :     return new Error(`${funcName} is not introspectable. Use ${replacement} instead.`);
     245                 :            : }
     246                 :            : 
     247                 :            : function _warnNotIntrospectable(funcName, replacement) {
     248                 :         28 :     logError(_notIntrospectableError(funcName, replacement));
     249                 :            : }
     250                 :            : 
     251                 :            : function _escapeCharacterSetChars(char) {
     252         [ +  + ]:         26 :     if ('-^]\\'.includes(char))
     253                 :          2 :         return `\\${char}`;
     254                 :         24 :     return char;
     255                 :            : }
     256                 :            : 
     257                 :         47 : function _init() {
     258                 :            :     // this is imports.gi.GLib
     259                 :            : 
     260                 :         47 :     GLib = this;
     261                 :            : 
     262                 :         96 :     GLib.MainLoop.prototype.runAsync = function (...args) {
     263                 :         49 :         return new Promise((resolve, reject) => {
     264                 :         49 :             setMainLoopHook(() => {
     265                 :         49 :                 try {
     266 [ +  - ][ #  # ]:         49 :                     resolve(this.run(...args));
     267                 :          0 :                 } catch (error) {
     268                 :          0 :                     reject(error);
     269                 :            :                 }
     270                 :            :             });
     271                 :            :         });
     272                 :            :     };
     273                 :            : 
     274                 :            :     // For convenience in property min or max values, since GLib.MAXINT64 and
     275                 :            :     // friends will log a warning when used
     276                 :         47 :     this.MAXINT64_BIGINT = 0x7fff_ffff_ffff_ffffn;
     277                 :         47 :     this.MININT64_BIGINT = -this.MAXINT64_BIGINT - 1n;
     278                 :         47 :     this.MAXUINT64_BIGINT = 0xffff_ffff_ffff_ffffn;
     279                 :            : 
     280                 :            :     // small HACK: we add a matches() method to standard Errors so that
     281                 :            :     // you can do "if (e.matches(Ns.FooError, Ns.FooError.SOME_CODE))"
     282                 :            :     // without checking instanceof
     283                 :         47 :     Error.prototype.matches = function () {
     284                 :          0 :         return false;
     285                 :            :     };
     286                 :            : 
     287                 :            :     // Guard against domains that aren't valid quarks and would lead
     288                 :            :     // to a crash
     289                 :         47 :     const quarkToString = this.quark_to_string;
     290                 :         47 :     const realNewLiteral = this.Error.new_literal;
     291                 :         47 :     this.Error.new_literal = function (domain, code, message) {
     292         [ +  + ]:          5 :         if (quarkToString(domain) === null)
     293                 :          1 :             throw new TypeError(`Error.new_literal: ${domain} is not a valid domain`);
     294                 :          4 :         return realNewLiteral(domain, code, message);
     295                 :            :     };
     296                 :            : 
     297                 :        492 :     this.Variant._new_internal = function (sig, value) {
     298                 :        445 :         let signature = Array.prototype.slice.call(sig);
     299                 :            : 
     300                 :        445 :         let variant = _packVariant(signature, value);
     301         [ +  - ]:        443 :         if (signature.length !== 0)
     302                 :          0 :             throw new TypeError('Invalid GVariant signature (more than one single complete type)');
     303                 :            : 
     304                 :        443 :         return variant;
     305                 :        443 :     };
     306                 :            : 
     307                 :            :     // Deprecate version of new GLib.Variant()
     308                 :         47 :     this.Variant.new = function (sig, value) {
     309                 :          4 :         return new GLib.Variant(sig, value);
     310                 :            :     };
     311                 :         47 :     this.Variant.prototype.unpack = function () {
     312                 :          4 :         return _unpackVariant(this, false);
     313                 :            :     };
     314                 :         47 :     this.Variant.prototype.deepUnpack = function () {
     315                 :        147 :         return _unpackVariant(this, true);
     316                 :            :     };
     317                 :            :     // backwards compatibility alias
     318                 :         47 :     this.Variant.prototype.deep_unpack = this.Variant.prototype.deepUnpack;
     319                 :            : 
     320                 :            :     // Note: discards type information, if the variant contains any 'v' types
     321                 :         47 :     this.Variant.prototype.recursiveUnpack = function () {
     322                 :         76 :         return _unpackVariant(this, true, true);
     323                 :            :     };
     324                 :            : 
     325                 :         47 :     this.Variant.prototype.toString = function () {
     326                 :          0 :         return `[object variant of type "${this.get_type_string()}"]`;
     327                 :            :     };
     328                 :            : 
     329                 :         47 :     this.Bytes.prototype.toArray = function () {
     330                 :        307 :         return imports._byteArrayNative.fromGBytes(this);
     331                 :            :     };
     332                 :            : 
     333                 :         47 :     this.log_structured =
     334                 :            :     /**
     335                 :            :      * @param {string} logDomain Log domain.
     336                 :            :      * @param {GLib.LogLevelFlags} logLevel Log level, either from GLib.LogLevelFlags, or a user-defined level.
     337                 :            :      * @param {Record<string, unknown>} fields Key-value pairs of structured data to add to the log entry.
     338                 :            :      * @returns {void}
     339                 :            :      */
     340                 :         73 :     function log_structured(logDomain, logLevel, fields) {
     341                 :            :         /** @type {Record<string, GLib.Variant>} */
     342                 :         73 :         let variantFields = {};
     343                 :            : 
     344         [ +  + ]:        220 :         for (let key in fields) {
     345                 :        147 :             const field = fields[key];
     346                 :            : 
     347         [ +  + ]:        147 :             if (field instanceof Uint8Array) {
     348                 :          1 :                 variantFields[key] = new GLib.Variant('ay', field);
     349         [ -  + ]:        146 :             } else if (typeof field === 'string') {
     350                 :        146 :                 variantFields[key] = new GLib.Variant('s', field);
     351         [ #  # ]:          0 :             } else if (field instanceof GLib.Variant) {
     352                 :            :                 // GLib.log_variant converts all Variants that are
     353                 :            :                 // not 'ay' or 's' type to strings by printing
     354                 :            :                 // them.
     355                 :            :                 //
     356                 :            :                 // https://gitlab.gnome.org/GNOME/glib/-/blob/a380bfdf93cb3bfd3cd4caedc0127c4e5717545b/glib/gmessages.c#L1894
     357                 :          0 :                 variantFields[key] = field;
     358                 :            :             } else {
     359                 :          0 :                 throw new TypeError(`Unsupported value ${field}, log_structured supports GLib.Variant, Uint8Array, and string values.`);
     360                 :            :             }
     361                 :            :         }
     362                 :            : 
     363                 :         73 :         GLib.log_variant(logDomain, logLevel, new GLib.Variant('a{sv}', variantFields));
     364                 :            :     };
     365                 :            : 
     366                 :            :     // GjsPrivate depends on GLib so we cannot import it
     367                 :            :     // before GLib is fully resolved.
     368                 :            : 
     369                 :         47 :     this.log_set_writer_func_variant = function (...args) {
     370                 :          0 :         const {log_set_writer_func} = imports.gi.GjsPrivate;
     371                 :            : 
     372 [ #  # ][ #  # ]:          0 :         log_set_writer_func(...args);
     373                 :            :     };
     374                 :            : 
     375                 :         47 :     this.log_set_writer_default = function (...args) {
     376                 :          0 :         const {log_set_writer_default} = imports.gi.GjsPrivate;
     377                 :            : 
     378 [ #  # ][ #  # ]:          0 :         log_set_writer_default(...args);
     379                 :            :     };
     380                 :            : 
     381                 :         50 :     this.log_set_writer_func = function (writer_func) {
     382                 :          3 :         const {log_set_writer_func} = imports.gi.GjsPrivate;
     383                 :            : 
     384         [ +  - ]:          3 :         if (typeof writer_func !== 'function') {
     385                 :          0 :             log_set_writer_func(writer_func);
     386                 :            :         } else {
     387                 :         75 :             log_set_writer_func(function (logLevel, stringFields) {
     388                 :         72 :                 const stringFieldsObj = {...stringFields.recursiveUnpack()};
     389                 :         72 :                 return writer_func(logLevel, stringFieldsObj);
     390                 :         72 :             });
     391                 :            :         }
     392                 :            :     };
     393                 :            : 
     394 [ +  + ][ -  + ]:         55 :     this.VariantDict.prototype.lookup = function (key, variantType = null, deep = false) {
     395         [ +  + ]:          8 :         if (typeof variantType === 'string')
     396                 :          2 :             variantType = new GLib.VariantType(variantType);
     397                 :            : 
     398                 :          8 :         const variant = this.lookup_value(key, variantType);
     399         [ +  + ]:          8 :         if (variant === null)
     400                 :          4 :             return null;
     401                 :          4 :         return _unpackVariant(variant, deep);
     402                 :          8 :     };
     403                 :            : 
     404                 :            :     // Prevent user code from calling GLib string manipulation functions that
     405                 :            :     // return the same string that was passed in. These can't be annotated
     406                 :            :     // properly, and will mostly crash.
     407                 :            :     // Here we provide approximate implementations of the functions so that if
     408                 :            :     // they had happened to work in the past, they will continue working, but
     409                 :            :     // log a stack trace and a suggestion of what to use instead.
     410                 :            :     // Exceptions are thrown instead for GLib.stpcpy() of which the return value
     411                 :            :     // is useless anyway and GLib.ascii_formatd() which is too complicated to
     412                 :            :     // implement here.
     413                 :            : 
     414                 :         47 :     this.stpcpy = function () {
     415                 :          1 :         throw _notIntrospectableError('GLib.stpcpy()', 'the + operator');
     416                 :            :     };
     417                 :            : 
     418                 :         51 :     this.strstr_len = function (haystack, len, needle) {
     419                 :          4 :         _warnNotIntrospectable('GLib.strstr_len()', 'String.indexOf()');
     420                 :          4 :         let searchString = haystack;
     421         [ +  + ]:          4 :         if (len !== -1)
     422                 :          2 :             searchString = searchString.slice(0, len);
     423                 :          4 :         const index = searchString.indexOf(needle);
     424         [ +  + ]:          4 :         if (index === -1)
     425                 :          2 :             return null;
     426                 :          2 :         return haystack.slice(index);
     427                 :          4 :     };
     428                 :            : 
     429                 :         49 :     this.strrstr = function (haystack, needle) {
     430                 :          2 :         _warnNotIntrospectable('GLib.strrstr()', 'String.lastIndexOf()');
     431                 :          2 :         const index = haystack.lastIndexOf(needle);
     432         [ +  + ]:          2 :         if (index === -1)
     433                 :          1 :             return null;
     434                 :          1 :         return haystack.slice(index);
     435                 :          2 :     };
     436                 :            : 
     437                 :         50 :     this.strrstr_len = function (haystack, len, needle) {
     438                 :          3 :         _warnNotIntrospectable('GLib.strrstr_len()', 'String.lastIndexOf()');
     439                 :          3 :         let searchString = haystack;
     440         [ +  + ]:          3 :         if (len !== -1)
     441                 :          1 :             searchString = searchString.slice(0, len);
     442                 :          3 :         const index = searchString.lastIndexOf(needle);
     443         [ +  + ]:          3 :         if (index === -1)
     444                 :          1 :             return null;
     445                 :          2 :         return haystack.slice(index);
     446                 :          3 :     };
     447                 :            : 
     448                 :         47 :     this.strup = function (string) {
     449                 :          2 :         _warnNotIntrospectable('GLib.strup()',
     450                 :          1 :             'String.toUpperCase() or GLib.ascii_strup()');
     451                 :          1 :         return string.toUpperCase();
     452                 :            :     };
     453                 :            : 
     454                 :         47 :     this.strdown = function (string) {
     455                 :          2 :         _warnNotIntrospectable('GLib.strdown()',
     456                 :          1 :             'String.toLowerCase() or GLib.ascii_strdown()');
     457                 :          1 :         return string.toLowerCase();
     458                 :            :     };
     459                 :            : 
     460                 :         47 :     this.strreverse = function (string) {
     461                 :          2 :         _warnNotIntrospectable('GLib.strreverse()',
     462                 :          1 :             'Array.reverse() and String.join()');
     463         [ +  + ]:          1 :         return [...string].reverse().join('');
     464                 :            :     };
     465                 :            : 
     466                 :         47 :     this.ascii_dtostr = function (unused, len, number) {
     467                 :          2 :         _warnNotIntrospectable('GLib.ascii_dtostr()', 'JS string conversion');
     468                 :          2 :         return `${number}`.slice(0, len);
     469                 :            :     };
     470                 :            : 
     471                 :         47 :     this.ascii_formatd = function () {
     472                 :          2 :         throw _notIntrospectableError('GLib.ascii_formatd()',
     473                 :          1 :             'Number.toExponential() and string interpolation');
     474                 :            :     };
     475                 :            : 
     476                 :         47 :     this.strchug = function (string) {
     477                 :          2 :         _warnNotIntrospectable('GLib.strchug()', 'String.trimStart()');
     478                 :          2 :         return string.trimStart();
     479                 :            :     };
     480                 :            : 
     481                 :         47 :     this.strchomp = function (string) {
     482                 :          2 :         _warnNotIntrospectable('GLib.strchomp()', 'String.trimEnd()');
     483                 :          2 :         return string.trimEnd();
     484                 :            :     };
     485                 :            : 
     486                 :            :     // g_strstrip() is a macro and therefore doesn't even appear in the GIR
     487                 :            :     // file, but we may as well include it here since it's trivial
     488                 :         47 :     this.strstrip = function (string) {
     489                 :          4 :         _warnNotIntrospectable('GLib.strstrip()', 'String.trim()');
     490                 :          4 :         return string.trim();
     491                 :            :     };
     492                 :            : 
     493                 :         51 :     this.strdelimit = function (string, delimiters, newDelimiter) {
     494                 :          4 :         _warnNotIntrospectable('GLib.strdelimit()', 'String.replace()');
     495                 :            : 
     496         [ +  + ]:          4 :         if (delimiters === null)
     497                 :          2 :             delimiters = GLib.STR_DELIMITERS;
     498         [ +  + ]:          4 :         if (typeof newDelimiter === 'number')
     499                 :          2 :             newDelimiter = String.fromCharCode(newDelimiter);
     500                 :            : 
     501                 :          4 :         const delimiterChars = delimiters.split('');
     502                 :          4 :         const escapedDelimiterChars = delimiterChars.map(_escapeCharacterSetChars);
     503                 :          4 :         const delimiterRegex = new RegExp(`[${escapedDelimiterChars.join('')}]`, 'g');
     504                 :          4 :         return string.replace(delimiterRegex, newDelimiter);
     505                 :          4 :     };
     506                 :            : 
     507                 :         49 :     this.strcanon = function (string, validChars, substitutor) {
     508                 :          2 :         _warnNotIntrospectable('GLib.strcanon()', 'String.replace()');
     509                 :            : 
     510         [ +  + ]:          2 :         if (typeof substitutor === 'number')
     511                 :          1 :             substitutor = String.fromCharCode(substitutor);
     512                 :            : 
     513                 :          2 :         const validArray = validChars.split('');
     514                 :          2 :         const escapedValidArray = validArray.map(_escapeCharacterSetChars);
     515                 :          2 :         const invalidRegex = new RegExp(`[^${escapedValidArray.join('')}]`, 'g');
     516                 :          2 :         return string.replace(invalidRegex, substitutor);
     517                 :          2 :     };
     518                 :            : 
     519                 :            :     // Prevent user code from calling GThread functions which always crash
     520                 :         47 :     this.Thread.new = function () {
     521                 :          0 :         throw _notIntrospectableError('GLib.Thread.new()',
     522                 :          0 :             'GIO asynchronous methods or Promise()');
     523                 :            :     };
     524                 :            : 
     525                 :         47 :     this.Thread.try_new = function () {
     526                 :          0 :         throw _notIntrospectableError('GLib.Thread.try_new()',
     527                 :          0 :             'GIO asynchronous methods or Promise()');
     528                 :            :     };
     529                 :            : 
     530                 :         47 :     this.Thread.exit = function () {
     531                 :          0 :         throw new Error('\'GLib.Thread.exit()\' may not be called in GJS');
     532                 :            :     };
     533                 :            : 
     534                 :         47 :     this.Thread.prototype.ref = function () {
     535                 :          0 :         throw new Error('\'GLib.Thread.ref()\' may not be called in GJS');
     536                 :            :     };
     537                 :            : 
     538                 :         47 :     this.Thread.prototype.unref = function () {
     539                 :          0 :         throw new Error('\'GLib.Thread.unref()\' may not be called in GJS');
     540                 :            :     };
     541                 :            : }

Generated by: LCOV version 1.14