str: Add function xstrdup_if_nonnull() and introduce many users.
[pspp] / src / output / output-item.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2009, 2011 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18
19 #include "output/output-item-provider.h"
20
21 #include <assert.h>
22 #include <stdlib.h>
23
24 #include "libpspp/assertion.h"
25 #include "libpspp/cast.h"
26 #include "libpspp/str.h"
27
28 #include "gl/xalloc.h"
29
30 #include "gettext.h"
31 \f
32 /* Increases ITEM's reference count, indicating that it has an additional
33    owner.  An output item that is shared among multiple owners must not be
34    modified. */
35 struct output_item *
36 output_item_ref (const struct output_item *item_)
37 {
38   struct output_item *item = CONST_CAST (struct output_item *, item_);
39   item->ref_cnt++;
40   return item;
41 }
42
43 /* Decreases ITEM's reference count, indicating that it has one fewer owner.
44    If ITEM no longer has any owners, it is freed. */
45 void
46 output_item_unref (struct output_item *item)
47 {
48   if (item != NULL)
49     {
50       assert (item->ref_cnt > 0);
51       if (--item->ref_cnt == 0)
52         {
53           char *label = item->label;
54           item->class->destroy (item);
55           free (label);
56         }
57     }
58 }
59
60 /* Returns true if ITEM has more than one owner.  An output item that is shared
61    among multiple owners must not be modified. */
62 bool
63 output_item_is_shared (const struct output_item *item)
64 {
65   return item->ref_cnt > 1;
66 }
67
68 /* Returns the label for ITEM, which the caller must not modify or free. */
69 const char *
70 output_item_get_label (const struct output_item *item)
71 {
72   return item->label ? item->label : item->class->get_label (item);
73 }
74
75 /* Sets the label for ITEM to LABEL.  The caller retains ownership of LABEL.
76    If LABEL is nonnull, it overrides any previously set label and the default
77    label.  If LABEL is null, ITEM will now use its default label.
78
79    ITEM must not be shared. */
80 void
81 output_item_set_label (struct output_item *item, const char *label)
82 {
83   output_item_set_label_nocopy (item, xstrdup_if_nonnull (label));
84 }
85
86 /* Sets the label for ITEM to LABEL, transferring ownership of LABEL to ITEM.
87    If LABEL is nonnull, it overrides any previously set label and the default
88    label.  If LABEL is null, ITEM will now use its default label.
89
90    ITEM must not be shared. */
91 void
92 output_item_set_label_nocopy (struct output_item *item, char *label)
93 {
94   assert (!output_item_is_shared (item));
95   free (item->label);
96   item->label = label;
97 }