e2a21a2a7d8bad7a082a53134837a15c1bea740d
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

1) /*
2)  * FlexiPix library
Stefan Schuermans v1.0.6

Stefan Schuermans authored 13 years ago

3)  * !version: 1.0.6! !date: 2010-12-30!
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

4)  *
5)  * Copyright 2010 Stefan Schuermans <stefan schuermans info>
6)  *
7)  * This program is free software: you can redistribute it and/or modify
8)  * it under the terms of the GNU General Public License as published by
9)  * the Free Software Foundation, version 3 of the License.
10)  *
11)  *
12)  * This program is distributed in the hope that it will be useful,
13)  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14)  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15)  * GNU General Public License for more details.
16)  *
17)  * You should have received a copy of the GNU Lesser General Public License
18)  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19)  */
20) 
21) #include <errno.h>
22) #include <stdio.h>
23) #include <stdlib.h>
24) #include <string.h>
25) 
26) #include <flexipix/msg.h>
27) #include <flexipix/types.h>
28) #include <intern/const_data.h>
29) #include <intern/constants.h>
30) #include <intern/config.h>
31) #include <intern/mapping.h>
Stefan Schuermans v1.0.6

Stefan Schuermans authored 13 years ago

32) #include <intern/missing.h>
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

33) #include <intern/net.h>
34) #include <intern/parse.h>
Stefan Schuermans v1.0.3

Stefan Schuermans authored 13 years ago

35) #include <intern/strtod_noloc.h>
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

