Add enhanced access methods

This commit is contained in:
CK Tan 2020-11-01 17:52:57 -08:00
parent 5be06807ad
commit 71a9fd9772
4 changed files with 157 additions and 22 deletions

View file

@ -30,6 +30,9 @@ toml_json: toml_json.c $(LIB)
toml_cat: toml_cat.c $(LIB) toml_cat: toml_cat.c $(LIB)
tomlcpp.o: tomlcpp.cpp
prefix ?= /usr/local prefix ?= /usr/local
install: all install: all

View file

@ -18,8 +18,7 @@ The steps for getting values from our file is usually :
1. Parse the whole TOML file. 1. Parse the whole TOML file.
2. Get a single table from the file. 2. Get a single table from the file.
3. Find a value from the table. 3. Find a value from the table.
4. Convert that value to the appropriate type, i.e., string, int, etc. 4. Then, free up that memory if needed.
5. Then, free up that memory if needed.
Below is an example of parsing the values from the example table. Below is an example of parsing the values from the example table.
@ -59,42 +58,35 @@ if (0 == (server = toml_table_in(conf, "server"))) {
``` ```
3. Find a value from the table. 3. Find a value from the table.
4. Convert that value to the appropriate type (I.E. string, int).
```c ```c
toml_raw_t raw;
char* host;
int64_t port;
/* Extract 'host' config value. */ /* Extract 'host' config value. */
if (0 == (raw = toml_raw_in(server, "host"))) { toml_access_t host = toml_string_in(server, "host");
if (!host.ok) {
toml_free(conf);
return handle_error(); return handle_error();
} }
/* Convert the raw value into a string. */ toml_access_t port = toml_int_in(server, "port");
if (toml_rtos(raw, &host)) { if (!port.ok) {
toml_free(conf);
free(host.u.s);
return handle_error(); return handle_error();
} }
/* Extract 'port' config value. */ printf("host %s\n", host.u.s);
if (0 == (raw = toml_raw_in(server, "port"))) { printf("port %d\n", port.u.i);
return handle_error();
}
/* Convert the raw value into an int. */
if (toml_rtoi(raw, &port)) {
return handle_error();
}
``` ```
5. Then, free up that memory if needed. 4. Then, free up that memory if needed.
```c ```c
/* Use `toml_free` on the table returned from `toml_parse[_file]`. */ /* Use `toml_free` on the table returned from `toml_parse[_file]`. */
toml_free(conf); toml_free(conf);
/* Free any values returned from `toml_rto*`. */ /* Free any string values returned from access functions. */
free(host); free(host.u.s);
``` ```
## Building ## Building

111
toml.c
View file

@ -2147,3 +2147,114 @@ int toml_rtos(toml_raw_t src, char** ret)
return *ret ? 0 : -1; return *ret ? 0 : -1;
} }
toml_access_t toml_string_at(const toml_array_t* arr, int idx)
{
toml_access_t ret;
memset(&ret, 0, sizeof(ret));
toml_raw_t raw = toml_raw_at(arr, idx);
if (raw) {
ret.ok = (0 == toml_rtos(raw, &ret.u.s));
}
return ret;
}
toml_access_t toml_bool_at(const toml_array_t* arr, int idx)
{
toml_access_t ret;
memset(&ret, 0, sizeof(ret));
toml_raw_t raw = toml_raw_at(arr, idx);
if (raw) {
ret.ok = (0 == toml_rtob(raw, &ret.u.b));
}
return ret;
}
toml_access_t toml_int_at(const toml_array_t* arr, int idx)
{
toml_access_t ret;
memset(&ret, 0, sizeof(ret));
toml_raw_t raw = toml_raw_at(arr, idx);
if (raw) {
ret.ok = (0 == toml_rtoi(raw, &ret.u.i));
}
return ret;
}
toml_access_t toml_double_at(const toml_array_t* arr, int idx)
{
toml_access_t ret;
memset(&ret, 0, sizeof(ret));
toml_raw_t raw = toml_raw_at(arr, idx);
if (raw) {
ret.ok = (0 == toml_rtod(raw, &ret.u.d));
}
return ret;
}
toml_access_t toml_timestamp_at(const toml_array_t* arr, int idx)
{
toml_access_t ret;
memset(&ret, 0, sizeof(ret));
toml_raw_t raw = toml_raw_at(arr, idx);
if (raw) {
ret.ok = (0 == toml_rtots(raw, &ret.u.ts));
}
return ret;
}
toml_access_t toml_string_in(const toml_table_t* arr, const char* key)
{
toml_access_t ret;
memset(&ret, 0, sizeof(ret));
toml_raw_t raw = toml_raw_in(arr, key);
if (raw) {
ret.ok = (0 == toml_rtos(raw, &ret.u.s));
}
return ret;
}
toml_access_t toml_bool_in(const toml_table_t* arr, const char* key)
{
toml_access_t ret;
memset(&ret, 0, sizeof(ret));
toml_raw_t raw = toml_raw_in(arr, key);
if (raw) {
ret.ok = (0 == toml_rtob(raw, &ret.u.b));
}
return ret;
}
toml_access_t toml_int_in(const toml_table_t* arr, const char* key)
{
toml_access_t ret;
memset(&ret, 0, sizeof(ret));
toml_raw_t raw = toml_raw_in(arr, key);
if (raw) {
ret.ok = (0 == toml_rtoi(raw, &ret.u.i));
}
return ret;
}
toml_access_t toml_double_in(const toml_table_t* arr, const char* key)
{
toml_access_t ret;
memset(&ret, 0, sizeof(ret));
toml_raw_t raw = toml_raw_in(arr, key);
if (raw) {
ret.ok = (0 == toml_rtod(raw, &ret.u.d));
}
return ret;
}
toml_access_t toml_timestamp_in(const toml_table_t* arr, const char* key)
{
toml_access_t ret;
memset(&ret, 0, sizeof(ret));
toml_raw_t raw = toml_raw_in(arr, key);
if (raw) {
ret.ok = (0 == toml_rtots(raw, &ret.u.ts));
}
return ret;
}

