1 : /*
2 : * This file is part of MIN Test Framework. Copyright © 2008 Nokia Corporation
3 : * and/or its subsidiary(-ies).
4 : * Contact: Konrad Marek Zapalowicz
5 : * Contact e-mail: DG.MIN-Support@nokia.com
6 : *
7 : * This program is free software: you can redistribute it and/or modify it
8 : * under the terms of the GNU General Public License as published by the Free
9 : * Software Foundation, version 2 of the License.
10 : *
11 : * This program is distributed in the hope that it will be useful, but WITHOUT
12 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 : * more details. You should have received a copy of the GNU General Public
15 : * License along with this program. If not, see
16 : * <http://www.gnu.org/licenses/>.
17 : */
18 :
19 :
20 : /**
21 : * @file min_section_parser.c
22 : * @version 0.1
23 : * @brief This file contains implementation of Min Section Parser.
24 : */
25 :
26 : /* ------------------------------------------------------------------------- */
27 : /* INCLUDE FILES */
28 : #include "min_section_parser.h"
29 :
30 : /* ------------------------------------------------------------------------- */
31 : /* EXTERNAL DATA STRUCTURES */
32 : /* None */
33 :
34 : /* ------------------------------------------------------------------------- */
35 : /* EXTERNAL GLOBAL VARIABLES */
36 : /* None */
37 :
38 : /* ------------------------------------------------------------------------- */
39 : /* EXTERNAL FUNCTION PROTOTYPES */
40 : /* None */
41 :
42 : /* ------------------------------------------------------------------------- */
43 : /* GLOBAL VARIABLES */
44 : /* None */
45 :
46 : /* ------------------------------------------------------------------------- */
47 : /* CONSTANTS */
48 : /* None */
49 :
50 : /* ------------------------------------------------------------------------- */
51 : /* MACROS */
52 : /*#define MIN_UNIT_TEST*/
53 :
54 : /* ------------------------------------------------------------------------- */
55 : /* LOCAL GLOBAL VARIABLES */
56 : /* None */
57 :
58 : /* ------------------------------------------------------------------------- */
59 : /* LOCAL CONSTANTS AND MACROS */
60 : /* None */
61 :
62 : /* ------------------------------------------------------------------------- */
63 : /* MODULE DATA STRUCTURES */
64 : /* None */
65 :
66 : /* ------------------------------------------------------------------------- */
67 : /* LOCAL FUNCTION PROTOTYPES */
68 : /* ------------------------------------------------------------------------- */
69 : /** Generic start and end position parser for given data.
70 : * @param msp [in] MinSectionParser entity to operate on.
71 : * @param section [in] buffer to be parsed.
72 : * @param start_tag [in] tag from which parsing starts.
73 : * @param tag_indicator [in] indicates if tag is included in return value.
74 : * @param start_pos [out] indicates starting position of extracted section.
75 : * @param end_pos [out] indicates ending position of extracted section.
76 : * @param length [out] indicates the length of the extracted section.
77 : * @return 0 or -1 in case of failure.
78 : */
79 : LOCAL int mmp_parse_start_and_end_pos (MinSectionParser * msp,
80 : const TSChar * section,
81 : const TSChar * start_tag,
82 : TSTagToReturnValue tag_indicator,
83 : TSChar ** start_pos,
84 : TSChar ** end_pos, int *length);
85 : /* ------------------------------------------------------------------------- */
86 : /** Generic search for end-of-line.
87 : * @param msp [in] MinSectionParser entity to operate on.
88 : * @param c [in:out] indicates starting position when looking for EOL, is set
89 : * to the beginning of the next line when linefeed is found.
90 : * @return position before linefeed or INITPTR in case of failure.
91 : *
92 : */
93 : LOCAL TSChar *mmp_goto_end_of_line (MinSectionParser * msp, TSChar ** c);
94 : /* ------------------------------------------------------------------------- */
95 : /* FORWARD DECLARATIONS */
96 : /* None */
97 :
98 : /* ==================== LOCAL FUNCTIONS ==================================== */
99 : /* ------------------------------------------------------------------------- */
100 : LOCAL int mmp_parse_start_and_end_pos (MinSectionParser * msp,
101 : const TSChar * section,
102 : const TSChar * start_tag,
103 : TSTagToReturnValue tag_indicator,
104 : TSChar ** start_pos,
105 : TSChar ** end_pos,
106 : int *length)
107 8069 : {
108 8069 : int retval = ENOERR;
109 8069 : int i = 0;
110 8069 : TSChar *c = INITPTR;
111 8069 : TSChar *c2 = INITPTR;
112 :
113 8069 : *start_pos = INITPTR;
114 8069 : *end_pos = INITPTR;
115 8069 : *length = 0;
116 :
117 8069 : if (msp == INITPTR) {
118 8 : retval = -1;
119 8 : errno = EINVAL;
120 8 : goto EXIT;
121 : }
122 8061 : if (section == INITPTR) {
123 0 : retval = -1;
124 0 : errno = EINVAL;
125 0 : goto EXIT;
126 : }
127 8061 : if (start_tag == INITPTR) {
128 4 : retval = -1;
129 4 : errno = EINVAL;
130 4 : goto EXIT;
131 : }
132 :
133 8057 : if (msp->skip_and_mark_pos_ < strlen (section)) {
134 8047 : c = (TSChar *) & section[msp->skip_and_mark_pos_];
135 : } else {
136 10 : c = (TSChar *) & section[strlen (section) - 1];
137 : }
138 :
139 : /* Check if start_tag is given */
140 8057 : if (strlen (start_tag) == 0) {
141 21031 : while (strchr (" \n\t\r", *c) != NULL) {
142 8486 : if (*c == '\0') {
143 1115 : break;
144 : }
145 7371 : c++;
146 : }
147 6830 : *start_pos = c;
148 6830 : c2 = *start_pos;
149 :
150 6830 : if (*c == '\0') {
151 1115 : *length = 1;
152 1115 : *end_pos = *start_pos;
153 1115 : goto EXIT;
154 : }
155 :
156 : } else {
157 : /* We are looking for occurence of start_tag */
158 1227 : c2 = strstr (c, start_tag);
159 :
160 1227 : if (c2 != NULL) {
161 :
162 : /* tag will not be included to the section */
163 803 : if (tag_indicator != ESTag) {
164 : /* because start_pos is before start_tag */
165 691 : c2 += strlen (start_tag);
166 :
167 1634 : while (strchr (" \t\n", *c2) != NULL) {
168 252 : c2++;
169 : }
170 : }
171 :
172 : /* start position */
173 803 : *start_pos = c2;
174 : }
175 : }
176 :
177 6942 : if (*start_pos == INITPTR) {
178 424 : goto EXIT;
179 : }
180 6518 : if (**start_pos == '\0') {
181 0 : goto EXIT;
182 : }
183 :
184 : /* Look for the end_pos */
185 6518 : *end_pos = mmp_goto_end_of_line (msp, &c2);
186 :
187 6518 : if (*start_pos == *end_pos) {
188 0 : goto EXIT;
189 : }
190 :
191 471377 : for (i = 0; i < strlen (section); i++) {
192 471377 : if (*start_pos == §ion[i])
193 6518 : break;
194 : }
195 6518 : msp->skip_and_mark_pos_ = i;
196 :
197 : /* Count the length */
198 6518 : c2 = *start_pos;
199 6518 : c = *end_pos;
200 123692 : while (c2 != c) {
201 110656 : c2++;
202 110656 : (*length)++;
203 : }
204 :
205 6518 : (*length) += 1;
206 :
207 : /* Update next line beginning */
208 6518 : msp->skip_and_mark_pos_ += *length;
209 8069 : EXIT:
210 8069 : return retval;
211 : }
212 :
213 : /* ------------------------------------------------------------------------- */
214 : LOCAL TSChar *mmp_goto_end_of_line (MinSectionParser * msp, TSChar ** c)
215 6526 : {
216 6526 : TSChar *retval = INITPTR;
217 6526 : TSChar *last_item_pos = *c;
218 6526 : TSChar *c2 = *c;
219 :
220 6526 : if (msp == INITPTR) {
221 2 : errno = EINVAL;
222 2 : goto EXIT;
223 : }
224 :
225 : do {
226 : /* Peek next TSCharacter \n (0x0A) in UNIX */
227 117990 : if (*(c2 + 1) == 0x0A) {
228 6515 : c2++;
229 6515 : break;
230 : }
231 : /* Peek next TSCharacter \r (0x0D) in Symbian OS */
232 111475 : if (*(c2 + 1) == 0x0D) {
233 0 : c2++;
234 :
235 : /* Peek next TSCharacter \n (0x0A) in Symbian OS */
236 0 : if (*(c2 + 1) == 0x0A) {
237 0 : c2++;
238 0 : break;
239 : }
240 :
241 0 : c2--;
242 111475 : } else if (*(c2 + 1) == 0x09 || *(c2 + 1) == 0x20) {
243 11756 : c2++;
244 11756 : continue;
245 : }
246 :
247 99719 : c2++;
248 99719 : last_item_pos = c2;
249 :
250 111475 : } while (*c2 != '\0');
251 :
252 6524 : retval = last_item_pos;
253 6524 : *c = c2 + 1;
254 6526 : EXIT:
255 6526 : return retval;
256 : }
257 :
258 : /* ------------------------------------------------------------------------- */
259 : /* ======================== FUNCTIONS ====================================== */
260 : /* ------------------------------------------------------------------------- */
261 : MinSectionParser *mmp_create (unsigned int length)
262 1365 : {
263 1365 : MinSectionParser *msp = NEW (MinSectionParser);
264 :
265 1365 : if (msp == NULL) {
266 0 : msp = INITPTR;
267 0 : errno = ENOMEM;
268 0 : goto EXIT;
269 : }
270 :
271 1365 : msp->section_ = INITPTR;
272 1365 : msp->length_ = length;
273 1365 : msp->buffer_section_ = INITPTR;
274 1365 : msp->skip_and_mark_pos_ = 0;
275 1365 : msp->line_indicator_ = ESFalse;
276 1365 : msp->sub_offset_ = INITPTR;
277 :
278 1365 : msp->buffer_section_ = NEW2 (TSChar, msp->length_ + 1);
279 :
280 1365 : if (msp->buffer_section_ == NULL) {
281 0 : msp->buffer_section_ = INITPTR;
282 0 : DELETE (msp);
283 0 : goto EXIT;
284 : }
285 :
286 1365 : msp->buffer_section_[0] = '\0';
287 1365 : msp->buffer_section_[length] = '\0';
288 1365 : msp->section_ = msp->buffer_section_;
289 1365 : msp->sub_offset_ = msp->buffer_section_;
290 1365 : EXIT:
291 1365 : return msp;
292 : }
293 :
294 : /* ------------------------------------------------------------------------- */
295 : void mmp_destroy (MinSectionParser ** msp)
296 1476 : {
297 1476 : if (*msp == INITPTR)
298 138 : return;
299 :
300 1338 : DELETE ((*msp)->buffer_section_);
301 1338 : DELETE (*msp);
302 1338 : *msp = INITPTR;
303 : }
304 :
305 : /* ------------------------------------------------------------------------- */
306 : MinItemParser *mmp_get_item_line (MinSectionParser * msp,
307 : const TSChar * tag,
308 : TSTagToReturnValue tag_indicator)
309 1488 : {
310 1488 : MinItemParser *mip = INITPTR;
311 1488 : int ret = 0;
312 1488 : TSChar *start_pos = INITPTR;
313 1488 : TSChar *end_pos = INITPTR;
314 1488 : int length = 0;
315 1488 : TSChar *c = INITPTR;
316 :
317 1488 : if (msp == INITPTR) {
318 103 : errno = EINVAL;
319 103 : goto EXIT;
320 : }
321 1385 : if (tag == INITPTR) {
322 1 : errno = EINVAL;
323 1 : goto EXIT;
324 : }
325 :
326 : /* Indicator that GetItemLineL has been used */
327 1384 : msp->line_indicator_ = ESTrue;
328 :
329 1384 : msp->skip_and_mark_pos_ = 0;
330 :
331 1384 : ret =
332 : mmp_parse_start_and_end_pos (msp, msp->section_, tag,
333 : tag_indicator, &start_pos, &end_pos,
334 : &length);
335 : /* No parsing found */
336 1384 : if ((ret != ENOERR) || (length <= 0) || (start_pos == INITPTR)) {
337 : goto EXIT;
338 : }
339 :
340 1333 : ret = 0;
341 1333 : c = &msp->section_[0];
342 14878 : while (c != start_pos) {
343 12212 : c++;
344 12212 : ret++;
345 : }
346 :
347 1333 : mip = mip_create (msp->section_, ret, length);
348 :
349 1488 : EXIT:
350 1488 : return mip;
351 : }
352 :
353 : /* ------------------------------------------------------------------------- */
354 : MinItemParser *mmp_get_next_item_line (MinSectionParser * msp)
355 5791 : {
356 5791 : MinItemParser *mip = INITPTR;
357 5791 : int retval = 0;
358 5791 : TSChar *start_pos = INITPTR;
359 5791 : TSChar *end_pos = INITPTR;
360 5791 : TSChar *c = INITPTR;
361 5791 : int length = 0;
362 5791 : TSTagToReturnValue tag_indicator = ESTag;
363 :
364 5791 : if (msp == INITPTR) {
365 1 : errno = EINVAL;
366 1 : goto EXIT;
367 : }
368 5790 : if (msp->line_indicator_ == ESFalse) {
369 1 : goto EXIT;
370 : }
371 :
372 5789 : retval =
373 : mmp_parse_start_and_end_pos (msp, msp->section_, "",
374 : tag_indicator, &start_pos, &end_pos,
375 : &length);
376 : /* No parsing found */
377 5789 : if (retval != ENOERR || length <= 0 || start_pos == INITPTR)
378 : goto EXIT;
379 :
380 5789 : retval = 0;
381 5789 : c = &msp->section_[0];
382 515342 : while (c != start_pos) {
383 503764 : c++;
384 503764 : retval++;
385 : }
386 :
387 5789 : mip = mip_create (msp->section_, retval, length);
388 5791 : EXIT:
389 5791 : return mip;
390 : }
391 :
392 : /* ------------------------------------------------------------------------- */
393 : MinItemParser *mmp_get_next_tagged_item_line (MinSectionParser * msp,
394 : const TSChar * tag,
395 : TSTagToReturnValue
396 : tag_indicator)
397 6 : {
398 6 : MinItemParser *mip = INITPTR;
399 6 : int retval = 0;
400 6 : TSChar *start_pos = INITPTR;
401 6 : TSChar *end_pos = INITPTR;
402 6 : TSChar *c = INITPTR;
403 6 : int length = 0;
404 :
405 6 : if (msp == INITPTR) {
406 1 : errno = EINVAL;
407 1 : goto EXIT;
408 : }
409 5 : if (tag == INITPTR) {
410 1 : errno = EINVAL;
411 1 : goto EXIT;
412 : }
413 :
414 : /* mmp_get_line or mmp_get_item_line has not been called */
415 4 : if (msp->line_indicator_ == ESFalse) {
416 1 : goto EXIT;
417 : }
418 :
419 3 : retval =
420 : mmp_parse_start_and_end_pos (msp, msp->section_, tag,
421 : tag_indicator, &start_pos, &end_pos,
422 : &length);
423 : /* No parsing found */
424 3 : if (retval != ENOERR || length <= 0 || start_pos == INITPTR) {
425 : goto EXIT;
426 : }
427 :
428 3 : retval = 0;
429 3 : c = &msp->section_[0];
430 740 : while (c != start_pos) {
431 734 : c++;
432 734 : retval++;
433 : }
434 :
435 3 : mip = mip_create (msp->section_, retval, length);
436 6 : EXIT:
437 6 : return mip;
438 : }
439 :
440 : /* ------------------------------------------------------------------------- */
441 : MinSectionParser *mmp_sub_section (MinSectionParser * msp,
442 : const TSChar * start_tag,
443 : const TSChar * end_tag, int seeked)
444 6 : {
445 6 : MinSectionParser *sp = INITPTR;
446 :
447 6 : if (msp == INITPTR) {
448 1 : errno = EINVAL;
449 1 : goto EXIT;
450 : }
451 5 : if (start_tag == INITPTR) {
452 1 : errno = EINVAL;
453 1 : goto EXIT;
454 : }
455 4 : if (end_tag == INITPTR) {
456 1 : errno = EINVAL;
457 1 : goto EXIT;
458 : }
459 :
460 3 : msp->sub_offset_ = &msp->section_[0];
461 3 : sp = mmp_next_sub_section (msp, start_tag, end_tag, seeked);
462 6 : EXIT:
463 6 : return sp;
464 :
465 : }
466 :
467 : /* ------------------------------------------------------------------------- */
468 : MinSectionParser *mmp_next_sub_section (MinSectionParser * msp,
469 : const TSChar * start_tag,
470 : const TSChar * end_tag, int seeked)
471 17 : {
472 17 : MinSectionParser *sp = INITPTR;
473 17 : TSChar *buff = INITPTR;
474 17 : TSChar *c = INITPTR;
475 17 : TSChar *c2 = INITPTR;
476 17 : TSChar *length_startpos = INITPTR;
477 17 : TSChar *length_endpos = INITPTR;
478 17 : unsigned int tag_count = 1;
479 17 : unsigned int length = 0;
480 :
481 17 : if (msp == INITPTR) {
482 1 : errno = EINVAL;
483 1 : goto EXIT;
484 : }
485 16 : if (start_tag == INITPTR) {
486 1 : errno = EINVAL;
487 1 : goto EXIT;
488 : }
489 15 : if (end_tag == INITPTR) {
490 1 : errno = EINVAL;
491 1 : goto EXIT;
492 : }
493 :
494 14 : buff = &msp->section_[0];
495 :
496 : /* Check if start_tag is given */
497 14 : if (strlen (start_tag) == 0) {
498 : /* skip spaces, line break, tabs, etc */
499 6 : while (strchr (" \n\t\r", *buff) != NULL) {
500 0 : buff++;
501 : }
502 3 : length_startpos = buff;
503 : } else {
504 11 : c = buff;
505 11 : c2 = c;
506 :
507 : /* we are looking for occurence of start_tag */
508 11 : c2 = strstr (c, start_tag);
509 :
510 34 : while (c2 != NULL) {
511 19 : if (tag_count == seeked) {
512 : /* start tag found of correct one */
513 7 : length_startpos = c2;
514 7 : length_startpos += strlen (start_tag);
515 7 : break;
516 : } else {
517 : /* start tag found but not correct section */
518 12 : tag_count++;
519 : }
520 12 : c = c2 + 1;
521 12 : c2 = strstr (c, start_tag);
522 : }
523 : }
524 :
525 : /* Seeked section is not found */
526 14 : if (tag_count != seeked || c2 == NULL) {
527 : goto EXIT;
528 : }
529 :
530 515 : while (strchr (" \n\t\r", *length_startpos) != NULL) {
531 497 : length_startpos++;
532 : }
533 :
534 : /* Check if end_tag is given */
535 9 : if (strlen (end_tag) == 0) {
536 2 : length_endpos = &msp->section_[strlen (msp->section_) - 1];
537 : } else {
538 7 : c = length_startpos;
539 7 : c2 = c;
540 :
541 : /* We are looking for occurence of end_tag */
542 7 : c2 = strstr (c, end_tag);
543 :
544 7 : if (c2 != NULL) {
545 6 : length_endpos = c2;
546 6 : length_endpos--;
547 : } else {
548 : /* end_tag was not found => length will be 0 */
549 1 : length_endpos = length_startpos;
550 : }
551 : }
552 :
553 396 : while (strchr (" \n\t\r", *length_endpos) != NULL) {
554 378 : length_endpos--;
555 : }
556 :
557 : /* The length includes spaces and end of lines */
558 9 : length = strlen (length_startpos) - strlen (length_endpos);
559 :
560 9 : if (length <= 0) {
561 1 : goto EXIT;
562 : } else {
563 : /* Create MinSectionParser */
564 8 : sp = mmp_create (length + 2);
565 8 : mmp_set_data (sp, msp->section_, length_startpos, length + 1);
566 : }
567 17 : EXIT:
568 17 : return sp;
569 : }
570 :
571 : /* ------------------------------------------------------------------------- */
572 : int mmp_get_line (MinSectionParser * msp, const TSChar * tag, TSChar ** line,
573 : TSTagToReturnValue tag_indicator)
574 826 : {
575 826 : int retval = ENOERR;
576 826 : int length = 0;
577 826 : TSChar *start_pos = INITPTR;
578 826 : TSChar *end_pos = INITPTR;
579 :
580 826 : *line = INITPTR;
581 :
582 826 : if (msp == INITPTR) {
583 1 : retval = -1;
584 1 : errno = EINVAL;
585 1 : goto EXIT;
586 : }
587 825 : if (tag == INITPTR) {
588 1 : retval = -1;
589 1 : errno = EINVAL;
590 1 : goto EXIT;
591 : }
592 :
593 824 : if (strlen (msp->section_) == 0) {
594 0 : retval = -1;
595 0 : goto EXIT;
596 : }
597 :
598 824 : msp->line_indicator_ = ESTrue;
599 824 : msp->skip_and_mark_pos_ = 0;
600 :
601 824 : retval =
602 : mmp_parse_start_and_end_pos (msp, msp->section_, tag,
603 : tag_indicator, &start_pos, &end_pos,
604 : &length);
605 :
606 : /* No parsing found */
607 824 : if (retval != ENOERR || length <= 0 || start_pos == INITPTR) {
608 357 : retval = -1;
609 357 : goto EXIT;
610 : }
611 :
612 : /* we can return found line */
613 467 : *line = NEW2 (TSChar, length + 1);
614 467 : STRCPY (*line, start_pos, length);
615 467 : (*line)[length] = '\0';
616 826 : EXIT:
617 826 : return retval;
618 : }
619 :
620 : /* ------------------------------------------------------------------------- */
621 : int mmp_get_next_line (MinSectionParser * msp, TSChar ** line)
622 13 : {
623 13 : int retval = ENOERR;
624 13 : int length = 0;
625 13 : TSChar *start_pos = INITPTR;
626 13 : TSChar *end_pos = INITPTR;
627 : TSTagToReturnValue tag_indicator;
628 :
629 13 : *line = INITPTR;
630 :
631 13 : if (msp == INITPTR) {
632 1 : retval = -1;
633 1 : errno = EINVAL;
634 1 : goto EXIT;
635 : }
636 :
637 12 : if (msp->line_indicator_ == ESFalse) {
638 1 : retval = -1;
639 1 : goto EXIT;
640 : }
641 :
642 : /* tag_indicator has no meaning */
643 11 : tag_indicator = ESTag;
644 :
645 11 : retval =
646 : mmp_parse_start_and_end_pos (msp, msp->section_, "",
647 : tag_indicator, &start_pos, &end_pos,
648 : &length);
649 : /* No parsing found */
650 11 : if (retval != ENOERR || length <= 0 || start_pos == INITPTR) {
651 : goto EXIT;
652 : }
653 :
654 : /* we can return found line */
655 11 : *line = NEW2 (TSChar, length + 1);
656 11 : STRCPY (*line, start_pos, length);
657 11 : (*line)[length] = '\0';
658 13 : EXIT:
659 13 : return retval;
660 : }
661 :
662 : /* ------------------------------------------------------------------------- */
663 : int mmp_get_next_tagged_line (MinSectionParser * msp, const TSChar * tag,
664 : TSChar ** line,
665 : TSTagToReturnValue tag_indicator)
666 16 : {
667 16 : int retval = ENOERR;
668 16 : int length = 0;
669 16 : TSChar *start_pos = INITPTR;
670 16 : TSChar *end_pos = INITPTR;
671 :
672 16 : *line = INITPTR;
673 :
674 16 : if (msp == INITPTR) {
675 1 : retval = -1;
676 1 : errno = EINVAL;
677 1 : goto EXIT;
678 : }
679 15 : if (tag == INITPTR) {
680 1 : retval = -1;
681 1 : errno = EINVAL;
682 1 : goto EXIT;
683 : }
684 :
685 14 : if (msp->line_indicator_ == ESFalse) {
686 1 : retval = -1;
687 1 : goto EXIT;
688 : }
689 :
690 13 : retval =
691 : mmp_parse_start_and_end_pos (msp, msp->section_, tag,
692 : tag_indicator, &start_pos, &end_pos,
693 : &length);
694 : /* No parsing found */
695 13 : if (retval != ENOERR || length <= 0 || start_pos == INITPTR) {
696 : goto EXIT;
697 : }
698 :
699 : /* we can return found line */
700 9 : *line = NEW2 (TSChar, length + 1);
701 9 : if (start_pos != INITPTR) {
702 9 : STRCPY (*line, start_pos, length + 1);
703 9 : (*line)[length] = '\0';
704 : } else {
705 0 : (*line)[0] = '\0';
706 : }
707 :
708 16 : EXIT:
709 16 : return retval;
710 : }
711 :
712 : /* ------------------------------------------------------------------------- */
713 : int mmp_get_position (MinSectionParser * msp)
714 3 : {
715 3 : unsigned int retval = 0;
716 3 : if (msp == INITPTR) {
717 1 : retval = -1;
718 1 : errno = EINVAL;
719 1 : goto EXIT;
720 : }
721 2 : retval = msp->skip_and_mark_pos_;
722 3 : EXIT:
723 3 : return retval;
724 : }
725 :
726 : /* ------------------------------------------------------------------------- */
727 : int mmp_set_position (MinSectionParser * msp, unsigned int pos)
728 4 : {
729 4 : unsigned int retval = ENOERR;
730 4 : if (msp == INITPTR) {
731 1 : retval = -1;
732 1 : errno = EINVAL;
733 1 : goto EXIT;
734 : }
735 3 : msp->skip_and_mark_pos_ = pos;
736 4 : EXIT:
737 4 : return retval;
738 : }
739 :
740 : /* ------------------------------------------------------------------------- */
741 : void mmp_set_data (MinSectionParser * msp, const TSChar * data,
742 : TSChar * start_pos, unsigned int length)
743 1310 : {
744 1310 : if (msp == INITPTR) {
745 0 : goto EXIT;
746 : }
747 1310 : if (data == INITPTR) {
748 0 : goto EXIT;
749 : }
750 1310 : if (start_pos == INITPTR) {
751 0 : goto EXIT;
752 : }
753 1310 : if (msp->section_ == INITPTR) {
754 0 : goto EXIT;
755 : }
756 :
757 1310 : STRCPY (msp->section_, start_pos, length);
758 1310 : if (length < msp->length_)
759 1266 : msp->section_[length] = '\0';
760 : else
761 44 : msp->section_[msp->length_] = '\0';
762 :
763 1310 : EXIT:
764 : return;
765 : }
766 :
767 : /* ------------------------------------------------------------------------- */
768 : const TSChar *mmp_des (const MinSectionParser * msp)
769 6 : {
770 6 : if (msp == INITPTR)
771 1 : return INITPTR;
772 : else
773 5 : return msp->section_;
774 : }
775 :
776 : /* ------------------------------------------------------------------------- */
777 : /* ================= OTHER EXPORTED FUNCTIONS ============================== */
778 : /* None */
779 :
780 :
781 : /* ================= TESTS FOR LOCAL FUNCTIONS ============================= */
782 : #ifdef MIN_UNIT_TEST
783 : #include "min_section_parser.tests"
784 : #endif /* MIN_UNIT_TEST */
785 : /* ------------------------------------------------------------------------- */
786 : /* End of file */
|