0e2d779263ff44b9802d44fbe21ce524964304d1
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

1) /*
2)  * FlexiPix library
3)  *
Stefan Schuermans removed version information...

Stefan Schuermans authored 13 years ago

4)  * Copyright 2010-2011 Stefan Schuermans <stefan schuermans info>
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

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,
Stefan Schuermans value -> p_value for consis...

Stefan Schuermans authored 7 years ago

46)                            char *p_value)
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

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 */
Stefan Schuermans value -> p_value for consis...

Stefan Schuermans authored 7 years ago

66)   if (flp_parse_two_nos(p_value, &out, &pix, &ptr) || *ptr != 0) {
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

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",
Stefan Schuermans value -> p_value for consis...

Stefan Schuermans authored 7 years ago

71)                         p_value, p_ctx->line_no);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

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;
Stefan Schuermans add support for configuring...

Stefan Schuermans authored 7 years ago

111)   /* initialize address to default */
112)   p_distri->addr.sin_family = AF_INET;
113)   p_distri->addr.sin_addr.s_addr = htonl(FLP_DEST_IP_BASE +
114)                                          p_distri->distri * FLP_DEST_IP_STEP);
115)   p_distri->addr.sin_port = htons(FLP_DEST_PORT);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

116)   /* initialize mapping information */
117)   for (i = 0; i < 3; i++) {
118)     p_distri->mapping[i].base = 0.0;
119)     p_distri->mapping[i].gamma = 1.0;
120)     p_distri->mapping[i].factor = 1.0;
121)     flp_mapping_precalc(&p_distri->mapping[i]);
122)   }
123)   /* create and initialize pixel array */
124)   p_distri->p_pixels =
125)     (flp_pixel_t *)malloc(out * pix * sizeof (flp_pixel_t));
126)   if (!p_distri->p_pixels) {
127)     free(p_distri);
128)     if (p_ctx->p_msg_func)
129)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err, "out of memory\n");
130)     return -1;
131)   }
132)   for (i = 0; i < out * pix; i++) {
133)     p_distri->p_pixels[i].x = -1;
134)     p_distri->p_pixels[i].y = -1;
135)   }
136)   /* create and initialize message buffer */
137)   p_distri->msg_len = FLP_MCUF_HDR_LEN + out * pix * 3;
138)   p_distri->p_msg_buf = (flp_u8_t *)malloc(p_distri->msg_len);
139)   if (!p_distri->p_msg_buf) {
140)     free(p_distri->p_pixels);
141)     free(p_distri);
142)     if (p_ctx->p_msg_func)
143)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err, "out of memory\n");
144)     return -1;
145)   }
146)   memset(p_distri->p_msg_buf, 0, p_distri->msg_len);
147)   memcpy(p_distri->p_msg_buf, flp_mcuf_hdr, FLP_MCUF_HDR_LEN);
148)   p_distri->p_msg_buf[FLP_MCUF_HDR_OFS_OUTPUTS] = (flp_u8_t)out;
149)   p_distri->p_msg_buf[FLP_MCUF_HDR_OFS_PIXELS] = (flp_u8_t)pix;
150)   /* store pointer to distributor */
151)   p_ctx->p_display->distri_ptrs[distri] = p_distri;
152) 
153)   /* count distributors */
154)   p_ctx->p_display->distri_cnt++;
155) 
156)   return 0;
157) }
158) 
Stefan Schuermans add support for configuring...

Stefan Schuermans authored 7 years ago

159) /**
160)  * \brief process distributor address from config file
161)  *
162)  * \param[in,out] p_ctx context information
163)  * \param[in] p_setting_part2 second half of setting to process
164)  * \param[in] p_value value of setting
165)  * \return 0 in case of success, -1 in case of error
166)  */
167) int flp_config_proc_distri_addr(flp_config_ctx_t *p_ctx, char *p_setting_part2,
168)                                 char *p_value)
169) {
170)   char *ptr;
171)   unsigned long val;
172)   unsigned int distri;
173)   flp_distri_t *p_distri;
174) 
175)   /* get distributor number */
176)   val = strtoul(p_setting_part2, &ptr, 0);
Stefan Schuermans stricter parsing for distri...

Stefan Schuermans authored 7 years ago

