LCOV - code coverage report
Current view: top level - libgnucash/engine - qofobject.cpp (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 97.6 % 123 120
Test Date: 2025-02-07 16:25:45 Functions: 100.0 % 18 18
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /********************************************************************\
       2                 :             :  * qofobject.c -- the Core Object Registration/Lookup Interface     *
       3                 :             :  * This program is free software; you can redistribute it and/or    *
       4                 :             :  * modify it under the terms of the GNU General Public License as   *
       5                 :             :  * published by the Free Software Foundation; either version 2 of   *
       6                 :             :  * the License, or (at your option) any later version.              *
       7                 :             :  *                                                                  *
       8                 :             :  * This program is distributed in the hope that it will be useful,  *
       9                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
      10                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
      11                 :             :  * GNU General Public License for more details.                     *
      12                 :             :  *                                                                  *
      13                 :             :  * You should have received a copy of the GNU General Public License*
      14                 :             :  * along with this program; if not, contact:                        *
      15                 :             :  *                                                                  *
      16                 :             :  * Free Software Foundation           Voice:  +1-617-542-5942       *
      17                 :             :  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
      18                 :             :  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
      19                 :             :  *                                                                  *
      20                 :             : \********************************************************************/
      21                 :             : /*
      22                 :             :  * qofobject.c -- the Core Object Object Registry
      23                 :             :  * Copyright (C) 2001 Derek Atkins
      24                 :             :  * Author: Derek Atkins <warlord@MIT.EDU>
      25                 :             :  */
      26                 :             : #include <config.h>
      27                 :             : #include <glib.h>
      28                 :             : 
      29                 :             : #include "qof.h"
      30                 :             : #include "qofobject-p.h"
      31                 :             : 
      32                 :             : static QofLogModule log_module = QOF_MOD_OBJECT;
      33                 :             : 
      34                 :             : static gboolean object_is_initialized = FALSE;
      35                 :             : static GList *object_modules = nullptr;
      36                 :             : static GList *book_list = nullptr;
      37                 :             : 
      38                 :             : /*
      39                 :             :  * These getters are used in tests to reach static vars from outside
      40                 :             :  * They should be removed when no longer needed
      41                 :             :  */
      42                 :             : 
      43                 :             : extern "C"
      44                 :             : {
      45                 :             : 
      46                 :             : GList* get_object_modules( void );
      47                 :             : GList* get_book_list( void );
      48                 :             : }
      49                 :             : 
      50                 :             : GList*
      51                 :          30 : get_object_modules( void )
      52                 :             : {
      53                 :          30 :     return object_modules;
      54                 :             : }
      55                 :             : 
      56                 :             : GList*
      57                 :          12 : get_book_list( void )
      58                 :             : {
      59                 :          12 :     return book_list;
      60                 :             : }
      61                 :             : 
      62                 :             : /*********/
      63                 :             : 
      64                 :             : gpointer
      65                 :           4 : qof_object_new_instance (QofIdTypeConst type_name, QofBook *book)
      66                 :             : {
      67                 :             :     const QofObject *obj;
      68                 :             : 
      69                 :           4 :     if (!type_name) return nullptr;
      70                 :             : 
      71                 :           3 :     obj = qof_object_lookup (type_name);
      72                 :           3 :     if (!obj) return nullptr;
      73                 :             : 
      74                 :           2 :     if (obj->create)
      75                 :           1 :         return (obj->create (book));
      76                 :             : 
      77                 :           1 :     return nullptr;
      78                 :             : }
      79                 :             : 
      80                 :         568 : void qof_object_book_begin (QofBook *book)
      81                 :             : {
      82                 :             :     GList *l;
      83                 :             : 
      84                 :         568 :     if (!book) return;
      85                 :         568 :     ENTER (" ");
      86                 :        6883 :     for (l = object_modules; l; l = l->next)
      87                 :             :     {
      88                 :        6315 :         QofObject *obj = static_cast<QofObject*>(l->data);
      89                 :        6315 :         if (obj->book_begin)
      90                 :        1679 :             obj->book_begin (book);
      91                 :             :     }
      92                 :             : 
      93                 :             :     /* Remember this book for later */
      94                 :         568 :     book_list = g_list_prepend (book_list, book);
      95                 :         568 :     LEAVE (" ");
      96                 :             : }
      97                 :             : 
      98                 :         457 : void qof_object_book_end (QofBook *book)
      99                 :             : {
     100                 :             :     GList *l;
     101                 :             : 
     102                 :         457 :     if (!book) return;
     103                 :         457 :     ENTER (" ");
     104                 :        4410 :     for (l = object_modules; l; l = l->next)
     105                 :             :     {
     106                 :        3953 :         QofObject *obj = static_cast<QofObject*>(l->data);
     107                 :        3953 :         if (obj->book_end)
     108                 :        2633 :             obj->book_end (book);
     109                 :             :     }
     110                 :             : 
     111                 :             :     /* Remove it from the list */
     112                 :         457 :     book_list = g_list_remove (book_list, book);
     113                 :         457 :     LEAVE (" ");
     114                 :             : }
     115                 :             : 
     116                 :             : gboolean
     117                 :           4 : qof_object_is_dirty (const QofBook *book)
     118                 :             : {
     119                 :             :     GList *l;
     120                 :             : 
     121                 :           4 :     if (!book) return FALSE;
     122                 :           6 :     for (l = object_modules; l; l = l->next)
     123                 :             :     {
     124                 :           4 :         QofObject *obj = static_cast<QofObject*>(l->data);
     125                 :           4 :         if (obj->is_dirty)
     126                 :             :         {
     127                 :             :             QofCollection *col;
     128                 :           4 :             col = qof_book_get_collection (book, obj->e_type);
     129                 :           4 :             if (obj->is_dirty (col)) return TRUE;
     130                 :             :         }
     131                 :             :     }
     132                 :           2 :     return FALSE;
     133                 :             : }
     134                 :             : 
     135                 :             : void
     136                 :           2 : qof_object_mark_clean (QofBook *book)
     137                 :             : {
     138                 :             :     GList *l;
     139                 :             : 
     140                 :           2 :     if (!book) return;
     141                 :           5 :     for (l = object_modules; l; l = l->next)
     142                 :             :     {
     143                 :           3 :         QofObject *obj = static_cast<QofObject*>(l->data);
     144                 :           3 :         if (obj->mark_clean)
     145                 :             :         {
     146                 :             :             QofCollection *col;
     147                 :           3 :             col = qof_book_get_collection (book, obj->e_type);
     148                 :           3 :             (obj->mark_clean) (col);
     149                 :             :         }
     150                 :             :     }
     151                 :             : }
     152                 :             : 
     153                 :           7 : void qof_object_foreach_type (QofForeachTypeCB cb, gpointer user_data)
     154                 :             : {
     155                 :             :     GList *l;
     156                 :             : 
     157                 :           7 :     if (!cb) return;
     158                 :             : 
     159                 :          25 :     for (l = object_modules; l; l = l->next)
     160                 :             :     {
     161                 :          18 :         QofObject *obj = static_cast<QofObject*>(l->data);
     162                 :          18 :         (cb) (obj, user_data);
     163                 :             :     }
     164                 :             : }
     165                 :             : 
     166                 :             : gboolean
     167                 :           8 : qof_object_compliance (QofIdTypeConst type_name, gboolean warn)
     168                 :             : {
     169                 :             :     const QofObject *obj;
     170                 :             : 
     171                 :           8 :     obj = qof_object_lookup(type_name);
     172                 :           8 :     if ((obj->create == nullptr) || (obj->foreach == nullptr))
     173                 :             :     {
     174                 :           6 :         if (warn)
     175                 :             :         {
     176                 :           3 :             PINFO (" Object type %s is not fully QOF compliant", obj->e_type);
     177                 :             :         }
     178                 :           6 :         return FALSE;
     179                 :             :     }
     180                 :           2 :     return TRUE;
     181                 :             : }
     182                 :             : 
     183                 :             : 
     184                 :             : void
     185                 :        2408 : qof_object_foreach (QofIdTypeConst type_name, QofBook *book,
     186                 :             :                     QofInstanceForeachCB cb, gpointer user_data)
     187                 :             : {
     188                 :             :     QofCollection *col;
     189                 :             :     const QofObject *obj;
     190                 :             : 
     191                 :        2408 :     if (!book || !type_name)
     192                 :             :     {
     193                 :           6 :         return;
     194                 :             :     }
     195                 :        2402 :     PINFO ("type=%s", type_name);
     196                 :             : 
     197                 :        2402 :     obj = qof_object_lookup (type_name);
     198                 :        2402 :     if (!obj)
     199                 :             :     {
     200                 :           0 :         PERR ("No object of type %s", type_name);
     201                 :           0 :         return;
     202                 :             :     }
     203                 :        2402 :     col = qof_book_get_collection (book, obj->e_type);
     204                 :        2402 :     if (!obj)
     205                 :             :     {
     206                 :           0 :         return;
     207                 :             :     }
     208                 :        2402 :     if (obj->foreach)
     209                 :             :     {
     210                 :        2402 :         obj->foreach (col, cb, user_data);
     211                 :             :     }
     212                 :        2402 :     return;
     213                 :             : }
     214                 :             : 
     215                 :             : static void
     216                 :           8 : do_prepend (QofInstance *qof_p, gpointer list_p)
     217                 :             : {
     218                 :           8 :     GList **list = static_cast<GList**>(list_p);
     219                 :           8 :     *list = g_list_prepend(*list, qof_p);
     220                 :           8 : }
     221                 :             : 
     222                 :             : void
     223                 :          37 : qof_object_foreach_sorted (QofIdTypeConst type_name, QofBook *book, QofInstanceForeachCB cb, gpointer user_data)
     224                 :             : {
     225                 :          37 :     GList *list = nullptr;
     226                 :             :     GList *iter;
     227                 :             : 
     228                 :          37 :     qof_object_foreach(type_name, book, do_prepend, &list);
     229                 :             : 
     230                 :          37 :     list = g_list_sort(list, qof_instance_guid_compare);
     231                 :             : 
     232                 :          45 :     for (iter = list; iter; iter = iter->next)
     233                 :             :     {
     234                 :           8 :         cb(static_cast<QofInstance*>(iter->data), user_data);
     235                 :             :     }
     236                 :             : 
     237                 :          37 :     g_list_free(list);
     238                 :             : 
     239                 :             :     // FIXME: Apparently this is a memory leak, as this g_list_free doesn't
     240                 :             :     // free all of the allocated memory of g_list_append in do_append(). Why?!?
     241                 :             :     // Does g_list_sort have special side-effects on the memory of the list?
     242                 :             :     // Subsequently, I've changed the g_list_append into g_list_prepend, but
     243                 :             :     // solely for performance reasons. To my surprise, this also makes the
     244                 :             :     // dubious memory leak go away. But again why?!?
     245                 :          37 : }
     246                 :             : 
     247                 :             : const char *
     248                 :          13 : qof_object_printable (QofIdTypeConst type_name, gpointer obj)
     249                 :             : {
     250                 :             :     const QofObject *b_obj;
     251                 :             : 
     252                 :          13 :     if (!type_name || !obj) return nullptr;
     253                 :             : 
     254                 :           8 :     b_obj = qof_object_lookup (type_name);
     255                 :           8 :     if (!b_obj) return nullptr;
     256                 :             : 
     257                 :           7 :     if (b_obj->printable)
     258                 :           6 :         return (b_obj->printable (obj));
     259                 :             : 
     260                 :           1 :     return nullptr;
     261                 :             : }
     262                 :             : 
     263                 :           4 : const char * qof_object_get_type_label (QofIdTypeConst type_name)
     264                 :             : {
     265                 :             :     const QofObject *obj;
     266                 :             : 
     267                 :           4 :     if (!type_name) return nullptr;
     268                 :             : 
     269                 :           3 :     obj = qof_object_lookup (type_name);
     270                 :           3 :     if (!obj) return nullptr;
     271                 :             : 
     272                 :           2 :     return (obj->type_label);
     273                 :             : }
     274                 :             : 
     275                 :             : /* INITIALIZATION and PRIVATE FUNCTIONS */
     276                 :             : 
     277                 :         129 : void qof_object_initialize (void)
     278                 :             : {
     279                 :         129 :     if (object_is_initialized) return;
     280                 :         120 :     object_is_initialized = TRUE;
     281                 :             : }
     282                 :             : 
     283                 :          55 : void qof_object_shutdown (void)
     284                 :             : {
     285                 :          55 :     g_return_if_fail (object_is_initialized == TRUE);
     286                 :             : 
     287                 :          55 :     g_list_free (object_modules);
     288                 :          55 :     object_modules = nullptr;
     289                 :          55 :     g_list_free (book_list);
     290                 :          55 :     book_list = nullptr;
     291                 :          55 :     object_is_initialized = FALSE;
     292                 :             : }
     293                 :             : 
     294                 :             : /* Register new types of object objects.
     295                 :             :  * Return TRUE if successful,
     296                 :             :  * return FALSE if it fails, invalid arguments, or if the object
     297                 :             :  * already exists
     298                 :             :  */
     299                 :        2093 : gboolean qof_object_register (const QofObject *object)
     300                 :             : {
     301                 :        2093 :     g_return_val_if_fail (object_is_initialized, FALSE);
     302                 :             : 
     303                 :        2093 :     if (!object) return FALSE;
     304                 :        2091 :     g_return_val_if_fail (object->interface_version == QOF_OBJECT_VERSION, FALSE);
     305                 :             : 
     306                 :        2091 :     if (g_list_index (object_modules, (gpointer)object) == -1)
     307                 :        2066 :         object_modules = g_list_prepend (object_modules, (gpointer)object);
     308                 :             :     else
     309                 :          25 :         return FALSE;
     310                 :             : 
     311                 :             :     /* Now initialize all the known books */
     312                 :        2066 :     if (object->book_begin && book_list)
     313                 :             :     {
     314                 :             :         GList *node;
     315                 :          77 :         for (node = book_list; node; node = node->next)
     316                 :          42 :             object->book_begin (static_cast<QofBook*>(node->data));
     317                 :             :     }
     318                 :             : 
     319                 :        2066 :     return TRUE;
     320                 :             : }
     321                 :             : 
     322                 :        2433 : const QofObject * qof_object_lookup (QofIdTypeConst name)
     323                 :             : {
     324                 :             :     GList *iter;
     325                 :             :     const QofObject *obj;
     326                 :             : 
     327                 :        2433 :     g_return_val_if_fail (object_is_initialized, nullptr);
     328                 :             : 
     329                 :        2433 :     if (!name) return nullptr;
     330                 :             : 
     331                 :       33071 :     for (iter = object_modules; iter; iter = iter->next)
     332                 :             :     {
     333                 :       33066 :         obj = static_cast<QofObject*>(iter->data);
     334                 :       33066 :         if (!g_strcmp0 (obj->e_type, name))
     335                 :        2427 :             return obj;
     336                 :             :     }
     337                 :           5 :     return nullptr;
     338                 :             : }
     339                 :             : 
     340                 :             : /* ========================= END OF FILE =================== */
        

Generated by: LCOV version 2.0-1