Merge pull request #42 from DerekCresswell/reformat-readme

Use custom types to help with clarity between raw and processed types
This commit is contained in:
CK Tan 2020-07-09 16:48:05 -07:00 committed by GitHub
commit d879b89737
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 113 additions and 81 deletions

View file

@ -1,83 +1,113 @@
# tomlc99
TOML in c99; v0.5.0 compliant.
# Usage
## Usage
Please see the `toml.h` file for details. What follows is a simple example that
parses this config file:
```
```toml
[server]
   host = "www.example.com"
host = "www.example.com"
port = 80
```
For each config param, the code first extracts a raw value and then
convert it to a string or integer depending on context.
The steps for getting values from our file is usually :
```
1. Parse the whole TOML file.
2. Get a single table from the file.
3. Find a value from the table.
4. Convert that value to the appropriate type (I.E. string, int).
5. Then, free up that memory if needed.
Below is an example of parsing the values from the example table.
1. Parse the whole TOML file.
```c
FILE* fp;
toml_table_t* conf;
toml_table_t* server;
const char* raw;
char* host;
int64_t port;
char errbuf[200];
/* open file and parse */
if (0 == (fp = fopen(FNAME, "r"))) {
/* Open the file. */
if (0 == (fp = fopen("path/to/file.toml", "r"))) {
return handle_error();
}
/* Run the file through the parser. */
conf = toml_parse_file(fp, errbuf, sizeof(errbuf));
fclose(fp);
if (0 == conf) {
return handle_error();
}
/* locate the [server] table */
fclose(fp);
/* Alternatively, use `toml_parse` which takes a string rather than a file. */
conf = toml_parse("A null terminated string that is TOML\0", errbuf, sizeof(errbuf);
```
2. Get a single table from the file.
```c
toml_table_t* server;
/* Locate the [server] table. */
if (0 == (server = toml_table_in(conf, "server"))) {
return handle_error();
}
```
/* extract host config value */
3. Find a value from the table.
4. Convert that value to the appropriate type (I.E. string, int).
```c
toml_raw_t raw;
char* host;
int64_t port;
/* Extract 'host' config value. */
if (0 == (raw = toml_raw_in(server, "host"))) {
return handle_error();
}
/* Convert the raw value into a string. */
if (toml_rtos(raw, &host)) {
return handle_error();
}
/* extract port config value */
/* Extract 'port' config value. */
if (0 == (raw = toml_raw_in(server, "port"))) {
return handle_error();
}
/* Convert the raw value into an int. */
if (toml_rtoi(raw, &port)) {
return handle_error();
}
/* done with conf */
toml_free(conf);
/* use host and port */
do_work(host, port);
/* clean up */
free(host);
```
5. Then, free up that memory if needed.
# Building
```c
/* Use `toml_free` on the table returned from `toml_parse[_file]`. */
toml_free(conf);
/* Free any values returned from `toml_rto*`. */
free(host);
free(port);
```
## Building
A normal *make* suffices. Alternately, you can also simply include the
`toml.c` and `toml.h` files in your project.
# Testing
## Testing
To test against the standard test set provided by BurntSushi/toml-test:
```
```sh
% make
% cd test1
% bash build.sh # do this once
@ -87,7 +117,7 @@ To test against the standard test set provided by BurntSushi/toml-test:
To test against the standard test set provided by iarna/toml:
```
```sh
% make
% cd test2
% bash build.sh # do this once

17
toml.c
View file