177)   if (ptr == p_setting_part2 || *ptr != 0) {
Stefan Schuermans add support for configuring...

Stefan Schuermans authored 7 years ago

178)     if (p_ctx->p_msg_func)
179)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
180)                         "invalid mapping specifier \"%s\""
181)                         " in line %u of config file\n",
182)                         p_setting_part2, p_ctx->line_no);
183)     return -1;
184)   }
185)   distri = (unsigned int)val;
186)   if (distri >= FLP_DISTRI_MAX_CNT) {
187)     if (p_ctx->p_msg_func)
188)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
189)                         "invalid distributor number \"%u\""
190)                         " in line %u of config file\n",
191)                         distri, p_ctx->line_no);
192)     return -1;
193)   }
194) 
195)   /* get distributor */
196)   p_distri = p_ctx->p_display->distri_ptrs[distri];
197)   if (!p_distri) {
198)     if (p_ctx->p_msg_func)
199)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
200)                         "no distributor with number \"%u\""
201)                         " in line %u of config file\n",
202)                         distri, p_ctx->line_no);
203)     return -1;
204)   }
205) 
206)   /* get address */
207)   if (flp_parse_addr(p_value, &p_distri->addr)) {
208)     if (p_ctx->p_msg_func)
209)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
210)                         "invalid address \"%s\" for distributor with number"
211)                         " \"%u\" in line %u of config file\n",
212)                         p_value, distri, p_ctx->line_no);
213)     return -1;
214)   }
215) 
216)   return 0;
217) }
218) 
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

219) /**
220)  * \brief process mapping from config file
221)  *
222)  * \param[in,out] p_ctx context information
223)  * \param[in] p_setting_part2 second half of setting to process
224)  * \param[in] p_value value of setting
225)  * \return 0 in case of success, -1 in case of error
226)  */
227) int flp_config_proc_mapping(flp_config_ctx_t *p_ctx, char *p_setting_part2,
Stefan Schuermans value -> p_value for consis...

Stefan Schuermans authored 7 years ago

228)                             char *p_value)
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

229) {
230)   char *ptr, *ptr2;
231)   unsigned long val;
232)   unsigned int distri, chan;
233)   flp_distri_t *p_distri;
234)   double base, factor, gamma;
235) 
236)   /* get distributor number */
237)   val = strtoul(p_setting_part2, &ptr, 0);
238)   if (ptr == p_setting_part2
239)       || (*ptr != 0 && *ptr != ' ' && *ptr != '\t'
240)           && *ptr != '\r' && *ptr != '\n')) {
241)     if (p_ctx->p_msg_func)
242)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
243)                         "invalid mapping specifier \"%s\""
244)                         " in line %u of config file\n",
245)                         p_setting_part2, p_ctx->line_no);
246)     return -1;
247)   }
248)   distri = (unsigned int)val;
249)   if (distri >= FLP_DISTRI_MAX_CNT) {
250)     if (p_ctx->p_msg_func)
251)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
252)                         "invalid distributor number \"%u\""
253)                         " in line %u of config file\n",
254)                         distri, p_ctx->line_no);
255)     return -1;
256)   }
257) 
258)   /* get channel */
259)   while (*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n')
260)     ptr++;
261)   if (!strcmp(ptr, "red"))
262)     chan = 0;
263)   else if (!strcmp(ptr, "green"))
264)     chan = 1;
265)   else if (!strcmp(ptr, "blue"))
266)     chan = 2;
267)   else {
268)     if (p_ctx->p_msg_func)
269)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
270)                         "invalid channel \"%s\""
271)                         " in line %u of config file\n", ptr,
272)                         p_ctx->line_no);
273)     return -1;
274)   }
275) 
276)   /* get distributor */
277)   p_distri = p_ctx->p_display->distri_ptrs[distri];
278)   if (!p_distri) {
279)     if (p_ctx->p_msg_func)
280)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
281)                         "no distributor with number \"%u\""
282)                         " in line %u of config file\n",
283)                         distri, p_ctx->line_no);
284)     return -1;
285)   }
286) 
287)   /* get mapping parameters: base, factor, gamma */
Stefan Schuermans value -> p_value for consis...

Stefan Schuermans authored 7 years ago