31
toml.h
View file

@ -36,8 +36,10 @@
#define TOML_EXTERN extern #define TOML_EXTERN extern
#endif #endif
typedef struct toml_timestamp_t toml_timestamp_t;
typedef struct toml_table_t toml_table_t; typedef struct toml_table_t toml_table_t;
typedef struct toml_array_t toml_array_t; typedef struct toml_array_t toml_array_t;
typedef struct toml_access_t toml_access_t;
/* A raw value, must be processed by toml_rto* before using. */ /* A raw value, must be processed by toml_rto* before using. */
typedef const char* toml_raw_t; typedef const char* toml_raw_t;
@ -124,7 +126,6 @@ TOML_EXTERN int toml_rtod_ex(toml_raw_t s, double* ret, char* buf, int buflen);
* fields may be NULL if they are not relevant. e.g. In a DATE * fields may be NULL if they are not relevant. e.g. In a DATE
* type, the hour, minute, second and z fields will be NULLs. * type, the hour, minute, second and z fields will be NULLs.
*/ */
typedef struct toml_timestamp_t toml_timestamp_t;
struct toml_timestamp_t { struct toml_timestamp_t {
struct { /* internal. do not use. */ struct { /* internal. do not use. */
int year, month, day; int year, month, day;
@ -139,10 +140,38 @@ struct toml_timestamp_t {
/* Raw to Timestamp. Return 0 on success, -1 otherwise. */ /* Raw to Timestamp. Return 0 on success, -1 otherwise. */
TOML_EXTERN int toml_rtots(toml_raw_t s, toml_timestamp_t* ret); TOML_EXTERN int toml_rtots(toml_raw_t s, toml_timestamp_t* ret);
/* Enhanced access methods */
struct toml_access_t {
int ok;
union {
char* s; /* string value. s must be freed after use */
int b; /* bool value */
int64_t i; /* int value */
double d; /* double value */
toml_timestamp_t ts;
} u;
};
TOML_EXTERN toml_access_t toml_string_at(const toml_array_t* arr, int idx);
TOML_EXTERN toml_access_t toml_bool_at(const toml_array_t* arr, int idx);
TOML_EXTERN toml_access_t toml_int_at(const toml_array_t* arr, int idx);
TOML_EXTERN toml_access_t toml_double_at(const toml_array_t* arr, int idx);
TOML_EXTERN toml_access_t toml_timestamp_at(const toml_array_t* arr, int idx);
TOML_EXTERN toml_access_t toml_string_in(const toml_table_t* arr, const char* key);
TOML_EXTERN toml_access_t toml_bool_in(const toml_table_t* arr, const char* key);
TOML_EXTERN toml_access_t toml_int_in(const toml_table_t* arr, const char* key);
TOML_EXTERN toml_access_t toml_double_in(const toml_table_t* arr, const char* key);
TOML_EXTERN toml_access_t toml_timestamp_in(const toml_table_t* arr, const char* key);
/* misc */ /* misc */
TOML_EXTERN int toml_utf8_to_ucs(const char* orig, int len, int64_t* ret); TOML_EXTERN int toml_utf8_to_ucs(const char* orig, int len, int64_t* ret);
TOML_EXTERN int toml_ucs_to_utf8(int64_t code, char buf[6]); TOML_EXTERN int toml_ucs_to_utf8(int64_t code, char buf[6]);
TOML_EXTERN void toml_set_memutil(void* (*xxmalloc)(size_t), TOML_EXTERN void toml_set_memutil(void* (*xxmalloc)(size_t),
void (*xxfree)(void*)); void (*xxfree)(void*));
#endif /* TOML_H */ #endif /* TOML_H */