source: neercs/trunk/src/configuration.c @ 3969

Last change on this file since 3969 was 3969, checked in by Jean-Yves Lamoureux, 11 years ago
  • Massive indentation pass, could insert odd things, blame pterjan, he doesn't care.
  • Property svn:keywords set to Id
File size: 9.1 KB
Line 
1/*
2 *  neercs        console-based window manager
3 *  Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
4 *                2008 Jean-Yves Lamoureux <jylam@lnxscene.org>
5 *                All Rights Reserved
6 *
7 *  $Id: configuration.c 3969 2009-11-19 16:26:53Z jylam $
8 *
9 *  This program is free software. It comes without any warranty, to
10 *  the extent permitted by applicable law. You can redistribute it
11 *  and/or modify it under the terms of the Do What The Fuck You Want
12 *  To Public License, Version 2, as published by Sam Hocevar. See
13 *  http://sam.zoy.org/wtfpl/COPYING for more details.
14 */
15
16#include <fcntl.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <unistd.h>
22#include <errno.h>
23#include <string.h>
24
25#include "neercs.h"
26
27
28int read_configuration_file(char *filename, struct screen_list *screen_list)
29{
30    FILE *fp;
31    struct stat st;
32    int size = 0, i = 0, total = 0, offset = 0, l = 1;
33    char *buffer = NULL;
34
35    screen_list->config = NULL;
36
37    /* Check if file exist */
38    if (stat(filename, &st) < 0)
39    {
40        return -1;
41    }
42    /* Get its size */
43    size = st.st_size;
44    if (!size)
45    {
46        fprintf(stderr, "File too short\n");
47        return -1;
48    }
49
50    /* Open it */
51    fp = fopen(filename, "r");
52    if (!fp)
53    {
54        return -1;
55    }
56
57    buffer = malloc(size + 1);
58    if (!buffer)
59    {
60        fclose(fp);
61        fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
62                __LINE__);
63        return -1;
64    }
65    /* Read it */
66    while ((i = fread(buffer + total, 1, size, fp)) > 0)
67    {
68        total += i;
69    }
70    buffer[total] = '\n';
71
72    fclose(fp);
73
74    i = 0;
75
76    /* Parse it */
77    while ((i =
78            parse_conf_line(buffer + offset, total - offset, screen_list)) > 0)
79    {
80        offset += i;
81        l++;
82    }
83
84    free(buffer);
85
86    /* Fill neercs configuration with it */
87    fill_config(screen_list);
88
89    return 1;
90}
91
92
93int parse_conf_line(char *buf, int size, struct screen_list *screen_list)
94{
95    int i, s = 0, eol = 0, c = 0;
96    char *line = NULL;
97    int l = 0;
98    int in_quote = 0, end_spaces = 0;
99    static struct option *prev = NULL;
100
101    if (size <= 0)
102        return -1;
103
104    /* Find EOL */
105    for (i = 0; i < size; i++)
106    {
107        if (buf[i] == '\n')
108        {
109            s = i + 1;
110            break;
111        }
112    }
113
114    /* Strip comments and trailing spaces */
115    for (i = 0; i < s; i++)
116    {
117        if (buf[i] == ';' && !in_quote)
118        {
119            eol = i;
120            break;
121        }
122        else if (buf[i] == '\n')
123        {
124            eol = i;
125            break;
126        }
127        else if (buf[i] == ' ' && !c)
128        {
129        }
130        else
131        {
132            if (line == NULL)
133            {
134                line = malloc(2);
135                if (!line)
136                {
137                    fprintf(stderr, "Can't allocate memory at %s:%d\n",
138                            __FUNCTION__, __LINE__);
139                    return -1;
140                }
141            }
142            else
143            {
144                line = realloc(line, l + 2);
145                if (!line)
146                {
147                    fprintf(stderr, "Can't allocate memory at %s:%d\n",
148                            __FUNCTION__, __LINE__);
149                    return -1;
150                }
151            }
152            if (buf[i] == '"')
153                in_quote = !in_quote;
154            if (buf[i] == ' ')
155                end_spaces++;
156            else
157                end_spaces = 0;
158
159            line[l] = buf[i];
160            line[l + 1] = 0;
161            l++;
162            c = 1;
163        }
164    }
165
166    if (c == 0)
167    {
168        /* This line is empty, do nothing */
169    }
170    else
171    {
172        struct option *option = malloc(sizeof(struct option));
173        if (!option)
174        {
175            fprintf(stderr, "Can't allocate memory at %s:%d\n",
176                    __FUNCTION__, __LINE__);
177            return -1;
178        }
179        option->next = NULL;
180        l -= end_spaces;
181        line = realloc(line, l + 1);
182        line[l] = 0;
183
184        get_key_value(line, option);
185
186        if (!screen_list->config)
187            screen_list->config = option;
188
189        if (prev)
190            prev->next = option;
191
192        prev = option;
193    }
194    free(line);
195    return s;
196}
197
198int get_key_value(char *line, struct option *option)
199{
200    unsigned int i, o = 0, b = 0, end_spaces = 0;
201    char *cur = NULL;
202    option->value = NULL;
203    option->key = NULL;
204
205    /* Line is a section delimiter */
206    if (line[0] == '[')
207    {
208        option->value = malloc(strlen(line) - 1);
209        if (!option->value)
210        {
211            fprintf(stderr, "Can't allocate memory at %s:%d\n",
212                    __FUNCTION__, __LINE__);
213            return -1;
214        }
215        memcpy(option->value, line + 1, strlen(line) - 1);
216        option->value[strlen(line) - 2] = 0;
217        return 0;
218    }
219
220    cur = malloc(1);
221    if (!cur)
222    {
223        fprintf(stderr, "Can't allocate memory at %s:%d\n",
224                __FUNCTION__, __LINE__);
225        return -1;
226    }
227    cur[0] = 0;
228
229    for (i = 0; i < strlen(line); i++)
230    {
231        if (line[i] == ' ' && !b)
232            continue;
233
234
235        if (line[i] == '=')
236        {
237            b = 0;
238            cur[o - end_spaces] = 0;
239            cur = realloc(cur, (o - end_spaces) + 1);
240            if (!cur)
241            {
242                fprintf(stderr, "Can't allocate memory at %s:%d\n",
243                        __FUNCTION__, __LINE__);
244                return -1;
245            }
246            o = 0;
247            option->key = cur;
248            cur = malloc(1);
249        }
250        else
251        {
252            if (line[i] == ' ')
253                end_spaces++;
254            else
255                end_spaces = 0;
256
257            cur = realloc(cur, o + 2);
258            if (!cur)
259            {
260                fprintf(stderr, "Can't allocate memory at %s:%d\n",
261                        __FUNCTION__, __LINE__);
262                return -1;
263            }
264            cur[o] = line[i];
265            o++;
266            b = 1;
267
268        }
269    }
270    cur[o] = 0;
271    option->value = cur;
272    return 0;
273}
274
275
276#define IS_TOKEN(t) (!strncmp(option->key, t, strlen(option->key)))
277#define IS_VALUE(t) (!strncmp(option->value, t, strlen(option->value)))
278
279
280int fill_config(struct screen_list *screen_list)
281{
282    int i = 0;
283    struct option *option = screen_list->config;
284    char *section = NULL;
285
286    while (option)
287    {
288        if (option->key == NULL)
289        {
290            section = option->key;
291            option = option->next;
292            continue;
293        }
294
295        if (IS_TOKEN("window_manager"))
296        {
297            if (IS_VALUE("full"))
298                screen_list->wm_type = WM_FULL;
299            else if (IS_VALUE("hsplit"))
300                screen_list->wm_type = WM_HSPLIT;
301            else if (IS_VALUE("vsplit"))
302                screen_list->wm_type = WM_VSPLIT;
303            else if (IS_VALUE("card"))
304                screen_list->wm_type = WM_CARD;
305            else if (IS_VALUE("cube"))
306                screen_list->wm_type = WM_CUBE;
307            else
308                fprintf(stderr, "Unknown window manager '%s'\n", option->key);
309
310        }
311        else if (IS_TOKEN("cube_duration"))
312        {
313            screen_list->cube.duration = atoi(option->value) * 1000000;
314        }
315        else if (IS_TOKEN("thumbnails"))
316        {
317            if (IS_VALUE("true") || IS_VALUE("1"))
318                screen_list->mini = 1;
319            else
320                screen_list->mini = 0;
321
322        }
323        else if (IS_TOKEN("status_bar"))
324        {
325            if (IS_VALUE("true") || IS_VALUE("1"))
326                screen_list->status = 1;
327            else
328                screen_list->status = 0;
329
330        }
331        else if (IS_TOKEN("screensaver_timeout"))
332        {
333            screen_list->screensaver_timeout = atoi(option->value) * 1000000;
334            /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
335            if (!screen_list->screensaver_timeout)
336                screen_list->screensaver_timeout -= 1;
337        }
338        else if (IS_TOKEN("autolock_timeout"))
339        {
340            debug("Autolock is %d\n", screen_list->autolock_timeout);
341            if (screen_list->autolock_timeout == 0 ||
342                screen_list->autolock_timeout ==
343                ((long long unsigned int)0) - 1)
344            {
345                screen_list->autolock_timeout = atoi(option->value) * 1000000;
346                /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
347                if (!screen_list->autolock_timeout)
348                    screen_list->autolock_timeout -= 1;
349            }
350        }
351        else if (IS_TOKEN("lock_on_detach"))
352        {
353            if (IS_VALUE("true") || IS_VALUE("1"))
354                screen_list->lock_on_detach = 1;
355            else
356                screen_list->lock_on_detach = 0;
357        }
358        else if (IS_TOKEN("socket_dir"))
359        {
360            screen_list->socket_dir = option->value;
361        }
362        else if (IS_TOKEN("delay"))
363        {
364            screen_list->requested_delay = atoi(option->value);
365            screen_list->delay = atoi(option->value);
366        }
367        else
368        {
369            fprintf(stderr, "Unknown option '%s'\n", option->key);
370        }
371        option = option->next;
372    }
373
374    return i;
375}
Note: See TracBrowser for help on using the repository browser.