288)   base = flp_strtod_noloc(p_value, &ptr);
289)   if (ptr == p_value
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

290)       || (*ptr != 0 && *ptr != ' ' && *ptr != '\t'
291)           && *ptr != '\r' && *ptr != '\n')) {
292)     if (p_ctx->p_msg_func)
293)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
294)                         "invalid mapping parameters \"%s\""
295)                         " in line %u of config file\n",
Stefan Schuermans value -> p_value for consis...

Stefan Schuermans authored 7 years ago

296)                         p_value, p_ctx->line_no);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

297)     return -1;
298)   }
Stefan Schuermans v1.0.3

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

300)   if (ptr2 == ptr
301)       || (*ptr2 != 0 && *ptr2 != ' ' && *ptr2 != '\t'
302)           && *ptr2 != '\r' && *ptr2 != '\n')) {
303)     if (p_ctx->p_msg_func)
304)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
305)                         "invalid mapping parameters \"%s\""
306)                         " in line %u of config file\n",
Stefan Schuermans value -> p_value for consis...

Stefan Schuermans authored 7 years ago

307)                         p_value, p_ctx->line_no);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

308)     return -1;
309)   }
Stefan Schuermans v1.0.3

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

311)   if (ptr == ptr2
312)       || (*ptr != 0 && *ptr != ' ' && *ptr != '\t'
313)           && *ptr != '\r' && *ptr != '\n')) {
314)     if (p_ctx->p_msg_func)
315)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
316)                         "invalid mapping parameters \"%s\""
317)                         " in line %u of config file\n",
Stefan Schuermans value -> p_value for consis...

Stefan Schuermans authored 7 years ago

318)                         p_value, p_ctx->line_no);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

319)     return -1;
320)   }
321)   if (gamma <= 0.0) {
322)     if (p_ctx->p_msg_func)
323)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
324)                         "invalid gamma value \"%f\""
325)                         " in line %u of config file\n",
326)                         gamma, p_ctx->line_no);
327)     return -1;
328)   }
329) 
330)   /* store new mapping parameters and re-calculate mapping table */
331)   p_distri->mapping[chan].base = base;
332)   p_distri->mapping[chan].factor = factor;
333)   p_distri->mapping[chan].gamma = gamma;
334)   flp_mapping_precalc(&p_distri->mapping[chan]);
335) 
336)   return 0;
337) }
338) 
339) /**
340)  * \brief process pixel from config file
341)  *
342)  * \param[in,out] p_ctx context information
343)  * \param[in] sz_pixel text of pixel to process
344)  * \param[in] distri number of distributor
345)  * \param[in] out number of output
346)  * \param[in] pix number of pixel
347)  * \return 0 in case of success, -1 in case of error
348)  */
349) int flp_config_proc_pixel(flp_config_ctx_t *p_ctx, char *sz_pixel,
350)                           unsigned int distri, unsigned int out,
351)                           unsigned int pix)
352) {
353)   flp_distri_t *p_distri = p_ctx->p_display->distri_ptrs[distri];
354)   char *ptr;
355)   unsigned int x, y, idx;
356) 
357)   /* get coordinates of pixel */
358)   if (flp_parse_two_nos(sz_pixel, &x, &y, &ptr) || *ptr != 0
359)       || (int)x < 0 || (int)x >= p_ctx->p_display->size.x
360)       || (int)y < 0 || (int)y >= p_ctx->p_display->size.y) {
361)     if (p_ctx->p_msg_func)
362)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
363)                         "invalid pixel \"%s\""
364)                         " in line %u of config file\n",
365)                         sz_pixel, p_ctx->line_no);
366)     return -1;
367)   }
368) 
369)   /* check pixel number */
370)   if (pix >= FLP_PIXEL_MAX_CNT || pix >= p_distri->pixel_cnt) {
371)     if (p_ctx->p_msg_func)
372)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
373)                         "too many pixels (more than %u)"
374)                         " in line %u of config file\n",
375)                         p_distri->pixel_cnt, p_ctx->line_no);
376)     return -1;
377)   }
378) 
379)   /* check that pixel is not yet set */
380)   idx = out * p_distri->pixel_cnt + pix;
381)   if (p_distri->p_pixels[idx].x >= 0
382)       && p_distri->p_pixels[idx].y >= 0) {
383)     if (p_ctx->p_msg_func)
384)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
385)                         "pixel %u of output %u of distributor %u already set"
386)                         " to pixel %u,%u in line %u of config file\n",
387)                         pix, out, distri, p_distri->p_pixels[idx].x,
388)                  p_distri->p_pixels[idx].y, p_ctx->line_no);
389)     return -1;
390)   }
391) 
392)   /* set pixel coordinates */
393)   p_distri->p_pixels[idx].x = x;
394)   p_distri->p_pixels[idx].y = y;
395) 
396)   /* count pixels in total */
397)   p_ctx->p_display->pixel_cnt++;
398) 
399)   return 0;
400) }
401) 
402) /**
403)  * \brief process output from config file
404)  *
405)  * \param[in,out] p_ctx context information
406)  * \param[in] p_setting_part2 second half of setting to process
407)  * \param[in] p_value value of setting
408)  * \return 0 in case of success, -1 in case of error
409)  */
410) int flp_config_proc_output(flp_config_ctx_t *p_ctx, char *p_setting_part2,
Stefan Schuermans value -> p_value for consis...

Stefan Schuermans authored 7 years ago

411)                            char *p_value)
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

