<commit_before>#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>

#include <libngf/client.h>

#define MAX_BUF_SIZE 512

typedef struct _TestClient
{
    GMainLoop       *loop;
    GIOChannel      *channel;
    guint           event_source;

    DBusConnection  *connection;
    NgfClient       *client;
} TestClient;

static char*
copy_str (char *str, size_t length)
{
    if (str == NULL || length <= 0)
        return NULL;

    char *p = (char*) malloc (sizeof (char) * (length + 1));
    if (p == NULL)
        return NULL;

    p[length] = '\0';
    strncpy (p, str, length);
    return p;
}

static char*
skip_whitespace (char *str)
{
    char *p = str;
    while (*p != '\0' && (*p == ' ' || *p == '\t'))
        p++;
    return p;
}

static char*
get_str (char *buffer, char delim, char **str)
{
    char *p = NULL, *start = NULL;
    size_t length = 0;
    gboolean expect_quote = FALSE;

    if ((p = skip_whitespace (buffer)) == NULL)
        return NULL;

    start = p;
    if (*p == '"') {
        expect_quote = TRUE;
        start = ++p;
    }

    while (*p != '\0' && *p != '\n') {
        if ((!expect_quote && (*p == ' ' || *p == delim)) || (expect_quote && *p == '"'))
            break;

        p++;
    }

    length = (size_t) (p - start);
    *str = copy_str (start, length);

    if (*p == '"' || *p == delim)
        p++;

    return p;
}

static void
parse_command_play (TestClient *c, char *buf)
{
    char *advance = buf;
    char *event_id = NULL, *key = NULL, *value = NULL, *ptr = NULL, *type = NULL;
    NgfProplist *p = NULL;

    /* First parameter is the event */
    advance = get_str (buf, ' ', &event_id);
    if (event_id == NULL) {
        g_print ("Usage: play [EVENT_NAME] [KEY:VALUE], returns [ID]*\n");
        return;
    }

    p = ngf_proplist_new ();

    /* Then we have variable amount of key-value pairs */
    while (1) {
        advance = get_str (advance, ':', &key);
        if (key == NULL)
            break;

        advance = get_str (advance, ' ', &value);
        if (value == NULL) {
            free (key);
            break;
        }

        /* Parse the value, it may contain optional type within parenthesis. */

        g_print ("key=%s, value=%s\n", key, value);

        if (value[0] == '(') {
            ptr = get_str ((value + 1), ')', &type);
            g_print ("type=%s, ptr=%s\n", type, ptr);

            if (strncmp (type, "string", 6) == 0) {
                ngf_proplist_sets (p, key, ptr);
            }
            else if (strncmp (type, "integer", 7) == 0) {
                ngf_proplist_set_as_integer (p, key, ngf_proplist_parse_integer (ptr));
                g_print ("integer -> %d\n", ngf_proplist_get_as_integer (p, key));
            }
            else if (strncmp (type, "boolean", 7) == 0) {
                ngf_proplist_set_as_boolean (p, key, ngf_proplist_parse_boolean (ptr));
                g_print ("boolean -> %s\n", ngf_proplist_get_as_boolean (p, key) ? "TRUE" : "FALSE");
            }

            free (type);
        }
        else {
            ngf_proplist_sets (p, key, value);
        }
<commit_msg>Use new proplist in ngf-client example.<commit_after>#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>

#include <libngf/client.h>

#define MAX_BUF_SIZE 512

typedef struct _TestClient
{
    GMainLoop       *loop;
    GIOChannel      *channel;
    guint           event_source;

    DBusConnection  *connection;
    NgfClient       *client;
} TestClient;

static char*
copy_str (char *str, size_t length)
{
    if (str == NULL || length <= 0)
        return NULL;

    char *p = (char*) malloc (sizeof (char) * (length + 1));
    if (p == NULL)
        return NULL;

    p[length] = '\0';
    strncpy (p, str, length);
    return p;
}

static char*
skip_whitespace (char *str)
{
    char *p = str;
    while (*p != '\0' && (*p == ' ' || *p == '\t'))
        p++;
    return p;
}

static char*
get_str (char *buffer, char delim, char **str)
{
    char *p = NULL, *start = NULL;
    size_t length = 0;
    gboolean expect_quote = FALSE;

    if ((p = skip_whitespace (buffer)) == NULL)
        return NULL;

    start = p;
    if (*p == '"') {
        expect_quote = TRUE;
        start = ++p;
    }

    while (*p != '\0' && *p != '\n') {
        if ((!expect_quote && (*p == ' ' || *p == delim)) || (expect_quote && *p == '"'))
            break;

        p++;
    }

    length = (size_t) (p - start);
    *str = copy_str (start, length);

    if (*p == '"' || *p == delim)
        p++;

    return p;
}

static void
parse_command_play (TestClient *c, char *buf)
{
    char *advance = buf;
    char *event_id = NULL, *key = NULL, *value = NULL, *ptr = NULL, *type = NULL;
    NgfProplist *p = NULL;

    /* First parameter is the event */
    advance = get_str (buf, ' ', &event_id);
    if (event_id == NULL) {
        g_print ("Usage: play [EVENT_NAME] [KEY:VALUE], returns [ID]*\n");
        return;
    }

    p = ngf_proplist_new ();

    /* Then we have variable amount of key-value pairs */
    while (1) {
        advance = get_str (advance, ':', &key);
        if (key == NULL)
            break;

        advance = get_str (advance, ' ', &value);
        if (value == NULL) {
            free (key);
            break;
        }

        /* Parse the value, it may contain optional type within parenthesis. */

        g_print ("key=%s, value=%s\n", key, value);

        if (value[0] == '(') {
            ptr = get_str ((value + 1), ')', &type);
            g_print ("type=%s, ptr=%s\n", type, ptr);

            if (strncmp (type, "string", 6) == 0) {
                ngf_proplist_sets (p, key, ptr);
            }
            else if (strncmp (type, "integer", 7) == 0) {
                int value;
                if (ngf_proplist_parse_integer (ptr, &value)) {
                    ngf_proplist_set_as_integer (p, key, value);
                    g_print ("integer -> %d\n", value);
                }
            }
            else if (strncmp (type, "unsigned", 8) == 0) {
                uint32_t value;
                if (ngf_proplist_parse_unsigned (ptr, &value)) {
                    ngf_proplist_set_as_unsigned (p, key, value);
                    g_print ("unsigned -> %u\n", value);
                }
            }
            else if (strncmp (type, "boolean", 7) == 0) {
                int value;
                if (ngf_proplist_parse_boolean (ptr, &value)) {
                    ngf_proplist_set_as_boolean (p, key, value);
                    g_print ("boolean -> %s\n", value ? "TRUE" : "FALSE");
                }
            }

            free (type);
        }
        else {
            ngf_proplist_sets (p, key, value);
        }

{'fraction_non_alphanumeric': 0.16079965232507606, 'fraction_numerical': 0.0057945820657685065, 'mean_word_length': 1.8423219431864966, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '473223', 'n_tokens_mistral': 2465, 'n_tokens_neox': 2345, 'n_words': 642}