NeoMutt  2020-11-20
Teaching an old dog new tricks
DOXYGEN
mbtable.c File Reference

Type representing a multibyte character table. More...

#include "config.h"
#include <limits.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "mutt/lib.h"
#include "mbtable.h"
#include "set.h"
#include "types.h"
+ Include dependency graph for mbtable.c:

Go to the source code of this file.

Functions

struct MbTablembtable_parse (const char *s)
 Parse a multibyte string into a table. More...
 
static void mbtable_destroy (const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef)
 Destroy an MbTable object - Implements ConfigSetType::destroy() More...
 
static int mbtable_string_set (const struct ConfigSet *cs, void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err)
 Set an MbTable by string - Implements ConfigSetType::string_set() More...
 
static int mbtable_string_get (const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *result)
 Get a MbTable as a string - Implements ConfigSetType::string_get() More...
 
static struct MbTablembtable_dup (struct MbTable *table)
 Create a copy of an MbTable object. More...
 
static int mbtable_native_set (const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
 Set an MbTable config item by MbTable object - Implements ConfigSetType::native_set() More...
 
static intptr_t mbtable_native_get (const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
 Get an MbTable object from a MbTable config item - Implements ConfigSetType::native_get() More...
 
static int mbtable_reset (const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
 Reset an MbTable to its initial value - Implements ConfigSetType::reset() More...
 
void mbtable_free (struct MbTable **table)
 Free an MbTable object. More...
 

Variables

const struct ConfigSetType cst_mbtable
 Config type representing a multi-byte table. More...
 

Detailed Description

Type representing a multibyte character table.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file mbtable.c.

Function Documentation

◆ mbtable_parse()

struct MbTable* mbtable_parse ( const char *  s)

Parse a multibyte string into a table.

Parameters
sString of multibyte characters
Return values
ptrNew MbTable object

Definition at line 49 of file mbtable.c.

50 {
51  struct MbTable *t = NULL;
52  size_t slen, k;
53  mbstate_t mbstate;
54  char *d = NULL;
55 
56  slen = mutt_str_len(s);
57  if (!slen)
58  return NULL;
59 
60  t = mutt_mem_calloc(1, sizeof(struct MbTable));
61 
62  t->orig_str = mutt_str_dup(s);
63  /* This could be more space efficient. However, being used on tiny
64  * strings (`$to_chars` and `$status_chars`), the overhead is not great. */
65  t->chars = mutt_mem_calloc(slen, sizeof(char *));
66  t->segmented_str = mutt_mem_calloc(slen * 2, sizeof(char));
67  d = t->segmented_str;
68 
69  memset(&mbstate, 0, sizeof(mbstate));
70  while (slen && (k = mbrtowc(NULL, s, slen, &mbstate)))
71  {
72  if ((k == (size_t)(-1)) || (k == (size_t)(-2)))
73  {
74  /* XXX put message in err buffer; fail? warning? */
75  mutt_debug(LL_DEBUG1, "mbrtowc returned %d converting %s in %s\n",
76  (k == (size_t)(-1)) ? -1 : -2, s, t->orig_str);
77  if (k == (size_t)(-1))
78  memset(&mbstate, 0, sizeof(mbstate));
79  k = (k == (size_t)(-1)) ? 1 : slen;
80  }
81 
82  slen -= k;
83  t->chars[t->len++] = d;
84  while (k--)
85  *d++ = *s++;
86  *d++ = '\0';
87  }
88 
89  return t;
90 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
char ** chars
The array of multibyte character strings.
Definition: mbtable.h:39
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
multibyte character table
Definition: mbtable.h:35
char * orig_str
Original string used to generate this object.
Definition: mbtable.h:37
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
Log at debug level 1.
Definition: logging.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
int len
Number of characters.
Definition: mbtable.h:38
char * segmented_str
Each chars entry points inside this string.
Definition: mbtable.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mbtable_destroy()

static void mbtable_destroy ( const struct ConfigSet cs,
void *  var,
const struct ConfigDef cdef 
)
static

Destroy an MbTable object - Implements ConfigSetType::destroy()

Definition at line 95 of file mbtable.c.

96 {
97  struct MbTable **m = var;
98  if (!*m)
99  return;
100 
101  mbtable_free(m);
102 }
multibyte character table
Definition: mbtable.h:35
void mbtable_free(struct MbTable **table)
Free an MbTable object.
Definition: mbtable.c:281
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mbtable_string_set()

static int mbtable_string_set ( const struct ConfigSet cs,
void *  var,
struct ConfigDef cdef,
const char *  value,
struct Buffer err 
)
static

Set an MbTable by string - Implements ConfigSetType::string_set()

Definition at line 107 of file mbtable.c.

109 {
110  /* Store empty mbtables as NULL */
111  if (value && (value[0] == '\0'))
112  value = NULL;
113 
114  struct MbTable *table = NULL;
115 
116  int rc = CSR_SUCCESS;
117 
118  if (var)
119  {
120  struct MbTable *curval = *(struct MbTable **) var;
121  if (curval && mutt_str_equal(value, curval->orig_str))
123 
124  table = mbtable_parse(value);
125 
126  if (cdef->validator)
127  {
128  rc = cdef->validator(cs, cdef, (intptr_t) table, err);
129 
130  if (CSR_RESULT(rc) != CSR_SUCCESS)
131  {
132  mbtable_free(&table);
133  return rc | CSR_INV_VALIDATOR;
134  }
135  }
136 
137  mbtable_destroy(cs, var, cdef);
138 
139  *(struct MbTable **) var = table;
140 
141  if (!table)
142  rc |= CSR_SUC_EMPTY;
143  }
144  else
145  {
146  if (cdef->type & DT_INITIAL_SET)
147  FREE(&cdef->initial);
148 
149  cdef->type |= DT_INITIAL_SET;
150  cdef->initial = IP mutt_str_dup(value);
151  }
152 
153  return rc;
154 }
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
#define IP
Definition: set.h:54
intptr_t initial
Initial value.
Definition: set.h:66
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define DT_INITIAL_SET
Config item must have its initial value freed.
Definition: types.h:81
multibyte character table
Definition: mbtable.h:35
#define CSR_RESULT(x)
Definition: set.h:52
static void mbtable_destroy(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef)
Destroy an MbTable object - Implements ConfigSetType::destroy()
Definition: mbtable.c:95
#define CSR_SUC_EMPTY
Value is empty/unset.
Definition: set.h:42
#define CSR_SUC_NO_CHANGE
The value hasn&#39;t changed.
Definition: set.h:44
struct MbTable * mbtable_parse(const char *s)
Parse a multibyte string into a table.
Definition: mbtable.c:49
int(* validator)(const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Validate a config variable.
Definition: set.h:78
char * orig_str
Original string used to generate this object.
Definition: mbtable.h:37
unsigned int type
Variable type, e.g. DT_STRING.
Definition: set.h:64
#define FREE(x)
Definition: memory.h:40
#define CSR_INV_VALIDATOR
Value was rejected by the validator.
Definition: set.h:48
void mbtable_free(struct MbTable **table)
Free an MbTable object.
Definition: mbtable.c:281
+ Here is the call graph for this function:

◆ mbtable_string_get()

static int mbtable_string_get ( const struct ConfigSet cs,
void *  var,
const struct ConfigDef cdef,
struct Buffer result 
)
static

Get a MbTable as a string - Implements ConfigSetType::string_get()

Definition at line 159 of file mbtable.c.

161 {
162  const char *str = NULL;
163 
164  if (var)
165  {
166  struct MbTable *table = *(struct MbTable **) var;
167  if (!table || !table->orig_str)
168  return CSR_SUCCESS | CSR_SUC_EMPTY; /* empty string */
169  str = table->orig_str;
170  }
171  else
172  {
173  str = (char *) cdef->initial;
174  }
175 
176  mutt_buffer_addstr(result, str);
177  return CSR_SUCCESS;
178 }
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
intptr_t initial
Initial value.
Definition: set.h:66
multibyte character table
Definition: mbtable.h:35
#define CSR_SUC_EMPTY
Value is empty/unset.
Definition: set.h:42
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
char * orig_str
Original string used to generate this object.
Definition: mbtable.h:37
+ Here is the call graph for this function:

◆ mbtable_dup()

static struct MbTable* mbtable_dup ( struct MbTable table)
static

Create a copy of an MbTable object.

Parameters
tableMbTable to duplicate
Return values
ptrNew MbTable object

Definition at line 185 of file mbtable.c.

186 {
187  if (!table)
188  return NULL; /* LCOV_EXCL_LINE */
189 
190  struct MbTable *m = mutt_mem_calloc(1, sizeof(*m));
191  m->orig_str = mutt_str_dup(table->orig_str);
192  return m;
193 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
multibyte character table
Definition: mbtable.h:35
char * orig_str
Original string used to generate this object.
Definition: mbtable.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mbtable_native_set()

static int mbtable_native_set ( const struct ConfigSet cs,
void *  var,
const struct ConfigDef cdef,
intptr_t  value,
struct Buffer err 
)
static

Set an MbTable config item by MbTable object - Implements ConfigSetType::native_set()

Definition at line 198 of file mbtable.c.

201 {
202  int rc;
203 
204  if (cdef->validator)
205  {
206  rc = cdef->validator(cs, cdef, value, err);
207 
208  if (CSR_RESULT(rc) != CSR_SUCCESS)
209  return rc | CSR_INV_VALIDATOR;
210  }
211 
212  mbtable_free(var);
213 
214  struct MbTable *table = mbtable_dup((struct MbTable *) value);
215 
216  rc = CSR_SUCCESS;
217  if (!table)
218  rc |= CSR_SUC_EMPTY;
219 
220  *(struct MbTable **) var = table;
221  return rc;
222 }
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
multibyte character table
Definition: mbtable.h:35
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUC_EMPTY
Value is empty/unset.
Definition: set.h:42
int(* validator)(const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Validate a config variable.
Definition: set.h:78
static struct MbTable * mbtable_dup(struct MbTable *table)
Create a copy of an MbTable object.
Definition: mbtable.c:185
#define CSR_INV_VALIDATOR
Value was rejected by the validator.
Definition: set.h:48
void mbtable_free(struct MbTable **table)
Free an MbTable object.
Definition: mbtable.c:281
+ Here is the call graph for this function:

◆ mbtable_native_get()

static intptr_t mbtable_native_get ( const struct ConfigSet cs,
void *  var,
const struct ConfigDef cdef,
struct Buffer err 
)
static

Get an MbTable object from a MbTable config item - Implements ConfigSetType::native_get()

Definition at line 227 of file mbtable.c.

229 {
230  struct MbTable *table = *(struct MbTable **) var;
231 
232  return (intptr_t) table;
233 }
multibyte character table
Definition: mbtable.h:35

◆ mbtable_reset()

static int mbtable_reset ( const struct ConfigSet cs,
void *  var,
const struct ConfigDef cdef,
struct Buffer err 
)
static

Reset an MbTable to its initial value - Implements ConfigSetType::reset()

Definition at line 238 of file mbtable.c.

240 {
241  struct MbTable *table = NULL;
242  const char *initial = (const char *) cdef->initial;
243 
244  struct MbTable *curtable = *(struct MbTable **) var;
245  const char *curval = curtable ? curtable->orig_str : NULL;
246 
247  int rc = CSR_SUCCESS;
248  if (!curtable)
249  rc |= CSR_SUC_EMPTY;
250 
251  if (mutt_str_equal(initial, curval))
252  return rc | CSR_SUC_NO_CHANGE;
253 
254  if (initial)
255  table = mbtable_parse(initial);
256 
257  if (cdef->validator)
258  {
259  rc = cdef->validator(cs, cdef, (intptr_t) table, err);
260 
261  if (CSR_RESULT(rc) != CSR_SUCCESS)
262  {
263  mbtable_destroy(cs, &table, cdef);
264  return rc | CSR_INV_VALIDATOR;
265  }
266  }
267 
268  if (!table)
269  rc |= CSR_SUC_EMPTY;
270 
271  mbtable_destroy(cs, var, cdef);
272 
273  *(struct MbTable **) var = table;
274  return rc;
275 }
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
intptr_t initial
Initial value.
Definition: set.h:66
multibyte character table
Definition: mbtable.h:35
#define CSR_RESULT(x)
Definition: set.h:52
static void mbtable_destroy(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef)
Destroy an MbTable object - Implements ConfigSetType::destroy()
Definition: mbtable.c:95
#define CSR_SUC_EMPTY
Value is empty/unset.
Definition: set.h:42
#define CSR_SUC_NO_CHANGE
The value hasn&#39;t changed.
Definition: set.h:44
struct MbTable * mbtable_parse(const char *s)
Parse a multibyte string into a table.
Definition: mbtable.c:49
int(* validator)(const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Validate a config variable.
Definition: set.h:78
char * orig_str
Original string used to generate this object.
Definition: mbtable.h:37
#define CSR_INV_VALIDATOR
Value was rejected by the validator.
Definition: set.h:48
+ Here is the call graph for this function:

◆ mbtable_free()

void mbtable_free ( struct MbTable **  table)

Free an MbTable object.

Parameters
[out]tableMbTable to free

Definition at line 281 of file mbtable.c.

282 {
283  if (!table || !*table)
284  return;
285 
286  FREE(&(*table)->orig_str);
287  FREE(&(*table)->chars);
288  FREE(&(*table)->segmented_str);
289  FREE(table);
290 }
#define FREE(x)
Definition: memory.h:40
+ Here is the caller graph for this function:

Variable Documentation

◆ cst_mbtable

const struct ConfigSetType cst_mbtable
Initial value:
= {
"mbtable",
NULL,
NULL,
}
#define DT_MBTABLE
multibyte char table
Definition: types.h:34
static int mbtable_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err)
Set an MbTable by string - Implements ConfigSetType::string_set()
Definition: mbtable.c:107
static void mbtable_destroy(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef)
Destroy an MbTable object - Implements ConfigSetType::destroy()
Definition: mbtable.c:95
static int mbtable_native_set(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Set an MbTable config item by MbTable object - Implements ConfigSetType::native_set() ...
Definition: mbtable.c:198
static intptr_t mbtable_native_get(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Get an MbTable object from a MbTable config item - Implements ConfigSetType::native_get() ...
Definition: mbtable.c:227
static int mbtable_string_get(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *result)
Get a MbTable as a string - Implements ConfigSetType::string_get()
Definition: mbtable.c:159
static int mbtable_reset(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Reset an MbTable to its initial value - Implements ConfigSetType::reset()
Definition: mbtable.c:238

Config type representing a multi-byte table.

Definition at line 295 of file mbtable.c.