LCOV - code coverage report
Current view: top level - libgjs-private - gjs-match-info.c (source / functions) Coverage Total Hit
Test: gjs- Code Coverage Lines: 87.7 % 81 71
Test Date: 2024-04-20 17:42:51 Functions: 90.9 % 22 20
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 68.2 % 22 15

             Branch data     Line data    Source code
       1                 :             : /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
       2                 :             : /*
       3                 :             :  * SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
       4                 :             :  * SPDX-FileCopyrightText: 2023 Philip Chimento <philip.chimento@gmail.com>
       5                 :             :  */
       6                 :             : 
       7                 :             : #include <config.h>
       8                 :             : 
       9                 :             : #include <stdbool.h>
      10                 :             : #include <stddef.h>    /* for NULL */
      11                 :             : #include <stdint.h>
      12                 :             : #include <sys/types.h> /* for ssize_t */
      13                 :             : 
      14                 :             : #include <glib-object.h>
      15                 :             : #include <glib.h>
      16                 :             : 
      17                 :             : #include "libgjs-private/gjs-match-info.h"
      18                 :             : 
      19   [ +  +  +  -  :          60 : G_DEFINE_BOXED_TYPE(GjsMatchInfo, gjs_match_info, gjs_match_info_ref,
                   +  + ]
      20                 :             :                     gjs_match_info_unref)
      21                 :             : 
      22                 :             : struct _GjsMatchInfo {
      23                 :             :     gatomicrefcount refcount;
      24                 :             :     GMatchInfo* base; /* owned */
      25                 :             :     char* str;
      26                 :             : };
      27                 :             : 
      28                 :             : /* Takes ownership of string */
      29                 :          17 : static GjsMatchInfo* new_match_info(GMatchInfo* base, char* s) {
      30                 :          17 :     GjsMatchInfo* retval = g_new0(GjsMatchInfo, 1);
      31                 :          17 :     g_atomic_ref_count_init(&retval->refcount);
      32                 :          17 :     retval->base = base;
      33                 :          17 :     retval->str = s;
      34                 :          17 :     return retval;
      35                 :             : }
      36                 :             : 
      37                 :             : /**
      38                 :             :  * gjs_match_info_get_regex:
      39                 :             :  * @self: a #GjsMatchInfo
      40                 :             :  *
      41                 :             :  * Wrapper for g_match_info_get_regex().
      42                 :             :  *
      43                 :             :  * Returns: (transfer none): #GRegex object
      44                 :             :  */
      45                 :           0 : GRegex* gjs_match_info_get_regex(const GjsMatchInfo* self) {
      46                 :           0 :     g_return_val_if_fail(self != NULL, NULL);
      47                 :           0 :     return g_match_info_get_regex(self->base);
      48                 :             : }
      49                 :             : 
      50                 :             : /**
      51                 :             :  * gjs_match_info_get_string:
      52                 :             :  * @self: a #GjsMatchInfo
      53                 :             :  *
      54                 :             :  * Replacement for g_match_info_get_string(), but the string is owned by @self.
      55                 :             :  *
      56                 :             :  * Returns: (transfer none): the string searched with @match_info
      57                 :             :  */
      58                 :           4 : const char* gjs_match_info_get_string(const GjsMatchInfo* self) {
      59                 :           4 :     g_return_val_if_fail(self != NULL, NULL);
      60                 :           4 :     return self->str;
      61                 :             : }
      62                 :             : 
      63                 :             : /**
      64                 :             :  * gjs_match_info_ref:
      65                 :             :  * @self: a #GjsMatchInfo
      66                 :             :  *
      67                 :             :  * Replacement for g_match_info_ref().
      68                 :             :  *
      69                 :             :  * Returns: @self
      70                 :             :  */
      71                 :          17 : GjsMatchInfo* gjs_match_info_ref(GjsMatchInfo* self) {
      72                 :          17 :     g_return_val_if_fail(self != NULL, NULL);
      73                 :          17 :     g_atomic_ref_count_inc(&self->refcount);
      74                 :          17 :     return self;
      75                 :             : }
      76                 :             : 
      77                 :             : /**
      78                 :             :  * gjs_match_info_unref:
      79                 :             :  * @self: a #GjsMatchInfo
      80                 :             :  *
      81                 :             :  * Replacement for g_match_info_unref().
      82                 :             :  */
      83                 :          34 : void gjs_match_info_unref(GjsMatchInfo* self) {
      84                 :          34 :     g_return_if_fail(self != NULL);
      85         [ +  + ]:          34 :     if (g_atomic_ref_count_dec(&self->refcount)) {
      86                 :          17 :         g_match_info_unref(self->base);
      87                 :          17 :         g_free(self->str);
      88                 :          17 :         g_free(self);
      89                 :             :     }
      90                 :             : }
      91                 :             : 
      92                 :             : /**
      93                 :             :  * gjs_match_info_free:
      94                 :             :  * @self: (nullable): a #GjsMatchInfo, or %NULL
      95                 :             :  *
      96                 :             :  * Replacement for g_match_info_free().
      97                 :             :  */
      98                 :           0 : void gjs_match_info_free(GjsMatchInfo* self) {
      99                 :           0 :     g_return_if_fail(self != NULL);
     100         [ #  # ]:           0 :     if (self == NULL)
     101                 :           0 :         return;
     102                 :             : 
     103                 :           0 :     gjs_match_info_unref(self);
     104                 :             : }
     105                 :             : 
     106                 :             : /**
     107                 :             :  * gjs_match_info_next:
     108                 :             :  * @self: a #GjsMatchInfo
     109                 :             :  * @error: location to store the error occurring, or %NULL to ignore errors
     110                 :             :  *
     111                 :             :  * Wrapper for g_match_info_next().
     112                 :             :  *
     113                 :             :  * Returns: %TRUE or %FALSE
     114                 :             :  */
     115                 :           2 : gboolean gjs_match_info_next(GjsMatchInfo* self, GError** error) {
     116                 :           2 :     g_return_val_if_fail(self != NULL, FALSE);
     117                 :           2 :     return g_match_info_next(self->base, error);
     118                 :             : }
     119                 :             : 
     120                 :             : /**
     121                 :             :  * gjs_match_info_matches:
     122                 :             :  * @self: a #GjsMatchInfo
     123                 :             :  *
     124                 :             :  * Wrapper for g_match_info_matches().
     125                 :             :  *
     126                 :             :  * Returns: %TRUE or %FALSE
     127                 :             :  */
     128                 :           2 : gboolean gjs_match_info_matches(const GjsMatchInfo* self) {
     129                 :           2 :     g_return_val_if_fail(self != NULL, FALSE);
     130                 :           2 :     return g_match_info_matches(self->base);
     131                 :             : }
     132                 :             : 
     133                 :             : /**
     134                 :             :  * gjs_match_info_get_match_count:
     135                 :             :  * @self: a #GjsMatchInfo
     136                 :             :  *
     137                 :             :  * Wrapper for g_match_info_get_match_count().
     138                 :             :  *
     139                 :             :  * Returns: Number of matched substrings, or -1 if an error occurred
     140                 :             :  */
     141                 :           2 : int gjs_match_info_get_match_count(const GjsMatchInfo* self) {
     142                 :           2 :     g_return_val_if_fail(self != NULL, -1);
     143                 :           2 :     return g_match_info_get_match_count(self->base);
     144                 :             : }
     145                 :             : 
     146                 :             : /**
     147                 :             :  * gjs_match_info_is_partial_match:
     148                 :             :  * @self: a #GjsMatchInfo
     149                 :             :  *
     150                 :             :  * Wrapper for g_match_info_is_partial_match().
     151                 :             :  *
     152                 :             :  * Returns: %TRUE or %FALSE
     153                 :             :  */
     154                 :           2 : gboolean gjs_match_info_is_partial_match(const GjsMatchInfo* self) {
     155                 :           2 :     g_return_val_if_fail(self != NULL, FALSE);
     156                 :           2 :     return g_match_info_is_partial_match(self->base);
     157                 :             : }
     158                 :             : 
     159                 :             : /**
     160                 :             :  * gjs_match_info_expand_references:
     161                 :             :  * @self: (nullable): a #GjsMatchInfo or %NULL
     162                 :             :  * @string_to_expand: the string to expand
     163                 :             :  * @error: location to store the error occurring, or %NULL to ignore errors
     164                 :             :  *
     165                 :             :  * Wrapper for g_match_info_expand_references().
     166                 :             :  *
     167                 :             :  * Returns: (nullable): the expanded string, or %NULL if an error occurred
     168                 :             :  */
     169                 :           2 : char* gjs_match_info_expand_references(const GjsMatchInfo* self,
     170                 :             :                                        const char* string_to_expand,
     171                 :             :                                        GError** error) {
     172                 :           2 :     return g_match_info_expand_references(self->base, string_to_expand, error);
     173                 :             : }
     174                 :             : 
     175                 :             : /**
     176                 :             :  * gjs_match_info_fetch:
     177                 :             :  * @self: a #GjsMatchInfo
     178                 :             :  * @match_num: number of the sub expression
     179                 :             :  *
     180                 :             :  * Wrapper for g_match_info_fetch().
     181                 :             :  *
     182                 :             :  * Returns: (nullable): The matched substring, or %NULL if an error occurred.
     183                 :             :  */
     184                 :           2 : char* gjs_match_info_fetch(const GjsMatchInfo* self, int match_num) {
     185                 :           2 :     g_return_val_if_fail(self != NULL, NULL);
     186                 :           2 :     return g_match_info_fetch(self->base, match_num);
     187                 :             : }
     188                 :             : 
     189                 :             : /**
     190                 :             :  * gjs_match_info_fetch_pos:
     191                 :             :  * @self: a #GMatchInfo
     192                 :             :  * @match_num: number of the sub expression
     193                 :             :  * @start_pos: (out) (optional): pointer to location for the start position
     194                 :             :  * @end_pos: (out) (optional): pointer to location for the end position
     195                 :             :  *
     196                 :             :  * Wrapper for g_match_info_fetch_pos().
     197                 :             :  *
     198                 :             :  * Returns: %TRUE or %FALSE
     199                 :             :  */
     200                 :           2 : gboolean gjs_match_info_fetch_pos(const GjsMatchInfo* self, int match_num,
     201                 :             :                                   int* start_pos, int* end_pos) {
     202                 :           2 :     g_return_val_if_fail(self != NULL, FALSE);
     203                 :           2 :     return g_match_info_fetch_pos(self->base, match_num, start_pos, end_pos);
     204                 :             : }
     205                 :             : 
     206                 :             : /**
     207                 :             :  * gjs_match_info_fetch_named:
     208                 :             :  * @self: a #GjsMatchInfo
     209                 :             :  * @name: name of the subexpression
     210                 :             :  *
     211                 :             :  * Wrapper for g_match_info_fetch_named().
     212                 :             :  *
     213                 :             :  * Returns: (nullable): The matched substring, or %NULL if an error occurred.
     214                 :             :  */
     215                 :           2 : char* gjs_match_info_fetch_named(const GjsMatchInfo* self, const char* name) {
     216                 :           2 :     g_return_val_if_fail(self != NULL, NULL);
     217                 :           2 :     return g_match_info_fetch_named(self->base, name);
     218                 :             : }
     219                 :             : 
     220                 :             : /**
     221                 :             :  * gjs_match_info_fetch_named_pos:
     222                 :             :  * @self: a #GMatchInfo
     223                 :             :  * @name: name of the subexpression
     224                 :             :  * @start_pos: (out) (optional): pointer to location for the start position
     225                 :             :  * @end_pos: (out) (optional): pointer to location for the end position
     226                 :             :  *
     227                 :             :  * Wrapper for g_match_info_fetch_named_pos().
     228                 :             :  *
     229                 :             :  * Returns: %TRUE or %FALSE
     230                 :             :  */
     231                 :           2 : gboolean gjs_match_info_fetch_named_pos(const GjsMatchInfo* self,
     232                 :             :                                         const char* name, int* start_pos,
     233                 :             :                                         int* end_pos) {
     234                 :           2 :     g_return_val_if_fail(self != NULL, FALSE);
     235                 :           2 :     return g_match_info_fetch_named_pos(self->base, name, start_pos, end_pos);
     236                 :             : }
     237                 :             : 
     238                 :             : /**
     239                 :             :  * gjs_match_info_fetch_all:
     240                 :             :  * @self: a #GMatchInfo
     241                 :             :  *
     242                 :             :  * Wrapper for g_match_info_fetch_all().
     243                 :             :  *
     244                 :             :  * Returns: (transfer full): a %NULL-terminated array of strings. If the
     245                 :             :  *     previous match failed %NULL is returned
     246                 :             :  */
     247                 :           2 : char** gjs_match_info_fetch_all(const GjsMatchInfo* self) {
     248                 :           2 :     g_return_val_if_fail(self != NULL, NULL);
     249                 :           2 :     return g_match_info_fetch_all(self->base);
     250                 :             : }
     251                 :             : 
     252                 :             : /**
     253                 :             :  * gjs_regex_match:
     254                 :             :  * @regex: a #GRegex
     255                 :             :  * @s: the string to scan for matches
     256                 :             :  * @match_options: match options
     257                 :             :  * @match_info: (out) (optional): pointer to location for the #GjsMatchInfo
     258                 :             :  *
     259                 :             :  * Wrapper for g_regex_match() that doesn't require the string to be kept alive.
     260                 :             :  *
     261                 :             :  * Returns: %TRUE or %FALSE
     262                 :             :  */
     263                 :          13 : gboolean gjs_regex_match(const GRegex* regex, const char* s,
     264                 :             :                          GRegexMatchFlags match_options,
     265                 :             :                          GjsMatchInfo** match_info) {
     266                 :          13 :     return gjs_regex_match_full(regex, (const uint8_t*)s, -1, 0, match_options,
     267                 :             :                                 match_info, NULL);
     268                 :             : }
     269                 :             : 
     270                 :             : /**
     271                 :             :  * gjs_regex_match_full:
     272                 :             :  * @regex: a #GRegex
     273                 :             :  * @bytes: (array length=len): the string to scan for matches
     274                 :             :  * @len: the length of @bytes
     275                 :             :  * @start_position: starting index of the string to match, in bytes
     276                 :             :  * @match_options: match options
     277                 :             :  * @match_info: (out) (optional): pointer to location for the #GjsMatchInfo
     278                 :             :  * @error: location to store the error occurring, or %NULL to ignore errors
     279                 :             :  *
     280                 :             :  * Wrapper for g_regex_match_full() that doesn't require the string to be kept
     281                 :             :  * alive.
     282                 :             :  *
     283                 :             :  * Returns: %TRUE or %FALSE
     284                 :             :  */
     285                 :          15 : gboolean gjs_regex_match_full(const GRegex* regex, const uint8_t* bytes,
     286                 :             :                               ssize_t len, int start_position,
     287                 :             :                               GRegexMatchFlags match_options,
     288                 :             :                               GjsMatchInfo** match_info, GError** error) {
     289                 :          15 :     const char* s = (const char*)bytes;
     290         [ -  + ]:          15 :     if (match_info == NULL)
     291                 :           0 :         return g_regex_match_full(regex, s, len, start_position, match_options,
     292                 :             :                                   NULL, error);
     293                 :             : 
     294         [ +  + ]:          28 :     char* string_copy = len < 0 ? g_strdup(s) : g_strndup(s, len);
     295                 :          15 :     GMatchInfo* base = NULL;
     296                 :          15 :     bool retval = g_regex_match_full(regex, string_copy, len, start_position,
     297                 :             :                                      match_options, &base, error);
     298                 :             : 
     299         [ +  - ]:          15 :     if (base)
     300                 :          15 :         *match_info = new_match_info(base, string_copy);
     301                 :             : 
     302                 :          15 :     return retval;
     303                 :             : }
     304                 :             : 
     305                 :             : /**
     306                 :             :  * gjs_regex_match_all:
     307                 :             :  * @regex: a #GRegex
     308                 :             :  * @s: the string to scan for matches
     309                 :             :  * @match_options: match options
     310                 :             :  * @match_info: (out) (optional): pointer to location for the #GjsMatchInfo
     311                 :             :  *
     312                 :             :  * Wrapper for g_regex_match_all() that doesn't require the string to be kept
     313                 :             :  * alive.
     314                 :             :  *
     315                 :             :  * Returns: %TRUE or %FALSE
     316                 :             :  */
     317                 :           1 : gboolean gjs_regex_match_all(const GRegex* regex, const char* s,
     318                 :             :                              GRegexMatchFlags match_options,
     319                 :             :                              GjsMatchInfo** match_info) {
     320                 :           1 :     return gjs_regex_match_all_full(regex, (const uint8_t*)s, -1, 0,
     321                 :             :                                     match_options, match_info, NULL);
     322                 :             : }
     323                 :             : 
     324                 :             : /**
     325                 :             :  * gjs_regex_match_all_full:
     326                 :             :  * @regex: a #GRegex
     327                 :             :  * @bytes: (array length=len): the string to scan for matches
     328                 :             :  * @len: the length of @bytes
     329                 :             :  * @start_position: starting index of the string to match, in bytes
     330                 :             :  * @match_options: match options
     331                 :             :  * @match_info: (out) (optional): pointer to location for the #GMatchInfo
     332                 :             :  * @error: location to store the error occurring, or %NULL to ignore errors
     333                 :             :  *
     334                 :             :  * Wrapper for g_regex_match_all_full() that doesn't require the string to be
     335                 :             :  * kept alive.
     336                 :             :  *
     337                 :             :  * Returns: %TRUE or %FALSE
     338                 :             :  */
     339                 :           2 : gboolean gjs_regex_match_all_full(const GRegex* regex, const uint8_t* bytes,
     340                 :             :                                   ssize_t len, int start_position,
     341                 :             :                                   GRegexMatchFlags match_options,
     342                 :             :                                   GjsMatchInfo** match_info, GError** error) {
     343                 :           2 :     const char* s = (const char*)bytes;
     344         [ -  + ]:           2 :     if (match_info == NULL)
     345                 :           0 :         return g_regex_match_all_full(regex, s, len, start_position,
     346                 :             :                                       match_options, NULL, error);
     347                 :             : 
     348         [ +  + ]:           3 :     char* string_copy = len < 0 ? g_strdup(s) : g_strndup(s, len);
     349                 :           2 :     GMatchInfo* base = NULL;
     350                 :           2 :     bool retval = g_regex_match_all_full(
     351                 :             :         regex, string_copy, len, start_position, match_options, &base, error);
     352                 :             : 
     353         [ +  - ]:           2 :     if (base)
     354                 :           2 :         *match_info = new_match_info(base, string_copy);
     355                 :             : 
     356                 :           2 :     return retval;
     357                 :             : }
        

Generated by: LCOV version 2.0-1