412) {
413)   char *ptr, *p_pos, *p_white, white;
414)   unsigned int distri, out, pix;
415)   flp_distri_t *p_distri;
416)   int err;
417) 
418)   /* get number of distributor and output */
419)   if (flp_parse_two_nos(p_setting_part2, &distri, &out, &ptr) || *ptr != 0) {
420)     if (p_ctx->p_msg_func)
421)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
422)                         "invalid output specifier \"%s\""
423)                         " in line %u of config file\n",
424)                         p_setting_part2, p_ctx->line_no);
425)     return -1;
426)   }
427)   if (distri >= FLP_DISTRI_MAX_CNT) {
428)     if (p_ctx->p_msg_func)
429)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
430)                         "invalid distributor number \"%u\""
431)                         " in line %u of config file\n",
432)                         distri, p_ctx->line_no);
433)     return -1;
434)   }
435)   if (out >= FLP_OUTPUT_MAX_CNT) {
436)     if (p_ctx->p_msg_func)
437)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
438)                         "invalid output number \"%u\""
439)                         " in line %u of config file\n",
440)                         out, p_ctx->line_no);
441)     return -1;
442)   }
443) 
444)   /* get distributor */
445)   p_distri = p_ctx->p_display->distri_ptrs[distri];
446)   if (!p_distri) {
447)     if (p_ctx->p_msg_func)
448)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
449)                         "no distributor with number \"%u\""
450)                         " in line %u of config file\n",
451)                         distri, p_ctx->line_no);
452)     return -1;
453)   }
454)   /* check output number */
455)   if (out >= p_distri->output_cnt) {
456)     if (p_ctx->p_msg_func)
457)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
458)                         "no output with output number \"%u\""
459)                         " in line %u of config file\n",
460)                         out, p_ctx->line_no);
461)     return -1;
462)   }
463) 
464)   /* count outputs */
465)   p_ctx->p_display->output_cnt++;
466) 
467)   /* process pixels */
468) 
469)   /* process all parts separated by whitespace */
Stefan Schuermans value -> p_value for consis...

Stefan Schuermans authored 7 years ago

470)   p_pos = p_value;
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

