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

Last change on this file since 3961 was 3961, checked in by jylam, 4 years ago
  • Better testing cases for autolock_timeout
  • Property svn:keywords set to Id
File size: 8.7 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$
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__, __LINE__);
62        return -1;
63    }
64    /* Read it */
65    while((i = fread(buffer+total, 1, size, fp)) > 0)
66    {
67        total+=i;
68    }
69    buffer[total] = '\n';
70
71    fclose(fp);
72
73    i=0;
74
75    /* Parse it */
76    while((i = parse_conf_line(buffer + offset, total-offset, screen_list)) > 0)
77    {
78        offset+=i;
79        l++;
80    }
81
82    free(buffer);
83
84    /* Fill neercs configuration with it */
85    fill_config(screen_list);
86
87    return 1;
88}
89
90
91int parse_conf_line(char *buf, int size, struct screen_list *screen_list)
92{
93    int i, s = 0, eol = 0, c = 0;
94    char *line = NULL;
95    int l = 0;
96    int in_quote = 0, end_spaces = 0;
97    static struct option *prev = NULL;
98
99    if(size <= 0) return -1;
100
101    /* Find EOL  */
102    for(i=0; i<size; i++)
103    {
104        if(buf[i] == '\n')
105        {
106            s = i + 1;
107            break;
108        }
109    }
110
111    /* Strip comments and trailing spaces */
112    for(i=0; i<s; i++)
113    {
114        if(buf[i] == ';' && !in_quote)
115        {
116            eol = i;
117            break;
118        }
119        else if(buf[i] == '\n')
120        {
121            eol = i;
122            break;
123        }
124        else if(buf[i] == ' ' && !c) {}
125        else
126        {
127            if(line == NULL)
128            {
129                line = malloc(2);
130                if(!line)
131                {
132                    fprintf(stderr, "Can't allocate memory at %s:%d\n",
133                           __FUNCTION__, __LINE__);
134                    return -1;
135                }
136            }
137            else
138            {
139                line = realloc(line, l+2);
140                if(!line)
141                {
142                    fprintf(stderr, "Can't allocate memory at %s:%d\n",
143                           __FUNCTION__, __LINE__);
144                    return -1;
145                }
146            }
147            if(buf[i] == '"')
148                in_quote = !in_quote;
149            if(buf[i] == ' ')
150                end_spaces++;
151            else
152                end_spaces = 0;
153
154            line[l]   = buf[i];
155            line[l+1] = 0;
156            l++;
157            c = 1;
158        }
159    }
160
161    if(c==0)
162    {
163        /* This line is empty, do nothing */
164    }
165    else
166    {
167        struct option *option = malloc(sizeof(struct option));
168        if(!option)
169        {
170            fprintf(stderr, "Can't allocate memory at %s:%d\n",
171                   __FUNCTION__, __LINE__);
172            return -1;
173        }
174        option->next = NULL;
175        l-=end_spaces;
176        line = realloc(line, l+1);
177        line[l] = 0;
178
179        get_key_value(line, option);
180
181        if(!screen_list->config)
182            screen_list->config = option;
183
184        if(prev)
185            prev->next = option;
186
187        prev = option;
188    }
189    free(line);
190    return s;
191}
192
193int get_key_value(char *line, struct option *option)
194{
195    unsigned int i, o = 0, b=0, end_spaces = 0;
196    char *cur = NULL;
197    option->value = NULL;
198    option->key = NULL;
199
200    /* Line is a section delimiter */
201    if(line[0] == '[')
202    {
203        option->value = malloc(strlen(line) - 1);
204        if(!option->value)
205        {
206            fprintf(stderr, "Can't allocate memory at %s:%d\n",
207                    __FUNCTION__, __LINE__);
208            return -1;
209        }
210        memcpy(option->value, line+1, strlen(line) - 1);
211        option->value[strlen(line) - 2] = 0;
212        return 0;
213    }
214
215    cur = malloc(1);
216    if(!cur)
217    {
218        fprintf(stderr, "Can't allocate memory at %s:%d\n",
219                __FUNCTION__, __LINE__);
220        return -1;
221    }
222    cur[0] = 0;
223
224    for(i=0; i<strlen(line); i++)
225    {
226        if(line[i] == ' ' && !b) continue;
227
228
229        if(line[i] == '=')
230        {
231            b = 0;
232            cur[o-end_spaces] = 0;
233            cur = realloc(cur, (o-end_spaces)+1);
234            if(!cur)
235            {
236                fprintf(stderr, "Can't allocate memory at %s:%d\n",
237                       __FUNCTION__, __LINE__);
238                return -1;
239            }
240            o = 0;
241            option->key = cur;
242            cur = malloc(1);
243        }
244        else
245        {
246            if(line[i] == ' ') end_spaces++;
247            else end_spaces = 0;
248
249            cur = realloc(cur, o+2);
250            if(!cur)
251            {
252                fprintf(stderr, "Can't allocate memory at %s:%d\n",
253                       __FUNCTION__, __LINE__);
254                return -1;
255            }
256            cur[o]   = line[i];
257            o++;
258            b = 1;
259
260        }
261    }
262    cur[o] = 0;
263    option->value = cur;
264    return 0;
265}
266
267
268#define IS_TOKEN(t) (!strncmp(option->key, t, strlen(option->key)))
269#define IS_VALUE(t) (!strncmp(option->value, t, strlen(option->value)))
270
271
272int fill_config(struct screen_list *screen_list)
273{
274    int i = 0;
275    struct option *option = screen_list->config;
276    char *section = NULL;
277
278    while(option)
279    {
280        if(option->key == NULL)
281        {
282            section = option->key;
283            option = option->next;
284            continue;
285        }
286
287        if(IS_TOKEN("window_manager"))
288        {
289            if     (IS_VALUE("full"))   screen_list->wm_type = WM_FULL;
290            else if(IS_VALUE("hsplit")) screen_list->wm_type = WM_HSPLIT;
291            else if(IS_VALUE("vsplit")) screen_list->wm_type = WM_VSPLIT;
292            else if(IS_VALUE("card"))   screen_list->wm_type = WM_CARD;
293            else if(IS_VALUE("cube"))   screen_list->wm_type = WM_CUBE;
294            else fprintf(stderr, "Unknown window manager '%s'\n", option->key);
295
296        } else if(IS_TOKEN("cube_duration"))
297        {
298           screen_list->cube.duration = atoi(option->value) * 1000000;
299        } else if(IS_TOKEN("thumbnails"))
300        {
301            if     (IS_VALUE("true") || IS_VALUE("1")) screen_list->mini = 1;
302            else                                       screen_list->mini = 0;
303
304        } else if(IS_TOKEN("status_bar"))
305        {
306            if     (IS_VALUE("true") || IS_VALUE("1")) screen_list->status = 1;
307            else                                       screen_list->status = 0;
308
309        } else if(IS_TOKEN("screensaver_timeout"))
310        {
311            screen_list->screensaver_timeout = atoi(option->value) * 1000000;
312            /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
313            if(!screen_list->screensaver_timeout) screen_list->screensaver_timeout-=1;
314        }  else if(IS_TOKEN("autolock_timeout"))
315        {
316            debug("Autolock is %d\n", screen_list->autolock_timeout);
317            if(screen_list->autolock_timeout == 0 ||
318               screen_list->autolock_timeout == ((long long unsigned int)0) - 1)
319            {
320                screen_list->autolock_timeout = atoi(option->value) * 1000000;
321                /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
322                if(!screen_list->autolock_timeout) screen_list->autolock_timeout-=1;
323            }
324        }  else if(IS_TOKEN("lock_on_detach"))
325        {
326            if     (IS_VALUE("true") || IS_VALUE("1")) screen_list->lock_on_detach = 1;
327            else                                       screen_list->lock_on_detach = 0;
328        } else if(IS_TOKEN("socket_dir"))
329        {
330            screen_list->socket_dir = option->value;
331        } else if(IS_TOKEN("delay"))
332        {
333            screen_list->requested_delay = atoi(option->value);
334            screen_list->delay = atoi(option->value);
335        } else
336        {
337            fprintf(stderr, "Unknown option '%s'\n", option->key);
338        }
339        option = option->next;
340    }
341
342    return i;
343}
Note: See TracBrowser for help on using the repository browser.