36) #include <intern/types.h>
37) 
38) /**
39)  * \brief process distributor from config file
40)  *
41)  * \param[in,out] p_ctx context information
42)  * \param[in] p_setting_part2 second half of setting to process
43)  * \param[in] p_value value of setting
44)  * \return 0 in case of success, -1 in case of error
45)  */
46) int flp_config_proc_distri(flp_config_ctx_t *p_ctx, char *p_setting_part2,
47)                            char *value)
48) {
49)   char *ptr;
50)   unsigned long val;
51)   unsigned int distri, out, pix, i;
52)   flp_distri_t *p_distri;
53) 
54)   /* get distributor number */
55)   val = strtoul(p_setting_part2, &ptr, 0);
56)   if (ptr == p_setting_part2 || *ptr != 0 || val >= FLP_DISTRI_MAX_CNT) {
57)     if (p_ctx->p_msg_func)
58)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
59)                         "invalid distributor number \"%s\""
60)                         " in line %u of config file\n",
61)                         p_setting_part2, p_ctx->line_no);
62)     return -1;
63)   }
64)   distri = (unsigned int)val;
65) 
66)   /* get number of outputs and pixels */
67)   if (flp_parse_two_nos(value, &out, &pix, &ptr) || *ptr != 0) {
68)     if (p_ctx->p_msg_func)
69)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
70)                         "invalid distributor size \"%s\""
71)                         " in line %u of config file\n",
72)                         value, p_ctx->line_no);
73)     return -1;
74)   }
75)   if (out >= FLP_OUTPUT_MAX_CNT) {
76)     if (p_ctx->p_msg_func)
77)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
78)                         "invalid number of outputs \"%u\""
79)                         " in line %u of config file\n",
80)                         out, p_ctx->line_no);
81)     return -1;
82)   }
83)   if (pix >= FLP_PIXEL_MAX_CNT) {
84)     if (p_ctx->p_msg_func)
85)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
86)                         "invalid number of pixels \"%u\""
87)                         " in line %u of config file\n",
88)                         pix, p_ctx->line_no);
89)     return -1;
90)   }
91) 
92)   /* check if distributor is already present */
93)   if (p_ctx->p_display->distri_ptrs[distri]) {
94)     if (p_ctx->p_msg_func)
95)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
96)                         "duplicate definition of distributor \"%u\""
97)                         " in line %u of config file\n",
98)                         distri, p_ctx->line_no);
99)     return -1;
100)   }
101) 
102)   /* create a new distributor */
103)   p_distri = (flp_distri_t *)malloc(sizeof (flp_distri_t));
104)   if (!p_distri) {
105)     if (p_ctx->p_msg_func)
106)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err, "out of memory\n");
107)     return -1;
108)   }
109)   p_distri->distri = distri;
110)   p_distri->output_cnt = out;
111)   p_distri->pixel_cnt = pix;
112)   /* initialize mapping information */
113)   for (i = 0; i < 3; i++) {
114)     p_distri->mapping[i].base = 0.0;
115)     p_distri->mapping[i].gamma = 1.0;
116)     p_distri->mapping[i].factor = 1.0;
117)     flp_mapping_precalc(&p_distri->mapping[i]);
118)   }
119)   /* create and initialize pixel array */
120)   p_distri->p_pixels =
121)     (flp_pixel_t *)malloc(out * pix * sizeof (flp_pixel_t));
122)   if (!p_distri->p_pixels) {
123)     free(p_distri);
124)     if (p_ctx->p_msg_func)
125)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err, "out of memory\n");
126)     return -1;
127)   }
128)   for (i = 0; i < out * pix; i++) {
129)     p_distri->p_pixels[i].x = -1;
130)     p_distri->p_pixels[i].y = -1;
131)   }
132)   /* create and initialize message buffer */
133)   p_distri->msg_len = FLP_MCUF_HDR_LEN + out * pix * 3;
134)   p_distri->p_msg_buf = (flp_u8_t *)malloc(p_distri->msg_len);
135)   if (!p_distri->p_msg_buf) {
136)     free(p_distri->p_pixels);
137)     free(p_distri);
138)     if (p_ctx->p_msg_func)
139)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err, "out of memory\n");
140)     return -1;
141)   }
142)   memset(p_distri->p_msg_buf, 0, p_distri->msg_len);
143)   memcpy(p_distri->p_msg_buf, flp_mcuf_hdr, FLP_MCUF_HDR_LEN);
144)   p_distri->p_msg_buf[FLP_MCUF_HDR_OFS_OUTPUTS] = (flp_u8_t)out;
145)   p_distri->p_msg_buf[FLP_MCUF_HDR_OFS_PIXELS] = (flp_u8_t)pix;
146)   /* store pointer to distributor */
147)   p_ctx->p_display->distri_ptrs[distri] = p_distri;
148) 
149)   /* count distributors */
150)   p_ctx->p_display->distri_cnt++;
151) 
152)   return 0;
153) }
154) 
155) /**
156)  * \brief process mapping from config file
157)  *
158)  * \param[in,out] p_ctx context information
159)  * \param[in] p_setting_part2 second half of setting to process
160)  * \param[in] p_value value of setting
161)  * \return 0 in case of success, -1 in case of error
162)  */
163) int flp_config_proc_mapping(flp_config_ctx_t *p_ctx, char *p_setting_part2,
164)                             char *value)
165) {
166)   char *ptr, *ptr2;
167)   unsigned long val;
168)   unsigned int distri, chan;
169)   flp_distri_t *p_distri;
170)   double base, factor, gamma;
171) 
172)   /* get distributor number */
173)   val = strtoul(p_setting_part2, &ptr, 0);
174)   if (ptr == p_setting_part2
175)       || (*ptr != 0 && *ptr != ' ' && *ptr != '\t'
176)           && *ptr != '\r' && *ptr != '\n')) {
177)     if (p_ctx->p_msg_func)
178)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
179)                         "invalid mapping specifier \"%s\""
180)                         " in line %u of config file\n",
181)                         p_setting_part2, p_ctx->line_no);
182)     return -1;
183)   }
184)   distri = (unsigned int)val;
185)   if (distri >= FLP_DISTRI_MAX_CNT) {
186)     if (p_ctx->p_msg_func)
187)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
188)                         "invalid distributor number \"%u\""
189)                         " in line %u of config file\n",
190)                         distri, p_ctx->line_no);
191)     return -1;
192)   }
193) 
194)   /* get channel */
195)   while (*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n')
196)     ptr++;
197)   if (!strcmp(ptr, "red"))
198)     chan = 0;
199)   else if (!strcmp(ptr, "green"))
200)     chan = 1;
201)   else if (!strcmp(ptr, "blue"))
202)     chan = 2;
203)   else {
204)     if (p_ctx->p_msg_func)
205)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
206)                         "invalid channel \"%s\""
207)                         " in line %u of config file\n", ptr,
208)                         p_ctx->line_no);
209)     return -1;
210)   }
211) 
212)   /* get distributor */
213)   p_distri = p_ctx->p_display->distri_ptrs[distri];
214)   if (!p_distri) {
215)     if (p_ctx->p_msg_func)
216)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
217)                         "no distributor with number \"%u\""
218)                         " in line %u of config file\n",
219)                         distri, p_ctx->line_no);
220)     return -1;
221)   }
222) 
223)   /* get mapping parameters: base, factor, gamma */
Stefan Schuermans v1.0.3

