fb91a0085c0d36034a4d5a832f9598ead59d4e76
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

3)  * !version: 1.0.5! !date: 2010-12-22!
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>
32) #include <intern/net.h>
33) #include <intern/parse.h>
Stefan Schuermans v1.0.3

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

610)                  sz_config_file, errmsg);
611)     }