summaryrefslogtreecommitdiff
path: root/src/object.h
blob: 00c4813836e364e07c4beb733e79834c0edb8cfa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/** Copyright 2011-2013 Thorsten Wißmann. All rights reserved.
 *
 * This software is licensed under the "Simplified BSD License".
 * See LICENSE for details */

#ifndef __HS_OBJECT_H_
#define __HS_OBJECT_H_

#include <stdbool.h>
#include <glib.h>

#define OBJECT_PATH_SEPARATOR '.'

typedef struct HSObject {
    struct HSAttribute* attributes;
    size_t              attribute_count;
    GList*              children; // list of HSObjectChild
    void*               data;     // user data pointer
} HSObject;

typedef void (*HSAttributeCustom)(void* data, GString* output);
typedef int (*HSAttributeCustomInt)(void* data);

typedef struct HSAttribute {
    HSObject* object;           /* the object this attribute is in */
    enum  {
        HSATTR_TYPE_BOOL,
        HSATTR_TYPE_UINT,
        HSATTR_TYPE_INT,
        HSATTR_TYPE_STRING,
        HSATTR_TYPE_CUSTOM,
        HSATTR_TYPE_CUSTOM_INT,
    } type;                     /* the datatype */
    char*  name;                /* name as it is displayed to the user */
    union {
        bool*       b;
        int*        i;
        unsigned int* u;
        GString**   str;
        HSAttributeCustom custom;
        HSAttributeCustomInt custom_int;
    } value;
    /** if type is not custom:
     * on_change is called after the user changes the value. If this
     * function returns NULL, the value is accepted. If this function returns
     * some error message, the old value is restored automatically and the
     * message first is displayed to the user and then freed.
     *
     * if type is custom:
     * on_change will never be called, because custom are read-only for now.
     * */
    GString* (*on_change)  (struct HSAttribute* attr);
} HSAttribute;

#define ATTRIBUTE_BOOL(N, V, CHANGE) \
    { NULL, HSATTR_TYPE_BOOL, (N), { .b = &(V) }, (CHANGE) }
#define ATTRIBUTE_INT(N, V, CHANGE) \
    { NULL, HSATTR_TYPE_INT, (N), { .i = &(V) }, (CHANGE) }
#define ATTRIBUTE_UINT(N, V, CHANGE) \
    { NULL, HSATTR_TYPE_UINT, (N), { .u = &(V) }, (CHANGE) }
#define ATTRIBUTE_STRING(N, V, CHANGE) \
    { NULL, HSATTR_TYPE_STRING, (N), { .str = &(V) }, (CHANGE) }
#define ATTRIBUTE_CUSTOM(N, V, CHANGE) \
    { NULL, HSATTR_TYPE_CUSTOM, (N), { .custom = V }, (NULL) }
#define ATTRIBUTE_CUSTOM_INT(N, V, CHANGE) \
    { NULL, HSATTR_TYPE_CUSTOM_INT, (N), { .custom_int = V }, (NULL) }

#define ATTRIBUTE_LAST { .name = NULL }

void object_tree_init();
void object_tree_destroy();

HSObject* hsobject_root();

bool hsobject_init(HSObject* obj);
void hsobject_free(HSObject* obj);
HSObject* hsobject_create();
HSObject* hsobject_create_and_link(HSObject* parent, char* name);
void hsobject_destroy(HSObject* obj);
void hsobject_link(HSObject* parent, HSObject* child, char* name);
void hsobject_unlink(HSObject* parent, HSObject* child);
void hsobject_unlink_by_name(HSObject* parent, char* name);
void hsobject_link_rename(HSObject* parent, char* oldname, char* newname);
void hsobject_rename_child(HSObject* parent, HSObject* child, char* newname);
void hsobject_unlink_and_destroy(HSObject* parent, HSObject* child);

HSObject* hsobject_by_path(char* path);
HSObject* hsobject_parse_path(char* path, char** unparsable);
HSObject* hsobject_parse_path_verbose(char* path, char** unparsable, GString* output);

HSAttribute* hsattribute_parse_path_verbose(char* path, GString* output);

void hsobject_set_attributes(HSObject* obj, HSAttribute* attributes);

GString* ATTR_ACCEPT_ALL(HSAttribute* attr);
#define ATTR_READ_ONLY  NULL

HSObject* hsobject_find_child(HSObject* obj, char* name);
HSAttribute* hsobject_find_attribute(HSObject* obj, char* name);

char hsattribute_type_indicator(int type);

int attr_command(int argc, char* argv[], GString* output);
int print_object_tree_command(int argc, char* argv[], GString* output);
int hsattribute_get_command(int argc, char* argv[], GString* output);
int hsattribute_set_command(int argc, char* argv[], GString* output);
int hsattribute_assign(HSAttribute* attr, char* new_value_str, GString* output);
void hsattribute_append_to_string(HSAttribute* attribute, GString* output);
GString* hsattribute_to_string(HSAttribute* attribute);

void hsobject_complete_children(HSObject* obj, char* needle, char* prefix,
                                GString* output);
void hsobject_complete_attributes(HSObject* obj, char* needle, char* prefix,
                                GString* output);
int substitute_command(int argc, char* argv[], GString* output);
int compare_command(int argc, char* argv[], GString* output);

#endif