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
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
|
/*
* 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 @data 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)
{
int rc;
if (!ce)
return -EINVAL;
ce->is_filled = 1;
rc = strdup_to_struct_member(ce, data, data);
ce->datasiz = ce->data && *ce->data ? strlen(ce->data) + 1: 0;
return rc;
}
/**
* scols_cell_refer_data:
* @ce: a pointer to a struct libscols_cell instance
* @data: string (used for scols_print_table())
*
* Adds a reference to @data to @ce. The pointer is deallocated by
* scols_reset_cell() or scols_unref_line() by free(). 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;
ce->datasiz = ce->data && *ce->data ? strlen(ce->data) + 1: 0;
ce->is_filled = 1;
return 0;
}
/**
* scols_cell_refer_memory:
* @ce: a pointer to a struct libscols_cell instance
* @data: data
* @datasiz: size of the data
*
* Same like scols_cell_refer_data, but @data does not have to be zero terminated.
* The pointer is deallocated by scols_reset_cell() or scols_unref_line() by free().
*
* The column (for the cell) has to define wrap function which converts the
* data to zero terminated string, otherwise library will work with the data as
* with string!
*
* Returns: 0, a negative value in case of an error.
*
* Since: 2.40
*/
int scols_cell_refer_memory(struct libscols_cell *ce, char *data, size_t datasiz)
{
if (!ce)
return -EINVAL;
free(ce->data);
ce->data = data;
ce->datasiz = datasiz;
return 0;
}
/**
* scols_cell_get_datasiz:
* @ce: a pointer to a struct libscols_cell instance
*
* Returns: the current set data size.
*
* Since: 2.40
*/
size_t scols_cell_get_datasiz(struct libscols_cell *ce)
{
return ce ? ce->datasiz : 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 ? ce->userdata : NULL;
}
/**
* scols_cmpstr_cells:
* @a: pointer to cell
* @b: pointer to cell
* @data: unused pointer to private data (defined by API)
*
* Compares cells data by strcoll(). The function is designed for
* scols_column_set_cmpfunc() and scols_sort_table().
*
* Returns: follows strcoll() 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 strcoll(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 (!ce)
return -EINVAL;
if (color && !color_is_sequence(color)) {
char *seq = color_get_sequence(color);
if (!seq)
return -EINVAL;
free(ce->color);
ce->color = seq;
return 0;
}
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)
{
if (!ce)
return NULL;
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 ? ce->flags : 0;
}
/**
* 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)
{
int flags = scols_cell_get_flags(ce);
if (flags & SCOLS_CELL_FL_RIGHT)
return SCOLS_CELL_FL_RIGHT;
if (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 (data, usewrdata, colors) 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;
char *data = NULL;
if (!dest || !src)
return -EINVAL;
if (src->datasiz) {
data = malloc(src->datasiz);
if (!data)
return -ENOMEM;
memcpy(data, src->data, src->datasiz);
}
rc = scols_cell_refer_memory(dest, data, src->datasiz);
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;
}
|