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

Last change on this file since 2587 was 2587, checked in by Pascal Terjan, 13 years ago
  • Ensure screen_list->config is NULL when there is no config file
File size: 7.2 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: neercs.h 2458 2008-06-19 21:50:29Z pterjan $
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        printf("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                    printf("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                    printf("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        option->next = NULL;
169        l-=end_spaces;
170        line = realloc(line, l+1);
171        line[l] = 0;
172
173        get_key_value(line, option);
174
175        if(!screen_list->config)
176            screen_list->config = option;
177
178        if(prev)
179            prev->next = option;
180
181        prev = option;
182    }
183    free(line);
184    return s;
185}
186
187int get_key_value(char *line, struct option *option)
188{
189    unsigned int i, o = 0, b=0, end_spaces = 0;
190    char *cur = NULL;
191    option->value = NULL;
192    option->key = NULL;
193
194    /* Line is a section delimiter */
195    if(line[0] == '[')
196    {
197        option->value = malloc(strlen(line) - 1);
198        memcpy(option->value, line+1, strlen(line) - 1);
199        option->value[strlen(line) - 2] = 0;
200        return 0;
201    }
202
203    cur = malloc(1);
204    cur[0] = 0;
205
206    for(i=0; i<strlen(line); i++)
207    {
208        if(line[i] == ' ' && !b) continue;
209
210
211        if(line[i] == '=')
212        {
213            b = 0;
214            cur[o-end_spaces] = 0;
215            cur = realloc(cur, (o-end_spaces)+1);
216            o = 0;
217            option->key = cur;
218            cur = malloc(1);
219        }
220        else
221        {
222            if(line[i] == ' ') end_spaces++;
223            else end_spaces = 0;
224
225            cur = realloc(cur, o+2);
226            if(!cur)
227            {
228                printf("Can't allocate memory at %s:%d\n",
229                       __FUNCTION__, __LINE__);
230            }
231            cur[o]   = line[i];
232            o++;
233            b = 1;
234
235        }
236    }
237    cur[o] = 0;
238    option->value = cur;
239    return 0;
240}
241
242
243#define IS_TOKEN(t) (!strncmp(option->key, t, strlen(option->key)))
244#define IS_VALUE(t) (!strncmp(option->value, t, strlen(option->value)))
245
246
247int fill_config(struct screen_list *screen_list)
248{
249    int i = 0;
250    struct option *option = screen_list->config;
251    char *section = NULL;
252
253    while(option)
254    {
255        if(option->key == NULL)
256        {
257            section = option->key;
258            option = option->next;
259            continue;
260        }
261
262        if(IS_TOKEN("window_manager"))
263        {
264            if     (IS_VALUE("full"))   screen_list->wm_type = WM_FULL;
265            else if(IS_VALUE("hsplit")) screen_list->wm_type = WM_HSPLIT;
266            else if(IS_VALUE("vsplit")) screen_list->wm_type = WM_VSPLIT;
267            else if(IS_VALUE("card"))   screen_list->wm_type = WM_CARD;
268
269            else fprintf(stderr, "Unknown window manager '%s'\n", option->key);
270
271        } else if(IS_TOKEN("thumbnails"))
272        {
273            if     (IS_VALUE("true") || IS_VALUE("1")) screen_list->mini = 1;
274            else                                       screen_list->mini = 0;
275
276        } else if(IS_TOKEN("status_bar"))
277        {
278            if     (IS_VALUE("true") || IS_VALUE("1")) screen_list->status = 1;
279            else                                       screen_list->status = 0;
280
281        } else if(IS_TOKEN("screensaver_timeout"))
282        {
283            screen_list->screensaver_timeout = atoi(option->value) * 1000000;
284            /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
285            if(!screen_list->screensaver_timeout) screen_list->screensaver_timeout-=1;
286        }  else if(IS_TOKEN("autolock_timeout"))
287        {
288            screen_list->autolock_timeout = atoi(option->value) * 1000000;
289            /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
290            if(!screen_list->autolock_timeout) screen_list->autolock_timeout-=1;
291        } else if(IS_TOKEN("socket_dir"))
292        {
293            screen_list->socket_dir = option->value;
294        } else
295        {
296            fprintf(stderr, "Unknown option '%s'\n", option->key);
297        }
298        option = option->next;
299    }
300
301    return i;
302}
Note: See TracBrowser for help on using the repository browser.