Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial TINI parser implementation #5

Merged
merged 32 commits into from
Jan 10, 2024
Merged

Initial TINI parser implementation #5

merged 32 commits into from
Jan 10, 2024

Conversation

lsileoni
Copy link
Collaborator

@lsileoni lsileoni commented Jan 6, 2024

Work done

This is the primary implementation of a parser to the TINI format, a format, which is somewhere between INI and TOML.

The basic premise of the format goes as follows:

You have context switches, which determine at which point in the tree you are inserting and how. Then you have insertions to those contexts via simple key-value insertion.

As an example

[a.b.c] first checks if a map 'a' exists, if it doesn't, it will create it and repeat the process until all the maps have been created. This means the "context" of the parser points at map c, which is nested inside of b and a. Then any subsequent key-value pairs in the following lines will append to that context.

So if we have

[a.b]
key=value
one=two

Maps a, b will be created and map b will contain the aforementioned two key value pairs.

TINI also has vectors. Vectors are denoted via two square brackets.
[[vector]]
A repetition of a vector with the same name denotes a new map appended to the vector's context. This can be seen in the servers example within the main.cpp file.

This statment creates a vector of TiniNodes. TiniNodes are effectively an optional type of one of the following types:

std::vector<TiniNode *> *_vectorValue;
std::map<std::string, TiniNode *> *_mapValue;
std::string *_stringValue;

Within the TiniNode class, they are tagged by an enum. Before TiniNodes are created at all, there's a validation loop, that runs on the input, which checks for errors in the configuration and gives detailed line by line analysis on where those errors are and what category they are.

The basic validation loop

image

Demonstration

Input:

qdqjd;][d;][;e]1[]
[[spamvector]]
    key=value
    value=key
[d dijqwdoijqw oidq- spamvector]]
    key=value
    value=key
[abc[=[[][][][]
    key=value
    value=key
[[spa..mvector]]
    key=value
    value=key
    [key=value]

[a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u
    key
    value=key

    key

Output:

                 v
qdqjd;][d;][;e]1[]
Error: Only Key Provided at R: 1 C: 18

                 v
[ddijqwdoijqwoidq-spamvector]]
Error: Unexpected Token at R: 5 C: 18

    v
[abc[=[[][][][]
Error: Unexpected Token at R: 8 C: 5

      v
[[spa..mvector]]
Error: Unexpected Token at R: 11 C: 7

    v
[key=value]
Error: Unexpected Token at R: 14 C: 5

                                         v
[a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u
Error: Brackets Imbalanced at R: 16 C: 42

  v
key
Error: Only Key Provided at R: 17 C: 3

  v
key
Error: Only Key Provided at R: 20 C: 3

Found a total of 8 errors in the configuration!
[error] TiniTree: constructTree: FATAL (in ./src/main.cpp:45)

Usage of TINI in code

I provided an example usage of TINI in the main.cpp file.

TiniTree tree; // Creates an instance of the TINI tree (this can throw)
TiniNode& root = tree.getRoot(); // Once the tree has been created, you can get a reference to the root TiniNode

// With how the TiniNode is structured, you can recursively print and traverse any TiniNode from top down easily.

root.printContents(0, ""); // This prints the whole tree

root["a"]["b"]["c"].printContents(0, ""); // This prints the contents of the "c" map.

// This is how you print the maps of a vector.  for example one that contains servers
for (auto n : root["http"]["servers"].getVectorValue())
    n->printContents(0, "");

// This is how you get access to a single value of a key-value pair in TINI
auto v = root["root_map_value"].getStringValue();

@lsileoni lsileoni requested review from alcjzk and lanximaomao January 6, 2024 17:59
Copy link
Owner

@alcjzk alcjzk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks mostly good! Memory management needs a couple fixes in places

src/TiniNode.cpp Outdated Show resolved Hide resolved
src/TiniNode.cpp Outdated Show resolved Hide resolved
src/TiniNode.hpp Show resolved Hide resolved
src/TiniTree.cpp Outdated Show resolved Hide resolved
src/TiniTree.hpp Outdated Show resolved Hide resolved
src/TiniTree.hpp Outdated Show resolved Hide resolved
src/TiniTree.hpp Show resolved Hide resolved
src/TiniTree.hpp Outdated Show resolved Hide resolved
src/TiniTree.hpp Outdated Show resolved Hide resolved
Copy link
Owner

@alcjzk alcjzk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionally looks good to me, so I'll approve this :) There's a couple minor changes that could be made, but that's up to you.

The move assigment/constructor implementations also don't really utilize the move semantic to it's potential, but looks functionally correct. std::exchange is a pretty nice way to utilize the semantics a little better, the page has decent examples too

src/TiniTree.hpp Outdated Show resolved Hide resolved
src/TiniNode.cpp Outdated Show resolved Hide resolved
Copy link
Collaborator

@lanximaomao lanximaomao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will approve it first.

@lsileoni
Copy link
Collaborator Author

Valgrind shows no leaks, static analysis from scan-build shows no issues, merging.

@lsileoni lsileoni merged commit 35e66c5 into master Jan 10, 2024
3 checks passed
@alcjzk alcjzk deleted the config_parsing branch March 11, 2024 00:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants