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_parser.c
22 : * @version 0.1
23 : * @brief This file contains implementation of MIN Parser
24 : */
25 :
26 : /* ------------------------------------------------------------------------- */
27 : /* INCLUDE FILES */
28 : #include "min_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 : /* None */
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 : /** Parses sections from configuration files.
70 : *
71 : * Open and read configuration source and parses a required section.
72 : * If start tag is empty the parsing starts beginning of the configuration
73 : * file. If end tag is empty the parsing goes end of configuration file.
74 : * This method will parse next section after the earlier section if seeked
75 : * parameter is equal to 1.
76 : * If configuration file includes several sections with both start and end
77 : * tags so seeked parameter seeks the required section. The seeked
78 : * parameters indicates section that will be parsed.
79 : *
80 : * @param sp [in] adress of the MinParser
81 : * @param start_tag [in] Indicates a start tag for parsing.
82 : * @param end_tag [in] Indicates an end tag for parsing.
83 : * @param seeked [in] a seeked section which will be parsed.
84 : * @return MinSectionParser object or INITPTR in case of failure.
85 : */
86 : MinSectionParser *mp_next_section_file (MinParser * sp,
87 : const TSChar * start_tag,
88 : const TSChar * end_tag, int seeked);
89 : /* ------------------------------------------------------------------------- */
90 : /** Parses sections from memory.
91 : *
92 : * Open and read configuration source and parses a required section.
93 : * If start tag is empty the parsing starts beginning of the configuration
94 : * file. If end tag is empty the parsing goes end of configuration file.
95 : * This method will parse next section after the earlier section if seeked
96 : * parameter is set to 1.
97 : * If configuration source includes several sections with both start and end
98 : * tags so seeked parameter seeks the required section. The aSeeked
99 : * parameters indicates section that will be parsed.
100 : *
101 : * @param sp [in] adress of the MinParser
102 : * @param start_tag [in] Indicates a start tag for parsing.
103 : * @param end_tag [in] Indicates an end tag for parsing.
104 : * @param seeked [in] a seeked section which will be parsed.
105 : * @return MinSectionParser object or INITPTR in case of failure.
106 : *
107 : * Possible Errors:
108 : * - EINVAL: invalid parameter.
109 : * - EFAULT: sp->offset bigger than section length
110 : */
111 : MinSectionParser *mp_next_section_memory (MinParser * sp,
112 : const TSChar * start_tag,
113 : const TSChar * end_tag,
114 : int seeked);
115 : /* ------------------------------------------------------------------------- */
116 : /** Convert a section without comments.
117 : *
118 : * @param buff [in:out] section to be processed
119 : */
120 : void mp_parse_comments_off (TSChar * buff);
121 : /* ------------------------------------------------------------------------- */
122 : /** Handles special marks.( '\/\/', '\/\*' and '*\/\/' ).
123 : * This is used when ECStyleComments comment type is used.
124 : *
125 : * @param buff [in:out] section to be processed
126 : */
127 : void mp_handle_special_marks (TSChar * buff);
128 : /* ------------------------------------------------------------------------- */
129 : /* FORWARD DECLARATIONS */
130 : /* None */
131 :
132 : /* ==================== LOCAL FUNCTIONS ==================================== */
133 : /* ------------------------------------------------------------------------- */
134 : MinSectionParser *mp_next_section_file (MinParser * sp,
135 : const TSChar * start_tag,
136 : const TSChar * end_tag, int seeked)
137 1470 : {
138 1470 : MinSectionParser *section = INITPTR;
139 1470 : TSChar *buf_section = INITPTR;
140 :
141 1470 : if (sp == INITPTR) {
142 1 : errno = EINVAL;
143 1 : goto EXIT;
144 : }
145 1469 : if (start_tag == INITPTR) {
146 1 : errno = EINVAL;
147 1 : goto EXIT;
148 : }
149 1468 : if (end_tag == INITPTR) {
150 1 : errno = EINVAL;
151 1 : goto EXIT;
152 : }
153 :
154 1467 : buf_section =
155 : mfp_next_section (sp->file_parser_, start_tag, end_tag,
156 : &(sp->offset_)
157 : , seeked);
158 :
159 1467 : if (buf_section != INITPTR) {
160 1217 : if (sp->comment_type_ == ECStyleComments) {
161 0 : mp_parse_comments_off (buf_section);
162 : }
163 : /* Make MinSectionParser object and alloc required length */
164 1217 : section = mmp_create (strlen (buf_section) + 2);
165 : /* Copy required data to the section object */
166 1217 : mmp_set_data (section, buf_section, &buf_section[0]
167 : , strlen (buf_section) + 1);
168 : /* Clean */
169 1217 : DELETE (buf_section);
170 : }
171 :
172 1470 : EXIT:
173 1470 : return section;
174 : }
175 :
176 : /* ------------------------------------------------------------------------- */
177 : MinSectionParser *mp_next_section_memory (MinParser * sp,
178 : const TSChar * start_tag,
179 : const TSChar * end_tag, int seeked)
180 33 : {
181 33 : MinSectionParser *section = INITPTR;
182 33 : TSChar *whole_section = INITPTR;
183 33 : TSChar *current_section = INITPTR;
184 33 : TSChar *buff = INITPTR;
185 33 : unsigned int size = 0;
186 33 : const unsigned int tmpsize = 128;
187 33 : int read = 0;
188 33 : int tag_count = 0;
189 33 : int offset = 0;
190 33 : TSChar *start_pos = INITPTR;
191 33 : TSChar *end_pos = INITPTR;
192 33 : TSChar *c = INITPTR;
193 33 : TSChar *c2 = INITPTR;
194 33 : int length = 0;
195 :
196 33 : if (sp == INITPTR) {
197 1 : errno = EINVAL;
198 1 : goto EXIT;
199 : }
200 32 : if (start_tag == INITPTR) {
201 1 : errno = EINVAL;
202 1 : goto EXIT;
203 : }
204 31 : if (end_tag == INITPTR) {
205 1 : errno = EINVAL;
206 1 : goto EXIT;
207 : }
208 30 : if (sp->buffer_ == INITPTR) {
209 0 : errno = EINVAL;
210 0 : goto EXIT;
211 : }
212 :
213 30 : if (sp->parsing_mode_ == EBufferParsing) {
214 : /* Parser is created straight with data */
215 30 : size = strlen (sp->buffer_);
216 : } else {
217 : /* Parser is created with path and file information */
218 0 : size = fseek (sp->file_, 0, SEEK_END);
219 : }
220 :
221 : /* size or seeked cannot be 0 or negative */
222 30 : if (size <= 0 || seeked <= 0) {
223 6 : errno = EINVAL;
224 6 : goto EXIT;
225 : }
226 :
227 24 : whole_section = NEW2 (TSChar, size + 1);
228 24 : buff = NEW2 (TSChar, tmpsize + 1);
229 24 : current_section = NEW2 (TSChar, tmpsize + 1);
230 :
231 : /* Create parser */
232 24 : if (sp->parsing_mode_ == EBufferParsing) {
233 : /* Parser is created straight with data */
234 24 : STRCPY (whole_section, sp->buffer_, size + 1);
235 : } else {
236 : /* Parser is created with path and file information */
237 : do {
238 0 : read =
239 : fread (buff, sizeof (TSChar), tmpsize, sp->file_);
240 :
241 0 : if (sp->is_unicode_ == EFileUnicode) {
242 :
243 : /* Not supported yet!! */
244 :
245 : } else {
246 :
247 : /* This should be: 8bit to 16bit */
248 0 : STRCPY (current_section, buff,
249 : strlen (buff) + 1);
250 :
251 : /* Appends current section to whole section */
252 0 : STRCPY (&whole_section
253 : [strlen (whole_section) + 1]
254 : , current_section,
255 : strlen (current_section) + 1);
256 : }
257 :
258 0 : offset += tmpsize;
259 :
260 0 : } while (offset < size);
261 : }
262 :
263 24 : DELETE (buff);
264 24 : DELETE (current_section);
265 :
266 : /* User wants without c-style comments */
267 24 : if (sp->comment_type_ == ECStyleComments) {
268 0 : mp_parse_comments_off (whole_section);
269 : }
270 :
271 24 : if (sp->offset_ > (size - 1)) {
272 0 : errno = EFAULT;
273 0 : goto EXIT;
274 : }
275 24 : buff = &whole_section[sp->offset_];
276 :
277 : /* Check if start tag was given */
278 24 : if (strlen (start_tag) == 0) {
279 :
280 : /* skip line break, tabs, spaces, etc */
281 2 : while (strchr (" \n\t\r", *buff) != NULL) {
282 0 : buff++;
283 : }
284 1 : tag_count++;
285 1 : start_pos = buff;
286 : } else {
287 23 : c = buff;
288 23 : c2 = c;
289 :
290 : /* We are looking for occurence of start_tag */
291 23 : c2 = strstr (c, start_tag);
292 62 : while (c2 != NULL) {
293 36 : tag_count++;
294 36 : if (tag_count == seeked) {
295 : /* start tag found of correct one */
296 20 : start_pos = c2;
297 20 : start_pos += strlen (start_tag);
298 :
299 : /* skip line break, etc... */
300 220 : while (strchr (" \n\t\r", *start_pos) != NULL) {
301 180 : start_pos++;
302 : }
303 :
304 20 : break;
305 : } else {
306 : /* start tag found but not correct section */
307 : /* tag_count++; */
308 : }
309 16 : c = c2 + 1;
310 16 : c2 = strstr (c, start_tag);
311 : }
312 : }
313 :
314 : /* Seeked section is not found */
315 24 : if (tag_count != seeked) {
316 3 : goto EXIT;
317 : }
318 :
319 : /* Check if end tag was given */
320 21 : if (strlen (end_tag) == 0) {
321 1 : end_pos = &whole_section[strlen (whole_section) - 1];
322 : } else {
323 20 : c = start_pos;
324 20 : c2 = c;
325 :
326 : /* We are looking for occurence of end_tag */
327 20 : c2 = strstr (c, end_tag);
328 :
329 20 : if (c2 != NULL) {
330 20 : end_pos = c2;
331 : } else {
332 : /* end_tag was not found => length will be 0 */
333 0 : end_pos = start_pos;
334 : }
335 : }
336 :
337 : /* The length includes spaces and end of lines */
338 21 : length = strlen (start_pos) - strlen (end_pos);
339 :
340 21 : if (length <= 0) {
341 0 : goto EXIT;
342 : } else {
343 : /* Create MinSectionParser */
344 21 : section = mmp_create (length);
345 21 : mmp_set_data (section, whole_section, start_pos, length);
346 : }
347 33 : EXIT:
348 33 : return section;
349 : }
350 :
351 : /* ------------------------------------------------------------------------- */
352 : void mp_parse_comments_off (TSChar * buff)
353 6 : {
354 6 : TSChar *start_pos = INITPTR;
355 6 : TSChar *end_pos = INITPTR;
356 6 : TSChar *c = INITPTR;
357 6 : TSChar *tmp = INITPTR;
358 6 : int length = 0;
359 6 : TSearchType search_type = ENormalSearch;
360 :
361 6 : if (buff == INITPTR || strlen (buff) == 0)
362 1 : return;
363 :
364 5 : c = buff;
365 :
366 : /* Remove comments */
367 : do {
368 75 : switch (search_type) {
369 : case ENormalSearch:
370 58 : if (*c == '/') {
371 : /* Peek next TSCharacter */
372 7 : if (*(c + 1) == '/') {
373 3 : start_pos = c;
374 3 : c++;
375 3 : search_type = ECStyleSlash;
376 4 : } else if (*(c + 1) == '*') {
377 3 : start_pos = c;
378 3 : c++;
379 3 : search_type = ECStyleSlashAndAsterix;
380 : }
381 : }
382 58 : c++;
383 58 : break;
384 :
385 : case ECStyleSlash:
386 : /* Peek next TSCharacter(10 or '\n' in UNIX style ) */
387 8 : if (*(c + 1) == 0x0A) {
388 : /* Don't remove line break!!
389 : * ( Else this fails:
390 : * 1st line:"this is parsed text 1"
391 : * 2nd line:"this is parsed text 2
392 : * // this is comments"
393 : * 1st and 2nd lines will be together
394 : * and following
395 : * operations may fail)
396 : */
397 1 : end_pos = c + 1;
398 1 : search_type = EDoRemove;
399 1 : break;
400 : }
401 :
402 : /* Peek next TSCharacter(13 or '\r' in Symbian OS) */
403 7 : if (*(c + 1) == 0x0D) {
404 : /* Increment position */
405 0 : c++;
406 0 : if (*(c + 1) == 0x0A) {
407 : /* Don't remove line break!!
408 : * ( Else this fails:
409 : * 1st line:"this is parsed text 1"
410 : * 2nd line:"this is parsed text 2
411 : * // this is comments"
412 : * 1st and 2nd lines will be together
413 : * and followingoperations may fail)
414 : */
415 0 : end_pos = c;
416 0 : search_type = EDoRemove;
417 0 : break;
418 : }
419 : /* 0x0A not found, decrement position */
420 0 : c--;
421 : }
422 :
423 : /* Increment the lex position */
424 7 : c++;
425 : /* Take current end position */
426 7 : end_pos = c;
427 7 : break;
428 :
429 : case ECStyleSlashAndAsterix:
430 :
431 9 : if (*(c + 1) == '*') {
432 3 : c++;
433 3 : if (*(c + 1) == '/') {
434 3 : c++;
435 3 : end_pos = c + 1;
436 3 : search_type = EDoRemove;
437 3 : break;
438 : }
439 0 : c--;
440 : }
441 6 : c++;
442 6 : end_pos = c + 1;
443 6 : break;
444 :
445 : default:
446 0 : search_type = ENormalSearch;
447 : break;
448 : } /* switch */
449 :
450 : /* Remove comment */
451 75 : if (search_type == EDoRemove) {
452 4 : length = strlen (end_pos);
453 4 : tmp = NEW2 (TSChar, length + 2);
454 4 : STRCPY (tmp, end_pos, length + 1);
455 :
456 4 : STRCPY (start_pos, tmp, strlen (tmp) + 1);
457 :
458 4 : DELETE (tmp);
459 4 : tmp = INITPTR;
460 4 : length = 0;
461 :
462 4 : c = start_pos;
463 4 : search_type = ENormalSearch;
464 : }
465 75 : } while (*c != '\0');
466 :
467 : /* If comment is started and configure file ends to eof we remove
468 : comments althougt there are no end of line or '*\/' TSCharacters */
469 5 : if (search_type == ECStyleSlash
470 : || search_type == ECStyleSlashAndAsterix) {
471 :
472 2 : length = strlen (end_pos);
473 2 : tmp = NEW2 (TSChar, length + 2);
474 2 : STRCPY (tmp, end_pos, length + 1);
475 :
476 2 : STRCPY (start_pos, tmp, length + 1);
477 :
478 2 : DELETE (tmp);
479 2 : tmp = INITPTR;
480 2 : length = 0;
481 : }
482 :
483 5 : mp_handle_special_marks (buff);
484 : }
485 :
486 : /* ------------------------------------------------------------------------- */
487 : void mp_handle_special_marks (TSChar * buff)
488 11 : {
489 11 : TSChar *firstpos = INITPTR;
490 11 : TSChar *secondpos = INITPTR;
491 11 : TSChar *c = INITPTR;
492 :
493 11 : if (buff == INITPTR || strlen (buff) == 0)
494 1 : return;
495 :
496 10 : c = &buff[0];
497 :
498 : do {
499 114 : firstpos = c + 1;
500 114 : if (*c == '\\') {
501 :
502 1 : if (*(c + 1) == '/') {
503 0 : c++;
504 0 : secondpos = c + 1;
505 :
506 0 : if (*(c + 1) == '\\') {
507 0 : c++;
508 0 : if (*(c + 1) == '/'
509 : || *(c + 1) == '*') {
510 0 : STRCPY (secondpos,
511 : secondpos + 1,
512 : strlen (secondpos +
513 : 1));
514 0 : STRCPY (firstpos,
515 : firstpos + 1,
516 : strlen (firstpos +
517 : 1));
518 : }
519 : }
520 :
521 1 : } else if (*(c + 1) == '*') {
522 0 : c++;
523 0 : secondpos = c + 1;
524 :
525 0 : if (*(c + 1) == '\\') {
526 0 : c++;
527 0 : if (*(c + 1) == '/') {
528 0 : STRCPY (secondpos,
529 : secondpos + 1,
530 : strlen (secondpos +
531 : 1));
532 0 : STRCPY (firstpos,
533 : firstpos + 1,
534 : strlen (firstpos +
535 : 1));
536 : }
537 : }
538 : }
539 : }
540 114 : firstpos = INITPTR;
541 114 : secondpos = INITPTR;
542 114 : c++;
543 114 : } while (*c != '\0');
544 : }
545 :
546 : /* ------------------------------------------------------------------------- */
547 : /* ======================== FUNCTIONS ====================================== */
548 : /* ------------------------------------------------------------------------- */
549 : MinParser *mp_create (const TSChar * path, const TSChar * file,
550 : TCommentType comments)
551 305 : {
552 305 : MinParser *tmp = INITPTR;
553 305 : int plen = 0;
554 305 : int flen = 0;
555 305 : TSChar *filename = INITPTR;
556 305 : TSChar *c = INITPTR;
557 :
558 305 : if (path == INITPTR) {
559 3 : errno = EINVAL;
560 3 : goto EXIT;
561 : }
562 302 : if (file == INITPTR) {
563 1 : errno = EINVAL;
564 1 : goto EXIT;
565 : }
566 :
567 301 : plen = strlen (path);
568 301 : flen = strlen (file);
569 :
570 301 : if (plen == 0) {
571 2 : errno = EINVAL;
572 2 : goto EXIT;
573 : }
574 299 : if (flen == 0) {
575 1 : errno = EINVAL;
576 1 : goto EXIT;
577 : }
578 :
579 298 : tmp = NEW (MinParser);
580 298 : filename = NEW2 (TSChar, plen + flen + 2);
581 298 : c = &filename[plen];
582 :
583 : /* Initial values */
584 298 : tmp->file_ = INITPTR;
585 298 : tmp->offset_ = 0;
586 298 : tmp->comment_type_ = comments;
587 298 : tmp->parsing_mode_ = EFileParsing;
588 298 : tmp->buffer_tmp_ = INITPTR;
589 298 : tmp->buffer_ = INITPTR;
590 298 : tmp->is_unicode_ = 0;
591 298 : tmp->file_parser_ = INITPTR;
592 :
593 : /* Concatenate path and file and make sure that slash will be present */
594 298 : STRCPY (filename, path, plen);
595 298 : if (*(c - 1) != '/') {
596 283 : *c = '/';
597 283 : c++;
598 : }
599 298 : STRCPY (c, file, flen + 1);
600 298 : c[flen] = '\0';
601 :
602 : /* Open file */
603 298 : tmp->file_ = fopen (filename, "r");
604 298 : if (tmp->file_ == NULL) {
605 53 : DELETE (tmp);
606 53 : tmp = INITPTR;
607 53 : goto EXIT;
608 : }
609 :
610 : /* Create Min File Parser */
611 245 : tmp->file_parser_ =
612 : mfp_create (tmp->file_, EFileNotUnicode, tmp->comment_type_);
613 305 : EXIT:
614 305 : if (filename != INITPTR)
615 298 : DELETE (filename);
616 305 : return tmp;
617 : }
618 :
619 : /* ------------------------------------------------------------------------- */
620 : MinParser *mp_create_mem (const TSChar * buffer, TCommentType comments)
621 48 : {
622 48 : MinParser *tmp = INITPTR;
623 :
624 48 : if (buffer == INITPTR) {
625 1 : errno = EINVAL;
626 1 : goto EXIT;
627 : }
628 47 : if (strlen (buffer) == 0) {
629 0 : errno = EINVAL;
630 0 : goto EXIT;
631 : }
632 :
633 47 : tmp = NEW (MinParser);
634 47 : tmp->file_ = INITPTR;
635 47 : tmp->offset_ = 0;
636 47 : tmp->comment_type_ = comments;
637 47 : tmp->parsing_mode_ = EBufferParsing;
638 47 : tmp->buffer_tmp_ = INITPTR;
639 47 : tmp->buffer_ = INITPTR;
640 47 : tmp->is_unicode_ = EFileNotUnicode;
641 47 : tmp->file_parser_ = INITPTR;
642 47 : tmp->buffer_tmp_ = NEW2 (TSChar, strlen (buffer) + 1);
643 47 : tmp->buffer_ = &tmp->buffer_tmp_[0];
644 47 : STRCPY (tmp->buffer_, buffer, strlen (buffer) + 1);
645 48 : EXIT:
646 48 : return tmp;
647 : }
648 :
649 : /* ------------------------------------------------------------------------- */
650 : void mp_destroy (MinParser ** sp)
651 246 : {
652 246 : if (*sp == INITPTR)
653 2 : return;
654 :
655 244 : mfp_destroy (&((*sp)->file_parser_));
656 :
657 244 : if ((*sp)->parsing_mode_ == EFileParsing)
658 207 : fclose ((*sp)->file_);
659 :
660 244 : DELETE (*sp);
661 244 : *sp = INITPTR;
662 : }
663 :
664 : /* ------------------------------------------------------------------------- */
665 : MinSectionParser *mp_section (MinParser * sp, const TSChar * start_tag,
666 : const TSChar * end_tag, int seeked)
667 1476 : {
668 1476 : MinSectionParser *msp = INITPTR;
669 :
670 1476 : if (sp == INITPTR) {
671 1 : errno = EINVAL;
672 1 : goto EXIT;
673 : }
674 1475 : if (start_tag == INITPTR) {
675 2 : errno = EINVAL;
676 2 : goto EXIT;
677 : }
678 1473 : if (end_tag == INITPTR) {
679 2 : errno = EINVAL;
680 2 : goto EXIT;
681 : }
682 :
683 1471 : sp->offset_ = 0;
684 1471 : msp = mp_next_section (sp, start_tag, end_tag, seeked);
685 :
686 1476 : EXIT:
687 1476 : return msp;
688 : }
689 :
690 : /* ------------------------------------------------------------------------- */
691 : MinSectionParser *mp_next_section (MinParser * sp, const TSChar * start_tag,
692 : const TSChar * end_tag, int seeked)
693 1483 : {
694 1483 : MinSectionParser *msp = INITPTR;
695 :
696 1483 : if (sp == INITPTR) {
697 1 : errno = EINVAL;
698 1 : goto EXIT;
699 : }
700 1482 : if (start_tag == INITPTR) {
701 2 : errno = EINVAL;
702 2 : goto EXIT;
703 : }
704 1480 : if (end_tag == INITPTR) {
705 2 : errno = EINVAL;
706 2 : goto EXIT;
707 : }
708 :
709 : /* If parsing mode is set to file, we parse directly in the file */
710 1478 : if (sp->parsing_mode_ == EFileParsing) {
711 1462 : msp = mp_next_section_file (sp, start_tag, end_tag, seeked);
712 : } else {
713 : /* If parsing mode is set to buffer, process in old way */
714 16 : msp = mp_next_section_memory (sp, start_tag, end_tag, seeked);
715 : }
716 :
717 1483 : EXIT:
718 1483 : return msp;
719 : }
720 :
721 : /* ------------------------------------------------------------------------- */
722 : /* ================= OTHER EXPORTED FUNCTIONS ============================== */
723 : /* None */
724 :
725 : /* ================= TESTS FOR LOCAL FUNCTIONS ============================= */
726 : #ifdef MIN_UNIT_TEST
727 : #include "min_parser.tests"
728 : #endif /* MIN_UNIT_TEST */
729 : /* ------------------------------------------------------------------------- */
730 : /* End of file */
|