@ -1741,8 +1741,7 @@ const char* toml_key_in(const toml_table_t* tab, int keyidx)
return 0;
}
const char* toml_raw_in(const toml_table_t* tab, const char* key)
toml_raw_t toml_raw_in(const toml_table_t* tab, const char* key)
{
int i;
for (i = 0; i < tab->nkval; i++) {
@ -1773,7 +1772,7 @@ toml_table_t* toml_table_in(const toml_table_t* tab, const char* key)
return 0;
}
const char* toml_raw_at(const toml_array_t* arr, int idx)
toml_raw_t toml_raw_at(const toml_array_t* arr, int idx)
{
if (arr->kind != 'v')
return 0;
@ -1848,7 +1847,7 @@ toml_table_t* toml_table_at(const toml_array_t* arr, int idx)
}
int toml_rtots(const char* src_, toml_timestamp_t* ret)
int toml_rtots(toml_raw_t src_, toml_timestamp_t* ret)
{
if (! src_) return -1;
@ -1942,7 +1941,7 @@ int toml_rtots(const char* src_, toml_timestamp_t* ret)
/* Raw to boolean */
int toml_rtob(const char* src, int* ret_)
int toml_rtob(toml_raw_t src, int* ret_)
{
if (!src) return -1;
int dummy;
@ -1961,7 +1960,7 @@ int toml_rtob(const char* src, int* ret_)
/* Raw to integer */
int toml_rtoi(const char* src, int64_t* ret_)
int toml_rtoi(toml_raw_t src, int64_t* ret_)
{
if (!src) return -1;
@ -2024,7 +2023,7 @@ int toml_rtoi(const char* src, int64_t* ret_)
}
int toml_rtod_ex(const char* src, double* ret_, char* buf, int buflen)
int toml_rtod_ex(toml_raw_t src, double* ret_, char* buf, int buflen)
{
if (!src) return -1;
@ -2086,7 +2085,7 @@ int toml_rtod_ex(const char* src, double* ret_, char* buf, int buflen)
return (errno || *endp) ? -1 : 0;
}
int toml_rtod(const char* src, double* ret_)
int toml_rtod(toml_raw_t src, double* ret_)
{
char buf[100];
return toml_rtod_ex(src, ret_, buf, sizeof(buf));
@ -2095,7 +2094,7 @@ int toml_rtod(const char* src, double* ret_)
int toml_rtos(const char* src, char** ret)
int toml_rtos(toml_raw_t src, char** ret)
{
int multiline = 0;
const char* sp;

21
toml.h
View file

@ -39,6 +39,9 @@
typedef struct toml_table_t toml_table_t;
typedef struct toml_array_t toml_array_t;
/* A raw value, must be processed by toml_rto* before using. */
typedef const char* toml_raw_t;
/* Parse a file. Return a table on success, or 0 otherwise.
* Caller must toml_free(the-return-value) after use.
*/
@ -61,7 +64,7 @@ TOML_EXTERN void toml_free(toml_table_t* tab);
TOML_EXTERN const char* toml_key_in(const toml_table_t* tab, int keyidx);
/* Lookup table by key. Return the element or 0 if not found. */
TOML_EXTERN const char* toml_raw_in(const toml_table_t* tab, const char* key);
TOML_EXTERN toml_raw_t toml_raw_in(const toml_table_t* tab, const char* key);
TOML_EXTERN toml_array_t* toml_array_in(const toml_table_t* tab,
const char* key);
TOML_EXTERN toml_table_t* toml_table_in(const toml_table_t* tab,
@ -96,26 +99,26 @@ TOML_EXTERN int toml_table_ntab(const toml_table_t* tab);
TOML_EXTERN const char* toml_table_key(const toml_table_t* tab);
/* Deref array by index. Return the element at idx or 0 if out of range. */
TOML_EXTERN const char* toml_raw_at(const toml_array_t* arr, int idx);
TOML_EXTERN toml_raw_t toml_raw_at(const toml_array_t* arr, int idx);
TOML_EXTERN toml_array_t* toml_array_at(const toml_array_t* arr, int idx);
TOML_EXTERN toml_table_t* toml_table_at(const toml_array_t* arr, int idx);
/* Raw to String. Caller must call free(ret) after use.
* Return 0 on success, -1 otherwise.
*/
TOML_EXTERN int toml_rtos(const char* s, char** ret);
TOML_EXTERN int toml_rtos(toml_raw_t s, char** ret);
/* Raw to Boolean. Return 0 on success, -1 otherwise. */
TOML_EXTERN int toml_rtob(const char* s, int* ret);
TOML_EXTERN int toml_rtob(toml_raw_t s, int* ret);
/* Raw to Integer. Return 0 on success, -1 otherwise. */
TOML_EXTERN int toml_rtoi(const char* s, int64_t* ret);
TOML_EXTERN int toml_rtoi(toml_raw_t s, int64_t* ret);
/* Raw to Double. Return 0 on success, -1 otherwise. */
TOML_EXTERN int toml_rtod(const char* s, double* ret);
TOML_EXTERN int toml_rtod(toml_raw_t s, double* ret);
/* Same as toml_rtod, but return the sanitized double in string form as well */
TOML_EXTERN int toml_rtod_ex(const char* s, double* ret, char* buf, int buflen);
TOML_EXTERN int toml_rtod_ex(toml_raw_t s, double* ret, char* buf, int buflen);
/* Timestamp types. The year, month, day, hour, minute, second, z
* fields may be NULL if they are not relevant. e.g. In a DATE
@ -134,7 +137,7 @@ struct toml_timestamp_t {
};
/* Raw to Timestamp. Return 0 on success, -1 otherwise. */
TOML_EXTERN int toml_rtots(const char* s, toml_timestamp_t* ret);
TOML_EXTERN int toml_rtots(toml_raw_t s, toml_timestamp_t* ret);
/* misc */
TOML_EXTERN int toml_utf8_to_ucs(const char* orig, int len, int64_t* ret);