Stefan Schuermans authored 13 years ago

224)   base = flp_strtod_noloc(value, &ptr);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

225)   if (ptr == value
226)       || (*ptr != 0 && *ptr != ' ' && *ptr != '\t'
227)           && *ptr != '\r' && *ptr != '\n')) {
228)     if (p_ctx->p_msg_func)
229)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
230)                         "invalid mapping parameters \"%s\""
231)                         " in line %u of config file\n",
232)                         value, p_ctx->line_no);
233)     return -1;
234)   }
Stefan Schuermans v1.0.3

Stefan Schuermans authored 13 years ago

235)   factor = flp_strtod_noloc(ptr, &ptr2);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

236)   if (ptr2 == ptr
237)       || (*ptr2 != 0 && *ptr2 != ' ' && *ptr2 != '\t'
238)           && *ptr2 != '\r' && *ptr2 != '\n')) {
239)     if (p_ctx->p_msg_func)
240)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
241)                         "invalid mapping parameters \"%s\""
242)                         " in line %u of config file\n",
243)                         value, p_ctx->line_no);
244)     return -1;
245)   }
Stefan Schuermans v1.0.3

Stefan Schuermans authored 13 years ago

246)   gamma = flp_strtod_noloc(ptr2, &ptr);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

247)   if (ptr == ptr2
248)       || (*ptr != 0 && *ptr != ' ' && *ptr != '\t'
249)           && *ptr != '\r' && *ptr != '\n')) {
250)     if (p_ctx->p_msg_func)
251)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
252)                         "invalid mapping parameters \"%s\""
253)                         " in line %u of config file\n",
254)                         value, p_ctx->line_no);
255)     return -1;
256)   }
257)   if (gamma <= 0.0) {
258)     if (p_ctx->p_msg_func)
259)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
260)                         "invalid gamma value \"%f\""
261)                         " in line %u of config file\n",
262)                         gamma, p_ctx->line_no);
263)     return -1;
264)   }
265) 
266)   /* store new mapping parameters and re-calculate mapping table */
267)   p_distri->mapping[chan].base = base;
268)   p_distri->mapping[chan].factor = factor;
269)   p_distri->mapping[chan].gamma = gamma;
270)   flp_mapping_precalc(&p_distri->mapping[chan]);
271) 
272)   return 0;
273) }
274) 
275) /**
276)  * \brief process pixel from config file
277)  *
278)  * \param[in,out] p_ctx context information
279)  * \param[in] sz_pixel text of pixel to process
280)  * \param[in] distri number of distributor
281)  * \param[in] out number of output
282)  * \param[in] pix number of pixel
283)  * \return 0 in case of success, -1 in case of error
284)  */
285) int flp_config_proc_pixel(flp_config_ctx_t *p_ctx, char *sz_pixel,
286)                           unsigned int distri, unsigned int out,
287)                           unsigned int pix)
288) {
289)   flp_distri_t *p_distri = p_ctx->p_display->distri_ptrs[distri];
290)   char *ptr;
291)   unsigned int x, y, idx;
292) 
293)   /* get coordinates of pixel */
294)   if (flp_parse_two_nos(sz_pixel, &x, &y, &ptr) || *ptr != 0
295)       || (int)x < 0 || (int)x >= p_ctx->p_display->size.x
296)       || (int)y < 0 || (int)y >= p_ctx->p_display->size.y) {
297)     if (p_ctx->p_msg_func)
298)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
299)                         "invalid pixel \"%s\""
300)                         " in line %u of config file\n",
301)                         sz_pixel, p_ctx->line_no);
302)     return -1;
303)   }
304) 
305)   /* check pixel number */
306)   if (pix >= FLP_PIXEL_MAX_CNT || pix >= p_distri->pixel_cnt) {
307)     if (p_ctx->p_msg_func)
308)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
309)                         "too many pixels (more than %u)"
310)                         " in line %u of config file\n",
311)                         p_distri->pixel_cnt, p_ctx->line_no);
312)     return -1;
313)   }
314) 
315)   /* check that pixel is not yet set */
316)   idx = out * p_distri->pixel_cnt + pix;
317)   if (p_distri->p_pixels[idx].x >= 0
318)       && p_distri->p_pixels[idx].y >= 0) {
319)     if (p_ctx->p_msg_func)
320)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
321)                         "pixel %u of output %u of distributor %u already set"
322)                         " to pixel %u,%u in line %u of config file\n",
323)                         pix, out, distri, p_distri->p_pixels[idx].x,
324)                  p_distri->p_pixels[idx].y, p_ctx->line_no);
325)     return -1;
326)   }
327) 
328)   /* set pixel coordinates */
329)   p_distri->p_pixels[idx].x = x;
330)   p_distri->p_pixels[idx].y = y;
331) 
332)   /* count pixels in total */
333)   p_ctx->p_display->pixel_cnt++;
334) 
335)   return 0;
336) }
337) 
338) /**
339)  * \brief process output from config file
340)  *
341)  * \param[in,out] p_ctx context information
342)  * \param[in] p_setting_part2 second half of setting to process
343)  * \param[in] p_value value of setting
344)  * \return 0 in case of success, -1 in case of error
345)  */
346) int flp_config_proc_output(flp_config_ctx_t *p_ctx, char *p_setting_part2,
347)                            char *value)
348) {
349)   char *ptr, *p_pos, *p_white, white;
350)   unsigned int distri, out, pix;
351)   flp_distri_t *p_distri;
352)   int err;
353) 
354)   /* get number of distributor and output */
355)   if (flp_parse_two_nos(p_setting_part2, &distri, &out, &ptr) || *ptr != 0) {
356)     if (p_ctx->p_msg_func)
357)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
358)                         "invalid output specifier \"%s\""
359)                         " in line %u of config file\n",
360)                         p_setting_part2, p_ctx->line_no);
361)     return -1;
362)   }
363)   if (distri >= FLP_DISTRI_MAX_CNT) {
364)     if (p_ctx->p_msg_func)
365)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
366)                         "invalid distributor number \"%u\""
367)                         " in line %u of config file\n",
368)                         distri, p_ctx->line_no);
369)     return -1;
370)   }
371)   if (out >= FLP_OUTPUT_MAX_CNT) {
372)     if (p_ctx->p_msg_func)
373)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
374)                         "invalid output number \"%u\""
375)                         " in line %u of config file\n",
376)                         out, p_ctx->line_no);
377)     return -1;
378)   }
379) 
380)   /* get distributor */
381)   p_distri = p_ctx->p_display->distri_ptrs[distri];
382)   if (!p_distri) {
383)     if (p_ctx->p_msg_func)
384)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
385)                         "no distributor with number \"%u\""
386)                         " in line %u of config file\n",
387)                         distri, p_ctx->line_no);
388)     return -1;
389)   }
390)   /* check output number */
391)   if (out >= p_distri->output_cnt) {
392)     if (p_ctx->p_msg_func)
393)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
394)                         "no output with output number \"%u\""
395)                         " in line %u of config file\n",
396)                         out, p_ctx->line_no);
397)     return -1;
398)   }
399) 
400)   /* count outputs */
401)   p_ctx->p_display->output_cnt++;
402) 
403)   /* process pixels */
404) 
405)   /* process all parts separated by whitespace */
406)   p_pos = value;
407)   err = 0;
408)   pix = 0;
409)   while (*p_pos != 0) {
410) 
411)     /* get end of item (first whitespace) */
412)     for (p_white = p_pos;
413)          *p_white && *p_white != ' ' && *p_white != '\t'
414)          && *p_white != '\r' && *p_white != '\n'; p_white++);
415) 
416)     /* process item: a pixel */
417)     white = *p_white; /* terminate item */
418)     *p_white = 0;
419)     if (flp_config_proc_pixel(p_ctx, p_pos, distri, out, pix)) /* process */
420)       err = -1;       /* remember errors */
421)     pix++;            /* count pixels */
422)     *p_white = white; /* undo termination */
423) 
424)     /* skip whitespace and continue after it */
425)     for (;
426)          *p_white == ' ' || *p_white == '\t'
427)          || *p_white == '\r' || *p_white == '\n'; p_white++);
428)     p_pos = p_white;
429) 
430)   } /* while (*p_pos != 0) */
431) 
432)   return err;
433) }
434) 
435) /**
436)  * \brief process setting from config file
437)  *
438)  * \param[in,out] p_ctx context information
439)  * \param[in] p_setting setting to process
440)  * \param[in] p_value value of setting
441)  * \return 0 in case of success, -1 in case of error
442)  */
443) int flp_config_proc_setting(flp_config_ctx_t *p_ctx, char *p_setting,
444)                             char *p_value)
445) {
446)   char *ptr;
447)   unsigned int x, y;
448) 
449)   /* replace all whitespace with spaces in setting */
450)   while ((ptr = strchr(p_setting, '\t')))
451)     *ptr = ' ';
452)   while ((ptr = strchr(p_setting, '\r')))
453)     *ptr = ' ';
454)   while ((ptr = strchr(p_setting, '\n')))
455)     *ptr = ' ';
456) 
457)   /* bind address for UDP output */
458)   if (!strcmp(p_setting, "bindAddr")) {
459)     if (flp_parse_addr(p_value, &p_ctx->p_display->bind_addr)) {
460)       if (p_ctx->p_msg_func)
461)         p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
462)                           "invalid address \"%s\" for \"%s\""
463)                           " in line %u of config file\n",
464)                           p_value, p_setting, p_ctx->line_no);
465)       return -1;
466)     }
467)     if (p_ctx->p_msg_func)
468)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_info, "bind address: %s\n", p_value);
469)     return 0;
470)   }
471) 
472)   /* size of display */
473)   if (!strcmp(p_setting, "size")) {
474)     if (flp_parse_two_nos(p_value, &x, &y, &ptr)
475)         || (int)x <= 0 || (int)y <= 0) {
476)       if (p_ctx->p_msg_func)
477)         p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
478)                           "invalid value \"%s\" for \"%s\""
479)                           " in line %u of config file\n",
480)                           p_value, p_setting, p_ctx->line_no);
481)       return -1;
482)     }
483)     p_ctx->p_display->size.x = x;
484)     p_ctx->p_display->size.y = y;
485)     return 0;
486)   }
487) 
488)   /* distributor */
489)   if (!strncmp(p_setting, "distributor ", 12))
490)     return flp_config_proc_distri(p_ctx, p_setting + 12, p_value);
491) 
492)   /* mapping */
493)   if (!strncmp(p_setting, "mapping ", 8))
494)     return flp_config_proc_mapping(p_ctx, p_setting + 8, p_value);
495) 
496)   /* output */
497)   if (!strncmp(p_setting, "output ", 7))
498)     return flp_config_proc_output(p_ctx, p_setting + 7, p_value);
499) 
500)   /* unknown setting */
501)   if (p_ctx->p_msg_func)
502)     p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_warn,
503)                       "unknown setting \"%s\""
504)                       " in line %u of config file, ignored\n",
505)                       p_setting, p_ctx->line_no);
506)   return 0;
507) }
508) 
509) /**
510)  * \brief process line from config file
511)  *
512)  * \param[in,out] p_ctx context information
513)  * \param[in] p_line line to process
514)  * \return 0 in case of success, -1 in case of error
515)  */
516) int flp_config_proc_line(flp_config_ctx_t *p_ctx, char *p_line)
517) {
518)   char *p_hash, *p_equal, *p_setting, *p_value;
519)   int i;
520) 
521)   /* remove comment */
522)   p_hash = strchr(p_line, '#');
523)   if (p_hash)
524)     *p_hash = 0;
525) 
526)   /* remove trailing whitespace */
527)   for (i = strlen(p_line) - 1;
528)        i >= 0 && (p_line[i] == ' ' || p_line[i] == '\t'
529)                   || p_line[i] == '\r' || p_line[i] == '\n'); i--)
530)     p_line[i] = 0;
531) 
532)   /* remove leading whitespace */
533)   for (; *p_line == ' ' || *p_line == '\t'
534)          || *p_line == '\r' || *p_line == '\n'; p_line++);
535) 
536)   /* ignore empty line */
537)   if (!p_line[0])
538)     return 0;
539) 
540)   /* find equal sign */
541)   p_equal = strchr(p_line, '=');
542)   if (!p_equal) {               /* no equal sign found */
543)     if (p_ctx->p_msg_func)
544)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_warn,
545)                         "invalid line %u in config file, ignored\n",
546)                         p_ctx->line_no);
547)     return 0;
548)   }
549) 
550)   /* split string at equal sign */
551)   *p_equal = 0;
552)   p_setting = p_line;
553)   p_value = p_equal + 1;
554) 
555)   /* remove trailing whitespaces in setting name */
556)   for (i = strlen(p_setting) - 1;
557)        i >= 0 && (p_setting[i] == ' ' || p_setting[i] == '\t'
558)                   || p_setting[i] == '\r' || p_setting[i] == '\n'); i--)
559)     p_setting[i] = 0;
560) 
561)   /* remove leading whitespaces in value */
562)   for (; *p_value == ' ' || *p_value == '\t'
563)          || *p_value == '\r' || *p_value == '\n'; p_value++);
564) 
565)   /* process setting */
566)   return flp_config_proc_setting(p_ctx, p_setting, p_value);
567) }
568) 
569) /**
570)  * \brief process config file
571)  *
572)  * \param[in,out] p_display display to configure
573)  * \param[in] sz_config_file name of config file to read
574)  * \param[in] p_msg_func message callback function or NULL
575)  * \param[in] p_msg_ctx user context for message callback
576)  * \return 0 in case of success, -1 in case of error
577)  */
578) int flp_config_proc_file(flp_display_t *p_display,
579)                          const char *sz_config_file,
580)                          flp_msg_func_p_t p_msg_func, void *p_msg_ctx)
581) {
582)   flp_config_ctx_t ctx;
583)   FILE *file;
584) 
585)   /* set up context */
586)   ctx.p_display = p_display;
587)   ctx.p_msg_func = p_msg_func;
588)   ctx.p_msg_ctx = p_msg_ctx;
589) 
590)   /* check if file is present */
591)   if (!sz_config_file || !sz_config_file[0]) {
592)     if (p_msg_func)
593)       p_msg_func(p_msg_ctx, flp_msg_type_err,
594)                  "no config file specified\n");
595)     return -1;
596)   }
597) 
598)   if (p_msg_func)
599)     p_msg_func(p_msg_ctx, flp_msg_type_info,
600)                "using config file \"%s\"\n",
601)                sz_config_file);
602) 
603)   /* open file */
604)   file = fopen(sz_config_file, "rt");
605)   if (!file) {
Stefan Schuermans v1.0.2

Stefan Schuermans authored 13 years ago

606)     if (p_msg_func) {
607)       char errmsg[256];
608)       strerror_r(errno, errmsg, sizeof(errmsg));
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

609)       p_msg_func(p_msg_ctx, flp_msg_type_err,
610)                  "cannot open config file \"%s\" for reading: %s\n",
Stefan Schuermans v1.0.2

Stefan Schuermans authored 13 years ago

611)                  sz_config_file, errmsg);
612)     }