471)   err = 0;
472)   pix = 0;
473)   while (*p_pos != 0) {
474) 
475)     /* get end of item (first whitespace) */
476)     for (p_white = p_pos;
477)          *p_white && *p_white != ' ' && *p_white != '\t'
478)          && *p_white != '\r' && *p_white != '\n'; p_white++);
479) 
480)     /* process item: a pixel */
481)     white = *p_white; /* terminate item */
482)     *p_white = 0;
483)     if (flp_config_proc_pixel(p_ctx, p_pos, distri, out, pix)) /* process */
484)       err = -1;       /* remember errors */
485)     pix++;            /* count pixels */
486)     *p_white = white; /* undo termination */
487) 
488)     /* skip whitespace and continue after it */
489)     for (;
490)          *p_white == ' ' || *p_white == '\t'
491)          || *p_white == '\r' || *p_white == '\n'; p_white++);
492)     p_pos = p_white;
493) 
494)   } /* while (*p_pos != 0) */
495) 
496)   return err;
497) }
498) 
499) /**
500)  * \brief process setting from config file
501)  *
502)  * \param[in,out] p_ctx context information
503)  * \param[in] p_setting setting to process
504)  * \param[in] p_value value of setting
505)  * \return 0 in case of success, -1 in case of error
506)  */
507) int flp_config_proc_setting(flp_config_ctx_t *p_ctx, char *p_setting,
508)                             char *p_value)
509) {
510)   char *ptr;
511)   unsigned int x, y;
512) 
513)   /* replace all whitespace with spaces in setting */
514)   while ((ptr = strchr(p_setting, '\t')))
515)     *ptr = ' ';
516)   while ((ptr = strchr(p_setting, '\r')))
517)     *ptr = ' ';
518)   while ((ptr = strchr(p_setting, '\n')))
519)     *ptr = ' ';
520) 
521)   /* bind address for UDP output */
522)   if (!strcmp(p_setting, "bindAddr")) {
523)     if (flp_parse_addr(p_value, &p_ctx->p_display->bind_addr)) {
524)       if (p_ctx->p_msg_func)
525)         p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
526)                           "invalid address \"%s\" for \"%s\""
527)                           " in line %u of config file\n",
528)                           p_value, p_setting, p_ctx->line_no);
529)       return -1;
530)     }
531)     if (p_ctx->p_msg_func)
532)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_info, "bind address: %s\n", p_value);
533)     return 0;
534)   }
535) 
536)   /* size of display */
537)   if (!strcmp(p_setting, "size")) {
538)     if (flp_parse_two_nos(p_value, &x, &y, &ptr)
539)         || (int)x <= 0 || (int)y <= 0) {
540)       if (p_ctx->p_msg_func)
541)         p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
542)                           "invalid value \"%s\" for \"%s\""
543)                           " in line %u of config file\n",
544)                           p_value, p_setting, p_ctx->line_no);
545)       return -1;
546)     }
547)     p_ctx->p_display->size.x = x;
548)     p_ctx->p_display->size.y = y;
549)     return 0;
550)   }
551) 
552)   /* distributor */
553)   if (!strncmp(p_setting, "distributor ", 12))
554)     return flp_config_proc_distri(p_ctx, p_setting + 12, p_value);
555) 
Stefan Schuermans add support for configuring...

Stefan Schuermans authored 7 years ago

556)   /* distributor address */
557)   if (!strncmp(p_setting, "distributorAddr ", 16))
558)     return flp_config_proc_distri_addr(p_ctx, p_setting + 16, p_value);
559) 
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

