Merge Irssi 0.8.16-rc1
[silc.git] / apps / irssi / src / lib-config / iconfig.h
1 #ifndef __ICONFIG_H
2 #define __ICONFIG_H
3
4 enum {
5         NODE_TYPE_KEY,
6         NODE_TYPE_VALUE,
7         NODE_TYPE_BLOCK,
8         NODE_TYPE_LIST,
9         NODE_TYPE_COMMENT
10 };
11
12 #define has_node_value(a) \
13         ((a)->type == NODE_TYPE_KEY || (a)->type == NODE_TYPE_VALUE)
14 #define is_node_list(a) \
15         ((a)->type == NODE_TYPE_BLOCK || (a)->type == NODE_TYPE_LIST)
16
17 typedef struct _CONFIG_NODE CONFIG_NODE;
18 typedef struct _CONFIG_REC CONFIG_REC;
19
20 struct _CONFIG_NODE {
21         int type;
22         char *key;
23         void *value;
24 };
25
26 /* a = { x=y; y=z; }
27
28    node1: type = NODE_TYPE_BLOCK, key = "a", value = (GSList *) nodes
29    nodes: (node2, node3)
30      node2: type = NODE_TYPE_KEY, key = "x", value = (char *) "y"
31      node3: type = NODE_TYPE_KEY, key = "y", value = (char *) "z"
32
33    b = ( a, { b=c; d=e; } )
34
35    node1: type = NODE_TYPE_LIST, key = "b", value = (GSList *) nodes
36    nodes: (node2, node3)
37      node2: type = NODE_TYPE_VALUE, key = NULL, value = (char *) "a"
38      node4: type = NODE_TYPE_BLOCK, key = NULL, value = (GSList *) nodes2
39      nodes2: (node4, node5)
40        node4: type = NODE_TYPE_KEY, key = "b", value = (char *) "c"
41        node5: type = NODE_TYPE_KEY, key = "d", value = (char *) "e"
42
43    Comments node has key=NULL and value is the comment line. Empty lines are
44    also in comments so they won't be forgotten when the config file is
45    written.
46
47 */
48
49 struct _CONFIG_REC {
50         char *fname;
51         int create_mode;
52         int modifycounter; /* increase every time something is changed */
53
54         char *last_error;
55         CONFIG_NODE *mainnode;
56         GHashTable *cache; /* path -> node (for querying) */
57         GHashTable *cache_nodes; /* node -> path (for removing) */
58
59         GScanner *scanner;
60
61         /* while writing to configuration file.. */
62         GIOChannel *handle;
63         int tmp_indent_level; /* indentation position */
64         int tmp_last_lf; /* last character was a line feed */
65 };
66
67 /* Open configuration. The file is created if it doesn't exist, unless
68    `create_mode' is -1. `fname' can be NULL if you just want to use
69    config_parse_data() */
70 CONFIG_REC *config_open(const char *fname, int create_mode);
71 /* Release all memory used by configuration */
72 void config_close(CONFIG_REC *rec);
73 /* Change file name of config file */
74 void config_change_file_name(CONFIG_REC *rec, const char *fname, int create_mode);
75
76 /* Parse configuration file */
77 int config_parse(CONFIG_REC *rec);
78 /* Parse configuration found from `data'. `input_name' specifies the
79    "configuration name" which is displayed in error messages. */
80 int config_parse_data(CONFIG_REC *rec, const char *data, const char *input_name);
81
82 /* Write configuration file. Write to `fname' if it's not NULL.
83    If `create_mode' is -1, use the one that was given to config_open(). */
84 int config_write(CONFIG_REC *rec, const char *fname, int create_mode);
85
86 #define config_last_error(rec) \
87     (rec)->last_error
88
89 /* Getting values
90
91    `section' is something like "maingroup/key/subkey", or with lists
92    "maingroup/(list/subkey"
93
94    `def' is returned if the value is not found. */
95 char *config_get_str(CONFIG_REC *rec, const char *section, const char *key, const char *def);
96 int config_get_int(CONFIG_REC *rec, const char *section, const char *key, int def);
97 int config_get_bool(CONFIG_REC *rec, const char *section, const char *key, int def);
98
99 /* Returns n'th node from list. */
100 CONFIG_NODE *config_node_nth(CONFIG_NODE *node, int index);
101 /* Returns index for given key */
102 int config_node_index(CONFIG_NODE *parent, const char *key);
103
104 /* Returns the first non-comment node in list */
105 GSList *config_node_first(GSList *list);
106 /* Returns the next non-comment node in list */
107 GSList *config_node_next(GSList *list);
108
109 /* Setting values */
110 int config_set_str(CONFIG_REC *rec, const char *section, const char *key, const char *value);
111 int config_set_int(CONFIG_REC *rec, const char *section, const char *key, int value);
112 int config_set_bool(CONFIG_REC *rec, const char *section, const char *key, int value);
113
114 /* Handling the configuration directly with nodes -
115    useful when you need to read all values in a block/list. */
116 CONFIG_NODE *config_node_find(CONFIG_NODE *node, const char *key);
117 /* Find the section from node - if not found create it unless new_type is -1.
118    You can also specify in new_type if it's NODE_TYPE_LIST or NODE_TYPE_BLOCK */
119 CONFIG_NODE *config_node_section(CONFIG_NODE *parent, const char *key, int new_type);
120 CONFIG_NODE *config_node_section_index(CONFIG_NODE *parent, const char *key,
121                                        int index, int new_type);
122 /* Find the section with the whole path.
123    Create the path if necessary if `create' is TRUE. */
124 CONFIG_NODE *config_node_traverse(CONFIG_REC *rec, const char *section, int create);
125 /* Return all values from the list `node' in a g_strsplit() array */
126 char **config_node_get_list(CONFIG_NODE *node);
127 /* Add all values in `array' to `node' */
128 void config_node_add_list(CONFIG_REC *rec, CONFIG_NODE *node, char **array);
129
130 char *config_node_get_str(CONFIG_NODE *parent, const char *key, const char *def);
131 int config_node_get_int(CONFIG_NODE *parent, const char *key, int def);
132 int config_node_get_bool(CONFIG_NODE *parent, const char *key, int def);
133
134 /*
135  * key != NULL && value == NULL
136  * remove node with key 'key', equivalent to
137  * config_node_remove(rec, parent, config_node_find(parent, key))
138  * key == NULL && value != NULL
139  * create a new node with type NODE_TYPE_VALUE and value 'value'
140  * key != NULL && value != NULL
141  * if a node with key 'key' exists change its value to 'value',
142  * otherwise create a new node with type NODE_TYPE_KEY, key 'key' and value 'value'
143  * */
144 void config_node_set_str(CONFIG_REC *rec, CONFIG_NODE *parent, const char *key, const char *value);
145 void config_node_set_int(CONFIG_REC *rec, CONFIG_NODE *parent, const char *key, int value);
146 void config_node_set_bool(CONFIG_REC *rec, CONFIG_NODE *parent, const char *key, int value);
147
148 /* Remove one node from block/list. */
149 void config_node_remove(CONFIG_REC *rec, CONFIG_NODE *parent, CONFIG_NODE *node);
150 /* Remove n'th node from a list */
151 void config_node_list_remove(CONFIG_REC *rec, CONFIG_NODE *node, int index);
152
153 /* Clear all data inside node, but leave the node */
154 void config_node_clear(CONFIG_REC *rec, CONFIG_NODE *node);
155 /* Clear the entire configuration */
156 void config_nodes_remove_all(CONFIG_REC *rec);
157
158 #endif