summaryrefslogtreecommitdiffstats
path: root/libsmartcols/src/cell.c
blob: 0717a2d09e22d991da496545ddbfb975d62b44f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
/*
 * cell.c - functions for table handling at the cell level
 *
 * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com>
 * Copyright (C) 2014 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 */

/**
 * SECTION: cell
 * @title: Cell
 * @short_description: container for your data
 *
 * An API to access and modify per-cell data and information. Note that cell is
 * always part of the line. If you destroy (un-reference) a line than it
 * destroys all line cells too.
 */


#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>

#include "smartcolsP.h"

/*
 * The cell has no ref-counting, free() and new() functions. All is
 * handled by libscols_line.
 */

/**
 * scols_reset_cell:
 * @ce: pointer to a struct libscols_cell instance
 *
 * Frees the cell's internal data and resets its status.
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_reset_cell(struct libscols_cell *ce)
{
	if (!ce)
		return -EINVAL;

	/*DBG(CELL, ul_debugobj(ce, "reset"));*/
	free(ce->data);
	free(ce->color);
	memset(ce, 0, sizeof(*ce));
	return 0;
}

/**
 * scols_cell_set_data:
 * @ce: a pointer to a struct libscols_cell instance
 * @data: data (used for scols_print_table())
 *
 * Stores a copy of the @str in @ce, the old data are deallocated by free().
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_cell_set_data(struct libscols_cell *ce, const char *data)
{
	return strdup_to_struct_member(ce, data, data);
}

/**
 * scols_cell_refer_data:
 * @ce: a pointer to a struct libscols_cell instance
 * @data: data (used for scols_print_table())
 *
 * Adds a reference to @str to @ce. The pointer is deallocated by
 * scols_reset_cell() or scols_unref_line(). This function is mostly designed
 * for situations when the data for the cell are already composed in allocated
 * memory (e.g. asprintf()) to avoid extra unnecessary strdup().
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_cell_refer_data(struct libscols_cell *ce, char *data)
{
	if (!ce)
		return -EINVAL;
	free(ce->data);
	ce->data = data;
	return 0;
}

/**
 * scols_cell_get_data:
 * @ce: a pointer to a struct libscols_cell instance
 *
 * Returns: data in @ce or NULL.
 */
const char *scols_cell_get_data(const struct libscols_cell *ce)
{
	return ce ? ce->data : NULL;
}

/**
 * scols_cell_set_userdata:
 * @ce: a pointer to a struct libscols_cell instance
 * @data: private user data
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_cell_set_userdata(struct libscols_cell *ce, void *data)
{
	if (!ce)
		return -EINVAL;
	ce->userdata = data;
	return 0;
}

/**
 * scols_cell_get_userdata
 * @ce: a pointer to a struct libscols_cell instance
 *
 * Returns: user data
 */
void *scols_cell_get_userdata(struct libscols_cell *ce)
{
	return ce->userdata;
}

/**
 * scols_cmpstr_cells:
 * @a: pointer to cell
 * @b: pointer to cell
 * @data: unused pointer to private data (defined by API)
 *
 * Compares cells data by strcmp(). The function is designed for
 * scols_column_set_cmpfunc() and scols_sort_table().
 *
 * Returns: follows strcmp() return values.
 */
int scols_cmpstr_cells(struct libscols_cell *a,
		       struct libscols_cell *b,
		       __attribute__((__unused__)) void *data)
{
	const char *adata, *bdata;

	if (a == b)
		return 0;

	adata = scols_cell_get_data(a);
	bdata = scols_cell_get_data(b);

	if (adata == NULL && bdata == NULL)
		return 0;
	if (adata == NULL)
		return -1;
	if (bdata == NULL)
		return 1;
	return strcmp(adata, bdata);
}

/**
 * scols_cell_set_color:
 * @ce: a pointer to a struct libscols_cell instance
 * @color: color name or ESC sequence
 *
 * Set the color of @ce to @color.
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_cell_set_color(struct libscols_cell *ce, const char *color)
{
	if (color && isalpha(*color)) {
		color = color_sequence_from_colorname(color);
		if (!color)
			return -EINVAL;
	}
	return strdup_to_struct_member(ce, color, color);
}

/**
 * scols_cell_get_color:
 * @ce: a pointer to a struct libscols_cell instance
 *
 * Returns: the current color of @ce.
 */
const char *scols_cell_get_color(const struct libscols_cell *ce)
{
	return ce->color;
}

/**
 * scols_cell_set_flags:
 * @ce: a pointer to a struct libscols_cell instance
 * @flags: SCOLS_CELL_FL_* flags
 *
 * Note that cells in the table are always aligned by column flags. The cell
 * flags are used for table title only (now).
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_cell_set_flags(struct libscols_cell *ce, int flags)
{
	if (!ce)
		return -EINVAL;
	ce->flags = flags;
	return 0;
}

/**
 * scols_cell_get_flags:
 * @ce: a pointer to a struct libscols_cell instance
 *
 * Returns: the current flags
 */
int scols_cell_get_flags(const struct libscols_cell *ce)
{
	return ce->flags;
}

/**
 * scols_cell_get_alignment:
 * @ce: a pointer to a struct libscols_cell instance
 *
 * Since: 2.30
 *
 * Returns: SCOLS_CELL_FL_{RIGHT,CELNTER,LEFT}
 */
int scols_cell_get_alignment(const struct libscols_cell *ce)
{
	if (ce->flags & SCOLS_CELL_FL_RIGHT)
		return SCOLS_CELL_FL_RIGHT;
	else if (ce->flags & SCOLS_CELL_FL_CENTER)
		return SCOLS_CELL_FL_CENTER;

	return SCOLS_CELL_FL_LEFT;	/* default */
}

/**
 * scols_cell_copy_content:
 * @dest: a pointer to a struct libscols_cell instance
 * @src: a pointer to an immutable struct libscols_cell instance
 *
 * Copy the contents of @src into @dest.
 *
 * Returns: 0, a negative value in case of an error.
 */
int scols_cell_copy_content(struct libscols_cell *dest,
			    const struct libscols_cell *src)
{
	int rc;

	rc = scols_cell_set_data(dest, scols_cell_get_data(src));
	if (!rc)
		rc = scols_cell_set_color(dest, scols_cell_get_color(src));
	if (!rc)
		dest->userdata = src->userdata;

	DBG(CELL, ul_debugobj(src, "copy"));
	return rc;
}