560)   /* mapping */
561)   if (!strncmp(p_setting, "mapping ", 8))
562)     return flp_config_proc_mapping(p_ctx, p_setting + 8, p_value);
563) 
564)   /* output */
565)   if (!strncmp(p_setting, "output ", 7))
566)     return flp_config_proc_output(p_ctx, p_setting + 7, p_value);
567) 
568)   /* unknown setting */
569)   if (p_ctx->p_msg_func)
570)     p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_warn,
571)                       "unknown setting \"%s\""
572)                       " in line %u of config file, ignored\n",
573)                       p_setting, p_ctx->line_no);
574)   return 0;
575) }
576) 
577) /**
578)  * \brief process line from config file
579)  *
580)  * \param[in,out] p_ctx context information
581)  * \param[in] p_line line to process
582)  * \return 0 in case of success, -1 in case of error
583)  */
584) int flp_config_proc_line(flp_config_ctx_t *p_ctx, char *p_line)
585) {
586)   char *p_hash, *p_equal, *p_setting, *p_value;
587)   int i;
588) 
589)   /* remove comment */
590)   p_hash = strchr(p_line, '#');
591)   if (p_hash)
592)     *p_hash = 0;
593) 
594)   /* remove trailing whitespace */
595)   for (i = strlen(p_line) - 1;
596)        i >= 0 && (p_line[i] == ' ' || p_line[i] == '\t'
597)                   || p_line[i] == '\r' || p_line[i] == '\n'); i--)
598)     p_line[i] = 0;
599) 
600)   /* remove leading whitespace */
601)   for (; *p_line == ' ' || *p_line == '\t'
602)          || *p_line == '\r' || *p_line == '\n'; p_line++);
603) 
604)   /* ignore empty line */
605)   if (!p_line[0])
606)     return 0;
607) 
608)   /* find equal sign */
609)   p_equal = strchr(p_line, '=');
610)   if (!p_equal) {               /* no equal sign found */
611)     if (p_ctx->p_msg_func)
612)       p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_warn,
613)                         "invalid line %u in config file, ignored\n",
614)                         p_ctx->line_no);
615)     return 0;
616)   }
617) 
618)   /* split string at equal sign */
619)   *p_equal = 0;
620)   p_setting = p_line;
621)   p_value = p_equal + 1;
622) 
623)   /* remove trailing whitespaces in setting name */
624)   for (i = strlen(p_setting) - 1;
625)        i >= 0 && (p_setting[i] == ' ' || p_setting[i] == '\t'
626)                   || p_setting[i] == '\r' || p_setting[i] == '\n'); i--)
627)     p_setting[i] = 0;
628) 
629)   /* remove leading whitespaces in value */
630)   for (; *p_value == ' ' || *p_value == '\t'
631)          || *p_value == '\r' || *p_value == '\n'; p_value++);
632) 
633)   /* process setting */
634)   return flp_config_proc_setting(p_ctx, p_setting, p_value);
635) }
636) 
637) /**
638)  * \brief process config file
639)  *
640)  * \param[in,out] p_display display to configure
641)  * \param[in] sz_config_file name of config file to read
642)  * \param[in] p_msg_func message callback function or NULL
643)  * \param[in] p_msg_ctx user context for message callback
644)  * \return 0 in case of success, -1 in case of error
645)  */
646) int flp_config_proc_file(flp_display_t *p_display,
647)                          const char *sz_config_file,
648)                          flp_msg_func_p_t p_msg_func, void *p_msg_ctx)
649) {
650)   flp_config_ctx_t ctx;
651)   FILE *file;
652) 
653)   /* set up context */
654)   ctx.p_display = p_display;
655)   ctx.p_msg_func = p_msg_func;
656)   ctx.p_msg_ctx = p_msg_ctx;
657) 
658)   /* check if file is present */
659)   if (!sz_config_file || !sz_config_file[0]) {
660)     if (p_msg_func)
661)       p_msg_func(p_msg_ctx, flp_msg_type_err,
662)                  "no config file specified\n");
663)     return -1;
664)   }
665) 
666)   if (p_msg_func)
667)     p_msg_func(p_msg_ctx, flp_msg_type_info,
668)                "using config file \"%s\"\n",
669)                sz_config_file);
670) 
671)   /* open file */
672)   file = fopen(sz_config_file, "rt");
673)   if (!file) {
Stefan Schuermans v1.0.2

Stefan Schuermans authored 13 years ago

674)     if (p_msg_func) {
675)       char errmsg[256];
676)       strerror_r(errno, errmsg, sizeof(errmsg));
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

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

Stefan Schuermans authored 13 years ago

679)                  sz_config_file, errmsg);
680)     }
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

681)     return -1;
682)   }
683) 
684)   /* process lines in file */
685)   ctx.line_no = 1;
686)   while (!feof(file)) {
687)     char line[4096], *p_lf;
688) 
689)     /* read a line */
690)     line[0] = 0;
Stefan Schuermans adaptions for gcc 5

Stefan Schuermans authored 7 years ago

691)     if (fgets(line, sizeof (line), file) == NULL)
692)       break;
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

693)     p_lf = strchr(line, '\n'); /* find LF in line in replace it with 0 */
694)     if (p_lf)
695)       *p_lf = 0;
696)     else {                     /* no LF in line */
697)       if (!feof(file)) {       /* not at end of file */
698)         char dummy[4096];
699)         if (p_msg_func)
700)           p_msg_func(p_msg_ctx, flp_msg_type_warn,
701)                      "line %u too long in config file, truncated\n",
702)                      ctx.line_no);
703)         /* jump over in rest of line */
704)         dummy[0] = 0;
705)         while (!feof(file) && !strchr(dummy, '\n'))
Stefan Schuermans adaptions for gcc 5

Stefan Schuermans authored 7 years ago

706)           if (fgets(dummy, sizeof (dummy), file) == NULL)
707)             break;