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

Last change on this file since 3997 was 3997, checked in by Jean-Yves Lamoureux, 11 years ago
  • Cleaned et reorganized configuration parsing stuff, paves the way to about:config thingy
  • Property svn:keywords set to Id
File size: 10.8 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 3997 2009-11-22 13:33:48Z 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
28struct config_line
29{
30    const char name[32];
31    int (*func_ptr) (const char *argv, struct screen_list * screen_list);
32};
33
34struct config_line *get_config(const char *name);
35int set_window_manager(const char *argv, struct screen_list *screen_list);
36int set_cube_duration(const char *argv, struct screen_list *screen_list);
37int set_thumbnails(const char *argv, struct screen_list *screen_list);
38int set_status_bar(const char *argv, struct screen_list *screen_list);
39int set_screensaver_timeout(const char *argv, struct screen_list *screen_list);
40int set_autolock_timeout(const char *argv, struct screen_list *screen_list);
41int set_lock_on_detach(const char *argv, struct screen_list *screen_list);
42int set_socket_dir(const char *argv, struct screen_list *screen_list);
43int set_delay(const char *argv, struct screen_list *screen_list);
44
45/* Options definition and associated function pointer */
46struct config_line config_option[] = {
47    {.name = "window_manager",.func_ptr = set_window_manager},
48    {.name = "cube_duration",.func_ptr = set_cube_duration},
49    {.name = "thumbnails",.func_ptr = set_thumbnails},
50    {.name = "status_bar",.func_ptr = set_status_bar},
51    {.name = "screensaver_timeout",.func_ptr = set_screensaver_timeout},
52    {.name = "autolock_timeout",.func_ptr = set_autolock_timeout},
53    {.name = "lock_on_detach",.func_ptr = set_lock_on_detach},
54    {.name = "socket_dir",.func_ptr = set_socket_dir},
55    {.name = "delay",.func_ptr = set_delay},
56   
57    {.name = "last",.func_ptr = NULL},
58};
59
60
61
62int read_configuration_file(char *filename, struct screen_list *screen_list)
63{
64    FILE *fp;
65    struct stat st;
66    int size = 0, i = 0, total = 0, offset = 0, l = 1;
67    char *buffer = NULL;
68
69    screen_list->config = NULL;
70
71    /* Check if file exist */
72    if (stat(filename, &st) < 0)
73    {
74        return -1;
75    }
76    /* Get its size */
77    size = st.st_size;
78    if (!size)
79    {
80        fprintf(stderr, "File too short\n");
81        return -1;
82    }
83
84    /* Open it */
85    fp = fopen(filename, "r");
86    if (!fp)
87    {
88        return -1;
89    }
90
91    buffer = malloc(size + 1);
92    if (!buffer)
93    {
94        fclose(fp);
95        fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
96                __LINE__);
97        return -1;
98    }
99    /* Read it */
100    while ((i = fread(buffer + total, 1, size, fp)) > 0)
101    {
102        total += i;
103    }
104    buffer[total] = '\n';
105
106    fclose(fp);
107
108    i = 0;
109
110    /* Parse it */
111    while ((i =
112            parse_conf_line(buffer + offset, total - offset, screen_list)) > 0)
113    {
114        offset += i;
115        l++;
116    }
117
118    free(buffer);
119
120    /* Fill neercs configuration with it */
121    fill_config(screen_list);
122
123    return 1;
124}
125
126
127int parse_conf_line(char *buf, int size, struct screen_list *screen_list)
128{
129    int i, s = 0, eol = 0, c = 0;
130    char *line = NULL;
131    int l = 0;
132    int in_quote = 0, end_spaces = 0;
133    static struct option *prev = NULL;
134
135    if (size <= 0)
136        return -1;
137
138    /* Find EOL */
139    for (i = 0; i < size; i++)
140    {
141        if (buf[i] == '\n')
142        {
143            s = i + 1;
144            break;
145        }
146    }
147
148    /* Strip comments and trailing spaces */
149    for (i = 0; i < s; i++)
150    {
151        if (buf[i] == ';' && !in_quote)
152        {
153            eol = i;
154            break;
155        }
156        else if (buf[i] == '\n')
157        {
158            eol = i;
159            break;
160        }
161        else if (buf[i] == ' ' && !c)
162        {
163        }
164        else
165        {
166            if (line == NULL)
167            {
168                line = malloc(2);
169                if (!line)
170                {
171                    fprintf(stderr, "Can't allocate memory at %s:%d\n",
172                            __FUNCTION__, __LINE__);
173                    return -1;
174                }
175            }
176            else
177            {
178                line = realloc(line, l + 2);
179                if (!line)
180                {
181                    fprintf(stderr, "Can't allocate memory at %s:%d\n",
182                            __FUNCTION__, __LINE__);
183                    return -1;
184                }
185            }
186            if (buf[i] == '"')
187                in_quote = !in_quote;
188            if (buf[i] == ' ')
189                end_spaces++;
190            else
191                end_spaces = 0;
192
193            line[l] = buf[i];
194            line[l + 1] = 0;
195            l++;
196            c = 1;
197        }
198    }
199
200    if (c == 0)
201    {
202        /* This line is empty, do nothing */
203    }
204    else
205    {
206        struct option *option = malloc(sizeof(struct option));
207        if (!option)
208        {
209            fprintf(stderr, "Can't allocate memory at %s:%d\n",
210                    __FUNCTION__, __LINE__);
211            return -1;
212        }
213        option->next = NULL;
214        l -= end_spaces;
215        line = realloc(line, l + 1);
216        line[l] = 0;
217
218        get_key_value(line, option);
219
220        if (!screen_list->config)
221            screen_list->config = option;
222
223        if (prev)
224            prev->next = option;
225
226        prev = option;
227    }
228    free(line);
229    return s;
230}
231
232int get_key_value(char *line, struct option *option)
233{
234    unsigned int i, o = 0, b = 0, end_spaces = 0;
235    char *cur = NULL;
236    option->value = NULL;
237    option->key = NULL;
238
239    /* Line is a section delimiter */
240    if (line[0] == '[')
241    {
242        option->value = malloc(strlen(line) - 1);
243        if (!option->value)
244        {
245            fprintf(stderr, "Can't allocate memory at %s:%d\n",
246                    __FUNCTION__, __LINE__);
247            return -1;
248        }
249        memcpy(option->value, line + 1, strlen(line) - 1);
250        option->value[strlen(line) - 2] = 0;
251        return 0;
252    }
253
254    cur = malloc(1);
255    if (!cur)
256    {
257        fprintf(stderr, "Can't allocate memory at %s:%d\n",
258                __FUNCTION__, __LINE__);
259        return -1;
260    }
261    cur[0] = 0;
262
263    for (i = 0; i < strlen(line); i++)
264    {
265        if (line[i] == ' ' && !b)
266            continue;
267
268
269        if (line[i] == '=')
270        {
271            b = 0;
272            cur[o - end_spaces] = 0;
273            cur = realloc(cur, (o - end_spaces) + 1);
274            if (!cur)
275            {
276                fprintf(stderr, "Can't allocate memory at %s:%d\n",
277                        __FUNCTION__, __LINE__);
278                return -1;
279            }
280            o = 0;
281            option->key = cur;
282            cur = malloc(1);
283        }
284        else
285        {
286            if (line[i] == ' ')
287                end_spaces++;
288            else
289                end_spaces = 0;
290
291            cur = realloc(cur, o + 2);
292            if (!cur)
293            {
294                fprintf(stderr, "Can't allocate memory at %s:%d\n",
295                        __FUNCTION__, __LINE__);
296                return -1;
297            }
298            cur[o] = line[i];
299            o++;
300            b = 1;
301
302        }
303    }
304    cur[o] = 0;
305    option->value = cur;
306    return 0;
307}
308
309
310
311struct config_line *get_config(const char *name)
312{
313    int i = 0;
314    while (strncmp(config_option[i].name, "last", strlen("last")))
315    {
316        if (!strncmp(name, config_option[i].name, strlen(name)))
317        {
318            debug("Found\n");
319            return &config_option[i];
320        }
321        i++;
322    }
323    return NULL;
324}
325
326
327
328int fill_config(struct screen_list *screen_list)
329{
330    int i = 0;
331    struct option *option = screen_list->config;
332    char *section = NULL;
333
334    while (option)
335    {
336        if (option->key == NULL)
337        {
338            section = option->key;
339            option = option->next;
340            continue;
341        }
342
343        struct config_line *c = get_config(option->key);
344        if (c)
345        {
346            printf("Found config '%s', ptr %p\n", c->name, c->func_ptr);
347            c->func_ptr(option->value, screen_list);
348        }
349        option = option->next;
350    }
351
352    return i;
353}
354
355
356
357/*
358 * Options setters
359 */
360
361#define IS_OPTION(t) (!strncmp(argv, t, strlen(argv)))
362int set_window_manager(const char *argv, struct screen_list *screen_list)
363{
364    if (IS_OPTION("full"))
365        screen_list->wm_type = WM_FULL;
366    else if (IS_OPTION("hsplit"))
367        screen_list->wm_type = WM_HSPLIT;
368    else if (IS_OPTION("vsplit"))
369        screen_list->wm_type = WM_VSPLIT;
370    else if (IS_OPTION("card"))
371        screen_list->wm_type = WM_CARD;
372    else if (IS_OPTION("cube"))
373        screen_list->wm_type = WM_CUBE;
374    else
375    {
376        fprintf(stderr, "Unknown window manager '%s'\n", argv);
377        return -1;
378    }
379    return 0;
380}
381
382int set_cube_duration(const char *argv, struct screen_list *screen_list)
383{
384    screen_list->cube.duration = atoi(argv) * 1000000;
385    return 0;
386}
387
388int set_thumbnails(const char *argv, struct screen_list *screen_list)
389{
390    if (IS_OPTION("true") || IS_OPTION("1"))
391        screen_list->mini = 1;
392    else
393        screen_list->mini = 0;
394    return 0;
395   
396}
397
398int set_status_bar(const char *argv, struct screen_list *screen_list)
399{
400    if (IS_OPTION("true") || IS_OPTION("1"))
401        screen_list->status = 1;
402    else
403        screen_list->status = 0;
404    return 0;
405}
406
407int set_screensaver_timeout(const char *argv, struct screen_list *screen_list)
408{
409    screen_list->screensaver_timeout = atoi(argv) * 1000000;
410    /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
411    if (!screen_list->screensaver_timeout)
412        screen_list->screensaver_timeout -= 1;
413    return 0;
414}
415
416int set_autolock_timeout(const char *argv, struct screen_list *screen_list)
417{
418    if (screen_list->autolock_timeout == 0 ||
419        screen_list->autolock_timeout ==
420        ((long long unsigned int)0) - 1)
421    {
422        screen_list->autolock_timeout = atoi(argv) * 1000000;
423        /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
424        if (!screen_list->autolock_timeout)
425            screen_list->autolock_timeout -= 1;
426    }
427    return 0;
428}
429
430int set_lock_on_detach(const char *argv, struct screen_list *screen_list)
431{
432    if (IS_OPTION("true") || IS_OPTION("1"))
433        screen_list->lock_on_detach = 1;
434    else
435        screen_list->lock_on_detach = 0;
436    return 0;
437}
438
439int set_socket_dir(const char *argv, struct screen_list *screen_list)
440{
441    screen_list->socket_dir = argv;
442        return 0;
443}
444
445int set_delay(const char *argv, struct screen_list *screen_list)
446{
447    screen_list->requested_delay = atoi(argv);
448    screen_list->delay = atoi(argv);
449        return 0;
450}
Note: See TracBrowser for help on using the repository browser.