mirror of https://github.com/neutrinolabs/xrdp
Merge commit 'f6e95526498ad92644b3f2689636f33be108049b' as 'third_party/tomlc99'
This commit is contained in:
commit
ee1ea91eb1
|
@ -0,0 +1,14 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = false
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{c,h}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
|
@ -0,0 +1,38 @@
|
|||
*~
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
toml_cat
|
||||
toml_json
|
||||
toml_sample
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
|
@ -0,0 +1,22 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) CK Tan
|
||||
https://github.com/cktan/tomlc99
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,50 @@
|
|||
prefix ?= /usr/local
|
||||
HFILES = toml.h
|
||||
CFILES = toml.c
|
||||
OBJ = $(CFILES:.c=.o)
|
||||
EXEC = toml_json toml_cat toml_sample
|
||||
PCFILE = libtoml.pc
|
||||
|
||||
CFLAGS = -std=c99 -Wall -Wextra -fpic
|
||||
LIB_VERSION = 1.0
|
||||
LIB = libtoml.a
|
||||
LIB_SHARED = libtoml.so.$(LIB_VERSION)
|
||||
|
||||
# to compile for debug: make DEBUG=1
|
||||
# to compile for no debug: make
|
||||
ifdef DEBUG
|
||||
CFLAGS += -O0 -g
|
||||
else
|
||||
CFLAGS += -O2 -DNDEBUG
|
||||
endif
|
||||
|
||||
|
||||
all: $(LIB) $(LIB_SHARED) $(EXEC)
|
||||
|
||||
*.o: $(HFILES)
|
||||
|
||||
libtoml.a: toml.o
|
||||
ar -rcs $@ $^
|
||||
|
||||
libtoml.so.$(LIB_VERSION): toml.o
|
||||
$(CC) -shared -o $@ $^
|
||||
|
||||
$(EXEC): $(LIB)
|
||||
|
||||
install: all
|
||||
install -d ${prefix}/include ${prefix}/lib
|
||||
install toml.h ${prefix}/include
|
||||
install $(LIB) ${prefix}/lib
|
||||
install $(LIB_SHARED) ${prefix}/lib
|
||||
ifeq "$(prefix)" "/usr/local"
|
||||
install $(PCFILE) /usr/local/lib/pkgconfig
|
||||
endif
|
||||
|
||||
clean:
|
||||
rm -f *.o $(EXEC) $(LIB) $(LIB_SHARED)
|
||||
|
||||
|
||||
format:
|
||||
clang-format -i $(shell find . -name '*.[ch]')
|
||||
|
||||
.PHONY: all clean install format
|
|
@ -0,0 +1,194 @@
|
|||
# tomlc99
|
||||
|
||||
TOML in c99; v1.0 compliant.
|
||||
|
||||
If you are looking for a C++ library, you might try this wrapper: [https://github.com/cktan/tomlcpp](https://github.com/cktan/tomlcpp).
|
||||
|
||||
* Compatible with [TOML v1.0.0](https://toml.io/en/v1.0.0).
|
||||
* Tested with multiple test suites, including
|
||||
[BurntSushi/toml-test](https://github.com/BurntSushi/toml-test) and
|
||||
[iarna/toml-spec-tests](https://github.com/iarna/toml-spec-tests).
|
||||
* Provides very simple and intuitive interface.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Please see the `toml.h` file for details. The following is a simple example that
|
||||
parses this config file:
|
||||
|
||||
```toml
|
||||
[server]
|
||||
host = "www.example.com"
|
||||
port = [ 8080, 8181, 8282 ]
|
||||
```
|
||||
|
||||
These are the usual steps for getting values from a file:
|
||||
|
||||
1. Parse the TOML file.
|
||||
2. Traverse and locate a table in TOML.
|
||||
3. Extract values from the table.
|
||||
4. Free up allocated memory.
|
||||
|
||||
Below is an example of parsing the values from the example table.
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include "toml.h"
|
||||
|
||||
static void error(const char* msg, const char* msg1)
|
||||
{
|
||||
fprintf(stderr, "ERROR: %s%s\n", msg, msg1?msg1:"");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
FILE* fp;
|
||||
char errbuf[200];
|
||||
|
||||
// 1. Read and parse toml file
|
||||
fp = fopen("sample.toml", "r");
|
||||
if (!fp) {
|
||||
error("cannot open sample.toml - ", strerror(errno));
|
||||
}
|
||||
|
||||
toml_table_t* conf = toml_parse_file(fp, errbuf, sizeof(errbuf));
|
||||
fclose(fp);
|
||||
|
||||
if (!conf) {
|
||||
error("cannot parse - ", errbuf);
|
||||
}
|
||||
|
||||
// 2. Traverse to a table.
|
||||
toml_table_t* server = toml_table_in(conf, "server");
|
||||
if (!server) {
|
||||
error("missing [server]", "");
|
||||
}
|
||||
|
||||
// 3. Extract values
|
||||
toml_datum_t host = toml_string_in(server, "host");
|
||||
if (!host.ok) {
|
||||
error("cannot read server.host", "");
|
||||
}
|
||||
|
||||
toml_array_t* portarray = toml_array_in(server, "port");
|
||||
if (!portarray) {
|
||||
error("cannot read server.port", "");
|
||||
}
|
||||
|
||||
printf("host: %s\n", host.u.s);
|
||||
printf("port: ");
|
||||
for (int i = 0; ; i++) {
|
||||
toml_datum_t port = toml_int_at(portarray, i);
|
||||
if (!port.ok) break;
|
||||
printf("%d ", (int)port.u.i);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// 4. Free memory
|
||||
free(host.u.s);
|
||||
toml_free(conf);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
#### Accessing Table Content
|
||||
|
||||
TOML tables are dictionaries where lookups are done using string keys. In
|
||||
general, all access functions on tables are named `toml_*_in(...)`.
|
||||
|
||||
In the normal case, you know the key and its content type, and retrievals can be done
|
||||
using one of these functions:
|
||||
```c
|
||||
toml_string_in(tab, key);
|
||||
toml_bool_in(tab, key);
|
||||
toml_int_in(tab, key);
|
||||
toml_double_in(tab, key);
|
||||
toml_timestamp_in(tab, key);
|
||||
toml_table_in(tab, key);
|
||||
toml_array_in(tab, key);
|
||||
```
|
||||
|
||||
You can also interrogate the keys in a table using an integer index:
|
||||
```c
|
||||
toml_table_t* tab = toml_parse_file(...);
|
||||
for (int i = 0; ; i++) {
|
||||
const char* key = toml_key_in(tab, i);
|
||||
if (!key) break;
|
||||
printf("key %d: %s\n", i, key);
|
||||
}
|
||||
```
|
||||
|
||||
#### Accessing Array Content
|
||||
|
||||
TOML arrays can be deref-ed using integer indices. In general, all access methods on arrays are named `toml_*_at()`.
|
||||
|
||||
To obtain the size of an array:
|
||||
```c
|
||||
int size = toml_array_nelem(arr);
|
||||
```
|
||||
|
||||
To obtain the content of an array, use a valid index and call one of these functions:
|
||||
```c
|
||||
toml_string_at(arr, idx);
|
||||
toml_bool_at(arr, idx);
|
||||
toml_int_at(arr, idx);
|
||||
toml_double_at(arr, idx);
|
||||
toml_timestamp_at(arr, idx);
|
||||
toml_table_at(arr, idx);
|
||||
toml_array_at(arr, idx);
|
||||
```
|
||||
|
||||
#### toml_datum_t
|
||||
|
||||
Some `toml_*_at` and `toml_*_in` functions return a toml_datum_t
|
||||
structure. The `ok` flag in the structure indicates if the function
|
||||
call was successful. If so, you may proceed to read the value
|
||||
corresponding to the type of the content.
|
||||
|
||||
For example:
|
||||
```
|
||||
toml_datum_t host = toml_string_in(tab, "host");
|
||||
if (host.ok) {
|
||||
printf("host: %s\n", host.u.s);
|
||||
free(host.u.s); /* FREE applies to string and timestamp types only */
|
||||
}
|
||||
```
|
||||
|
||||
** IMPORTANT: if the accessed value is a string or a timestamp, you must call `free(datum.u.s)` or `free(datum.u.ts)` respectively after usage. **
|
||||
|
||||
## Building and installing
|
||||
|
||||
A normal *make* suffices. You can also simply include the
|
||||
`toml.c` and `toml.h` files in your project.
|
||||
|
||||
Invoking `make install` will install the header and library files into
|
||||
/usr/local/{include,lib}.
|
||||
|
||||
Alternatively, specify `make install prefix=/a/file/path` to install into
|
||||
/a/file/path/{include,lib}.
|
||||
|
||||
## Testing
|
||||
|
||||
To test against the standard test set provided by BurntSushi/toml-test:
|
||||
|
||||
```sh
|
||||
% make
|
||||
% cd test1
|
||||
% bash build.sh # do this once
|
||||
% bash run.sh # this will run the test suite
|
||||
```
|
||||
|
||||
|
||||
To test against the standard test set provided by iarna/toml:
|
||||
|
||||
```sh
|
||||
% make
|
||||
% cd test2
|
||||
% bash build.sh # do this once
|
||||
% bash run.sh # this will run the test suite
|
||||
```
|
|
@ -0,0 +1,11 @@
|
|||
prefix=/usr/local
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: libtoml
|
||||
URL: https://github.com/cktan/tomlc99/
|
||||
Description: TOML C library in c99.
|
||||
Version: v1.0
|
||||
Libs: -L${libdir} -ltoml
|
||||
Cflags: -I${includedir}
|
|
@ -0,0 +1,3 @@
|
|||
[server]
|
||||
host = "example.com"
|
||||
port = [ 8080, 8181, 8282 ]
|
|
@ -0,0 +1 @@
|
|||
/*.out
|
|
@ -0,0 +1,15 @@
|
|||
rm -f *.out
|
||||
for i in *.toml; do
|
||||
echo -n $i
|
||||
../toml_cat $i >& $i.out
|
||||
if [ -f $i.res ]; then
|
||||
if $(diff $i.out $i.res >& /dev/null); then
|
||||
echo " [OK]"
|
||||
else
|
||||
echo " [FAILED]"
|
||||
fi
|
||||
else
|
||||
echo " [?????]"
|
||||
fi
|
||||
|
||||
done
|
|
@ -0,0 +1,13 @@
|
|||
integers = [ 1, 2, 3 ]
|
||||
colors = [ "red", "yellow", "green" ]
|
||||
nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
|
||||
nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
|
||||
string_array = [ "all", 'strings', """are the same""", '''type''' ]
|
||||
|
||||
# Mixed-type arrays are allowed
|
||||
numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
|
||||
contributors = [
|
||||
"Foo Bar <foo@example.com>",
|
||||
{ name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
|
||||
]
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
integers = [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
],
|
||||
colors = [
|
||||
"red",
|
||||
"yellow",
|
||||
"green",
|
||||
],
|
||||
nested_arrays_of_ints = [
|
||||
[
|
||||
1,
|
||||
2,
|
||||
],
|
||||
[
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
],
|
||||
],
|
||||
nested_mixed_array = [
|
||||
[
|
||||
1,
|
||||
2,
|
||||
],
|
||||
[
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
],
|
||||
],
|
||||
string_array = [
|
||||
"all",
|
||||
"strings",
|
||||
"are the same",
|
||||
"type",
|
||||
],
|
||||
numbers = [
|
||||
0.100000,
|
||||
0.200000,
|
||||
0.500000,
|
||||
1,
|
||||
2,
|
||||
5,
|
||||
],
|
||||
contributors = [
|
||||
"Foo Bar <foo@example.com>",
|
||||
{
|
||||
name = "Baz Qux",
|
||||
email = "bazqux@example.com",
|
||||
url = "https://example.com/bazqux",
|
||||
},
|
||||
],
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
integers2 = [
|
||||
1, 2, 3
|
||||
]
|
||||
|
||||
integers3 = [
|
||||
1,
|
||||
2, # this is ok
|
||||
]
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
integers2 = [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
],
|
||||
integers3 = [
|
||||
1,
|
||||
2,
|
||||
],
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
[[products]]
|
||||
name = "Hammer"
|
||||
sku = 738594937
|
||||
|
||||
[[products]] # empty table within the array
|
||||
|
||||
[[products]]
|
||||
name = "Nail"
|
||||
sku = 284758393
|
||||
|
||||
color = "gray"
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
products = [
|
||||
{
|
||||
name = "Hammer",
|
||||
sku = 738594937,
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
name = "Nail",
|
||||
sku = 284758393,
|
||||
color = "gray",
|
||||
},
|
||||
],
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
[[fruits]]
|
||||
name = "apple"
|
||||
|
||||
[fruits.physical] # subtable
|
||||
color = "red"
|
||||
shape = "round"
|
||||
|
||||
[[fruits.varieties]] # nested array of tables
|
||||
name = "red delicious"
|
||||
|
||||
[[fruits.varieties]]
|
||||
name = "granny smith"
|
||||
|
||||
|
||||
[[fruits]]
|
||||
name = "banana"
|
||||
|
||||
[[fruits.varieties]]
|
||||
name = "plantain"
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
fruits = [
|
||||
{
|
||||
name = "apple",
|
||||
varieties = [
|
||||
{
|
||||
name = "red delicious",
|
||||
},
|
||||
{
|
||||
name = "granny smith",
|
||||
},
|
||||
],
|
||||
physical = {
|
||||
color = "red",
|
||||
shape = "round",
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "banana",
|
||||
varieties = [
|
||||
{
|
||||
name = "plantain",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
# INVALID TOML DOC
|
||||
[fruit.physical] # subtable, but to which parent element should it belong?
|
||||
color = "red"
|
||||
shape = "round"
|
||||
|
||||
[[fruit]] # parser must throw an error upon discovering that "fruit" is
|
||||
# an array rather than a table
|
||||
name = "apple"
|
|
@ -0,0 +1 @@
|
|||
ERROR: line 6: key exists
|
|
@ -0,0 +1,4 @@
|
|||
# INVALID TOML DOC
|
||||
fruits = []
|
||||
|
||||
[[fruits]] # Not allowed
|
|
@ -0,0 +1 @@
|
|||
ERROR: line 4: array mismatch
|
|
@ -0,0 +1,11 @@
|
|||
# INVALID TOML DOC
|
||||
[[fruits]]
|
||||
name = "apple"
|
||||
|
||||
[[fruits.varieties]]
|
||||
name = "red delicious"
|
||||
|
||||
# INVALID: This table conflicts with the previous array of tables
|
||||
[fruits.varieties]
|
||||
name = "granny smith"
|
||||
|
|
@ -0,0 +1 @@
|
|||
ERROR: line 9: key exists
|
|
@ -0,0 +1,14 @@
|
|||
# INVALID TOML DOC
|
||||
[[fruits]]
|
||||
name = "apple"
|
||||
|
||||
[[fruits.varieties]]
|
||||
name = "red delicious"
|
||||
|
||||
[fruits.physical]
|
||||
color = "red"
|
||||
shape = "round"
|
||||
|
||||
# INVALID: This array of tables conflicts with the previous table
|
||||
[[fruits.physical]]
|
||||
color = "green"
|
|
@ -0,0 +1 @@
|
|||
ERROR: line 13: key exists
|
|
@ -0,0 +1,3 @@
|
|||
points = [ { x = 1, y = 2, z = 3 },
|
||||
{ x = 7, y = 8, z = 9 },
|
||||
{ x = 2, y = 4, z = 8 } ]
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
points = [
|
||||
{
|
||||
x = 1,
|
||||
y = 2,
|
||||
z = 3,
|
||||
},
|
||||
{
|
||||
x = 7,
|
||||
y = 8,
|
||||
z = 9,
|
||||
},
|
||||
{
|
||||
x = 2,
|
||||
y = 4,
|
||||
z = 8,
|
||||
},
|
||||
],
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
bool1 = true
|
||||
bool2 = false
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
bool1 = true,
|
||||
bool2 = false,
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
# This is a full-line comment
|
||||
key = "value" # This is a comment at the end of a line
|
||||
another = "# This is not a comment"
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
key = "value",
|
||||
another = "# This is not a comment",
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
# fractional
|
||||
flt1 = +1.0
|
||||
flt2 = 3.1415
|
||||
flt3 = -0.01
|
||||
|
||||
# exponent
|
||||
flt4 = 5e+22
|
||||
flt5 = 1e06
|
||||
flt6 = -2E-2
|
||||
|
||||
# both
|
||||
flt7 = 6.626e-34
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
flt1 = 1.000000,
|
||||
flt2 = 3.141500,
|
||||
flt3 = -0.010000,
|
||||
flt4 = 49999999999999995805696.000000,
|
||||
flt5 = 1000000.000000,
|
||||
flt6 = -0.020000,
|
||||
flt7 = 0.000000,
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
invalid_float_1 = .7
|
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
ERROR: unable to decode value in table
|
|
@ -0,0 +1,2 @@
|
|||
invalid_float_2 = 7.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
ERROR: unable to decode value in table
|
|
@ -0,0 +1 @@
|
|||
invalid_float_3 = 3.e+20
|
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
ERROR: unable to decode value in table
|
|
@ -0,0 +1 @@
|
|||
flt8 = 224_617.445_991_228
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
flt8 = 224617.445991,
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
# infinity
|
||||
sf1 = inf # positive infinity
|
||||
sf2 = +inf # positive infinity
|
||||
sf3 = -inf # negative infinity
|
||||
|
||||
# not a number
|
||||
sf4 = nan # actual sNaN/qNaN encoding is implementation-specific
|
||||
sf5 = +nan # same as `nan`
|
||||
sf6 = -nan # valid, actual encoding is implementation-specific
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
sf1 = inf,
|
||||
sf2 = inf,
|
||||
sf3 = -inf,
|
||||
sf4 = nan,
|
||||
sf5 = nan,
|
||||
sf6 = nan,
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
name = { first = "Tom", last = "Preston-Werner" }
|
||||
point = { x = 1, y = 2 }
|
||||
animal = { type.name = "pug" }
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
name = {
|
||||
first = "Tom",
|
||||
last = "Preston-Werner",
|
||||
},
|
||||
point = {
|
||||
x = 1,
|
||||
y = 2,
|
||||
},
|
||||
animal = {
|
||||
type = {
|
||||
name = "pug",
|
||||
},
|
||||
},
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
[product]
|
||||
type = { name = "Nail" }
|
||||
type.edible = false # INVALID
|
|
@ -0,0 +1 @@
|
|||
ERROR: line 3: cannot insert new entry into existing table
|
|
@ -0,0 +1,3 @@
|
|||
[product]
|
||||
type.name = "Nail"
|
||||
type = { edible = false } # INVALID
|
|
@ -0,0 +1 @@
|
|||
ERROR: line 3: key exists
|
|
@ -0,0 +1,9 @@
|
|||
int1 = +99
|
||||
int2 = 42
|
||||
int3 = 0
|
||||
int4 = -17
|
||||
int5 = 1_000
|
||||
int6 = 5_349_221
|
||||
int7 = 53_49_221 # Indian number system grouping
|
||||
int8 = 1_2_3_4_5 # VALID but discouraged
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
int1 = 99,
|
||||
int2 = 42,
|
||||
int3 = 0,
|
||||
int4 = -17,
|
||||
int5 = 1000,
|
||||
int6 = 5349221,
|
||||
int7 = 5349221,
|
||||
int8 = 12345,
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
# hexadecimal with prefix `0x`
|
||||
hex1 = 0xDEADBEEF
|
||||
hex2 = 0xdeadbeef
|
||||
hex3 = 0xdead_beef
|
||||
|
||||
# octal with prefix `0o`
|
||||
oct1 = 0o01234567
|
||||
oct2 = 0o755 # useful for Unix file permissions
|
||||
|
||||
# binary with prefix `0b`
|
||||
bin1 = 0b11010110
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
hex1 = 3735928559,
|
||||
hex2 = 3735928559,
|
||||
hex3 = 3735928559,
|
||||
oct1 = 342391,
|
||||
oct2 = 493,
|
||||
bin1 = 214,
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
key = "value"
|
||||
bare_key = "value"
|
||||
bare-key = "value"
|
||||
1234 = "value"
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
key = "value",
|
||||
bare_key = "value",
|
||||
bare-key = "value",
|
||||
1234 = "value",
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
"127.0.0.1" = "value"
|
||||
"character encoding" = "value"
|
||||
"ʎǝʞ" = "value"
|
||||
'key2' = "value"
|
||||
'quoted "value"' = "value"
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
127.0.0.1 = "value",
|
||||
character encoding = "value",
|
||||
ʎǝʞ = "value",
|
||||
key2 = "value",
|
||||
quoted "value" = "value",
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
= "no key name" # INVALID
|
|
@ -0,0 +1 @@
|
|||
ERROR: line 1: syntax error
|
|
@ -0,0 +1 @@
|
|||
"" = "blank" # VALID but discouraged
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
= "blank",
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
name = "Orange"
|
||||
physical.color = "orange"
|
||||
physical.shape = "round"
|
||||
site."google.com" = true
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
name = "Orange",
|
||||
physical = {
|
||||
color = "orange",
|
||||
shape = "round",
|
||||
},
|
||||
site = {
|
||||
google.com = true,
|
||||
},
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fruit.name = "banana" # this is best practice
|
||||
fruit. color = "yellow" # same as fruit.color
|
||||
fruit . flavor = "banana" # same as fruit.flavor
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
fruit = {
|
||||
name = "banana",
|
||||
color = "yellow",
|
||||
flavor = "banana",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
# DO NOT DO THIS
|
||||
name = "Tom"
|
||||
name = "Pradyun"
|
|
@ -0,0 +1 @@
|
|||
ERROR: line 3: key exists
|
|
@ -0,0 +1,3 @@
|
|||
# THIS WILL NOT WORK
|
||||
spelling = "favorite"
|
||||
"spelling" = "favourite"
|
|
@ -0,0 +1 @@
|
|||
ERROR: line 3: key exists
|
|
@ -0,0 +1,5 @@
|
|||
# This makes the key "fruit" into a table.
|
||||
fruit.apple.smooth = true
|
||||
|
||||
# So then you can add to the table "fruit" like so:
|
||||
fruit.orange = 2
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
fruit = {
|
||||
orange = 2,
|
||||
apple = {
|
||||
smooth = true,
|
||||
},
|
||||
},
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
# THE FOLLOWING IS INVALID
|
||||
|
||||
# This defines the value of fruit.apple to be an integer.
|
||||
fruit.apple = 1
|
||||
|
||||
# But then this treats fruit.apple like it's a table.
|
||||
# You can't turn an integer into a table.
|
||||
fruit.apple.smooth = true
|
|
@ -0,0 +1 @@
|
|||
ERROR: line 8: key exists
|
|
@ -0,0 +1,10 @@
|
|||
# VALID BUT DISCOURAGED
|
||||
|
||||
apple.type = "fruit"
|
||||
orange.type = "fruit"
|
||||
|
||||
apple.skin = "thin"
|
||||
orange.skin = "thick"
|
||||
|
||||
apple.color = "red"
|
||||
orange.color = "orange"
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
apple = {
|
||||
type = "fruit",
|
||||
skin = "thin",
|
||||
color = "red",
|
||||
},
|
||||
orange = {
|
||||
type = "fruit",
|
||||
skin = "thick",
|
||||
color = "orange",
|
||||
},
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
# RECOMMENDED
|
||||
|
||||
apple.type = "fruit"
|
||||
apple.skin = "thin"
|
||||
apple.color = "red"
|
||||
|
||||
orange.type = "fruit"
|
||||
orange.skin = "thick"
|
||||
orange.color = "orange"
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
apple = {
|
||||
type = "fruit",
|
||||
skin = "thin",
|
||||
color = "red",
|
||||
},
|
||||
orange = {
|
||||
type = "fruit",
|
||||
skin = "thick",
|
||||
color = "orange",
|
||||
},
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
3.14159 = "pi"
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
3 = {
|
||||
14159 = "pi",
|
||||
},
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
key = "value"
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
key = "value",
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
key = # INVALID
|
|
@ -0,0 +1 @@
|
|||
ERROR: line 1: syntax error
|
|
@ -0,0 +1 @@
|
|||
first = "Tom" last = "Preston-Werner" # INVALID
|
|
@ -0,0 +1 @@
|
|||
ERROR: line 1: extra chars after value
|
|
@ -0,0 +1 @@
|
|||
str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
str = "I'm a string. \"You can quote me\". Name\tJos\0xc3\0xa9\nLocation\tSF.",
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
str1 = """
|
||||
Roses are red
|
||||
Violets are blue"""
|
||||
|
||||
# On a Unix system, the above multi-line string will most likely be the same as:
|
||||
str2 = "Roses are red\nViolets are blue"
|
||||
|
||||
# On a Windows system, it will most likely be equivalent to:
|
||||
str3 = "Roses are red\r\nViolets are blue"
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
str1 = "Roses are red\nViolets are blue",
|
||||
str2 = "Roses are red\nViolets are blue",
|
||||
str3 = "Roses are red\r\nViolets are blue",
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
# The following strings are byte-for-byte equivalent:
|
||||
str1 = "The quick brown fox jumps over the lazy dog."
|
||||
|
||||
str2 = """
|
||||
The quick brown \
|
||||
|
||||
|
||||
fox jumps over \
|
||||
the lazy dog."""
|
||||
|
||||
str3 = """\
|
||||
The quick brown \
|
||||
fox jumps over \
|
||||
the lazy dog.\
|
||||
"""
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
str1 = "The quick brown fox jumps over the lazy dog.",
|
||||
str2 = "The quick brown fox jumps over the lazy dog.",
|
||||
str3 = "The quick brown fox jumps over the lazy dog.",
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
str4 = """Here are two quotation marks: "". Simple enough."""
|
||||
# str5 = """Here are three quotation marks: """.""" # INVALID
|
||||
str5 = """Here are three quotation marks: ""\"."""
|
||||
str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\"."""
|
||||
|
||||
# "This," she said, "is just a pointless statement."
|
||||
str7 = """"This," she said, "is just a pointless statement.""""
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
str4 = "Here are two quotation marks: \"\". Simple enough.",
|
||||
str5 = "Here are three quotation marks: \"\"\".",
|
||||
str6 = "Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".",
|
||||
str7 = "\"This,\" she said, \"is just a pointless statement.\"",
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
# What you see is what you get.
|
||||
winpath = 'C:\Users\nodejs\templates'
|
||||
winpath2 = '\\ServerX\admin$\system32\'
|
||||
quoted = 'Tom "Dubs" Preston-Werner'
|
||||
regex = '<\i\c*\s*>'
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
winpath = "C:\\Users\\nodejs\\templates",
|
||||
winpath2 = "\\\\ServerX\\admin$\\system32\\",
|
||||
quoted = "Tom \"Dubs\" Preston-Werner",
|
||||
regex = "<\\i\\c*\\s*>",
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
regex2 = '''I [dw]on't need \d{2} apples'''
|
||||
lines = '''
|
||||
The first newline is
|
||||
trimmed in raw strings.
|
||||
All other whitespace
|
||||
is preserved.
|
||||
'''
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
regex2 = "I [dw]on't need \\d{2} apples",
|
||||
lines = "The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n",
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
quot15 = '''Here are fifteen quotation marks: """""""""""""""'''
|
||||
|
||||
# 'That,' she said, 'is still pointless.'
|
||||
str = ''''That,' she said, 'is still pointless.''''
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
quot15 = "Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"",
|
||||
str = "'That,' she said, 'is still pointless.'",
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
# apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID
|
||||
apos15 = "Here are fifteen apostrophes: '''''''''''''''"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue