1 : /*
2 : * This file is part of MIN Test Framework. Copyright © 2008 Nokia Corporation
3 : * and/or its subsidiary(-ies).
4 : * Contact: Marko Hyyppä
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_item_parser.c
22 : * @version 0.1
23 : * @brief This file contains implementation of MIN Item Parser
24 : */
25 :
26 : /* ------------------------------------------------------------------------- */
27 : /* INCLUDE FILES */
28 : #include <stdlib.h>
29 : #include <string.h>
30 : #include <errno.h>
31 : #include "min_common.h"
32 : #include "min_item_parser.h"
33 :
34 : /* ------------------------------------------------------------------------- */
35 : /* EXTERNAL DATA STRUCTURES */
36 : /* None */
37 :
38 : /* ------------------------------------------------------------------------- */
39 : /* EXTERNAL GLOBAL VARIABLES */
40 : /* None */
41 :
42 : /* ------------------------------------------------------------------------- */
43 : /* EXTERNAL FUNCTION PROTOTYPES */
44 : /* None */
45 :
46 : /* ------------------------------------------------------------------------- */
47 : /* GLOBAL VARIABLES */
48 : /* None */
49 :
50 : /* ------------------------------------------------------------------------- */
51 : /* CONSTANTS */
52 : /* None */
53 :
54 : /* ------------------------------------------------------------------------- */
55 : /* MACROS */
56 : /* None */
57 :
58 : /* ------------------------------------------------------------------------- */
59 : /* LOCAL GLOBAL VARIABLES */
60 : /* None */
61 :
62 : /* ------------------------------------------------------------------------- */
63 : /* LOCAL CONSTANTS AND MACROS */
64 : /* None */
65 :
66 : /* ------------------------------------------------------------------------- */
67 : /* MODULE DATA STRUCTURES */
68 : /* None */
69 :
70 : /* ------------------------------------------------------------------------- */
71 : /* LOCAL FUNCTION PROTOTYPES */
72 : /* None */
73 :
74 : /* ------------------------------------------------------------------------- */
75 : /* FORWARD DECLARATIONS */
76 : /* None */
77 :
78 : /* ==================== LOCAL FUNCTIONS ==================================== */
79 : /* None */
80 :
81 : /* ======================== FUNCTIONS ====================================== */
82 : /** Creates MIN Item Parser data structures with given string data.
83 : * @param section Pointer to section string.
84 : * @param start_pos Start position with integer value in given section string.
85 : * @param length Length integer value of given section string.
86 : * @return Pointer to created MIN Item Parser data structure.
87 : * If error result then pointer has got INITPTR value.
88 : *
89 : * Possible errors:
90 : * - ENOMEM not enough memory to create data structure.
91 : */
92 : MinItemParser *mip_create (TSChar * section, int start_pos, int length)
93 7229 : {
94 7229 : MinItemParser *mip = INITPTR;
95 :
96 7229 : if ((section != INITPTR) && (section != NULL) &&
97 : (start_pos >= 0) && (start_pos < strlen (section)) &&
98 : (length > 0)) {
99 :
100 6110 : mip = NEW (MinItemParser);
101 :
102 6110 : if (mip != NULL) {
103 6110 : mip->item_line_section_ = NEW2 (TSChar, length + 1);
104 :
105 6110 : if (mip->item_line_section_) {
106 6110 : STRCPY (mip->item_line_section_,
107 : (section + start_pos), length);
108 6110 : mip->item_line_section_[length] = '\0';
109 6110 : mip->item_skip_and_mark_pos_ = INITPTR;
110 6110 : mip->get_methods_indicator_ = ESFalse;
111 6110 : mip->parsing_type_ = ENormalParsing;
112 : } else {
113 : /* SIP creation failed,
114 : * free SIP memory allocation */
115 0 : DELETE (mip);
116 0 : mip = INITPTR;
117 0 : errno = ENOMEM;
118 : }
119 : } else {
120 : /* SIP creation failed, returns INITPTR */
121 0 : mip = INITPTR;
122 0 : errno = ENOMEM;
123 : }
124 : }
125 :
126 7229 : return mip;
127 : }
128 :
129 : /* ------------------------------------------------------------------------- */
130 : /** Frees allocated memory of MIN Item Parser data structure.
131 : * @param mip Pointer to existing MIN Item Parser data structure.
132 : */
133 : void mip_destroy (MinItemParser ** mip)
134 5297 : {
135 5297 : if (*mip != INITPTR) {
136 5286 : if ((*mip)->item_line_section_ != INITPTR) {
137 5286 : DELETE ((*mip)->item_line_section_);
138 : }
139 5286 : DELETE (*mip);
140 5286 : *mip = INITPTR;
141 : }
142 5297 : }
143 :
144 : /* ------------------------------------------------------------------------- */
145 : /** Parses MIN Item Parser section for start, end and extra end positions
146 : * including length value of parsed part of section.
147 : * @param mip Pointer to existing MIN Item Parser data structure.
148 : * @param start_tag Pointer to Start Tag string which be used with parsing.
149 : * @param ref_start_pos Start Position (char*) of parsed result string.
150 : * @param ref_end_pos End Position (char*) of parsed result string.
151 : * @param ref_length Length value of parsed result string.
152 : * @param ref_extra_end_pos Extra End Position (char*) of parsed result
153 : * string. Used when be found quated strings.
154 : * @return Returns result value. If parsing completed successfully then
155 : * value 0, else returns error code.
156 : *
157 : * Possible errors:
158 : * - EINVAL and error code -1 when parsing operation failed.
159 : */
160 : int mip_parse_start_and_end_pos (MinItemParser * mip, TSChar * start_tag,
161 : TSChar ** ref_start_pos,
162 : TSChar ** ref_end_pos, int *ref_length,
163 : TSChar ** ref_extra_end_pos)
164 14060 : {
165 14060 : int retval = 0;
166 14060 : TSChar *start_pos = NULL;
167 14060 : TSChar *end_pos = INITPTR;
168 14060 : TSChar *extra_end_pos = INITPTR; /* Normally this is INITPTR */
169 14060 : TSChar search_type = ENormalSearch;
170 14060 : TSChar *section = INITPTR;
171 14060 : TSChar *check_end = INITPTR;
172 14060 : int length = 0;
173 14060 : TSBool loop = ESFalse;
174 :
175 14060 : if (mip == INITPTR)
176 1 : goto EXIT;
177 :
178 21776 : if ((mip->get_methods_indicator_ == ESTrue) &&
179 : (mip->item_skip_and_mark_pos_ != INITPTR)) {
180 7717 : section = mip->item_skip_and_mark_pos_;
181 : } else {
182 6342 : section = mip->item_line_section_;
183 : }
184 14059 : if (start_tag != INITPTR) {
185 6617 : if (strlen (start_tag) > 0) {
186 : /* Find string after given start tag */
187 537 : section = strstr (section, start_tag);
188 537 : if (section == NULL)
189 191 : goto EXIT;
190 346 : start_pos = strchr (section, '=');
191 346 : if (start_pos == NULL)
192 0 : start_pos = strchr (section, ' ');
193 : }
194 : }
195 :
196 13868 : if (start_pos != NULL) {
197 346 : start_pos++;
198 : } else {
199 13522 : start_pos = section;
200 : }
201 :
202 27784 : while (*start_pos == ' ' && *start_pos != '\0') {
203 48 : start_pos++;
204 : }
205 :
206 : /*
207 : * Quotes have special meaning and information between quotes is
208 : * handled as a one string. Quotes not included to information.
209 : * Mode OFF.
210 : */
211 :
212 13868 : if (strncmp (start_pos, "\\\\", 2) == 0) {
213 3 : search_type = ENormalSearch;
214 3 : start_pos += 2;
215 9 : while (*start_pos == ' ')
216 3 : start_pos++;
217 3 : if (*start_pos == '\n' || *start_pos == '\0') {
218 1 : start_pos = INITPTR;
219 1 : goto EXIT;
220 : }
221 14028 : } else if ((mip->parsing_type_ == EQuoteStyleParsing) &&
222 : (strncmp (start_pos, "\"", 1) == 0)) {
223 163 : search_type = EQuoteStartSearch;
224 163 : start_pos += 1;
225 : } else {
226 13702 : search_type = ENormalSearch;
227 : }
228 :
229 13867 : check_end = start_pos;
230 13867 : length = 0;
231 13867 : loop = ESTrue;
232 :
233 120808 : while (loop) {
234 106941 : if (((search_type == EQuoteStartSearch)
235 : && (*check_end == '"'))
236 : || ((search_type != EQuoteStartSearch)
237 : && (*check_end == ' ')) || (*check_end == '\r')
238 : || (*check_end == '\n') || (*check_end == '\0')) {
239 13867 : loop = ESFalse;
240 : } else {
241 79207 : check_end++;
242 79207 : length++;
243 : }
244 : }
245 :
246 13867 : if (*check_end == '\0') {
247 3969 : extra_end_pos = INITPTR;
248 3969 : end_pos = check_end;
249 9898 : } else if (*check_end == '"') {
250 162 : end_pos = check_end - 1;
251 162 : check_end = check_end + 1;
252 162 : if (*check_end != '\r' &&
253 : *check_end != '\n' && *check_end != '\0') {
254 3 : extra_end_pos = check_end;
255 : }
256 : } else {
257 9736 : extra_end_pos = INITPTR;
258 9736 : end_pos = check_end + 1;
259 : }
260 :
261 : /* Quotes style parsing is in use.
262 : * Special handling when empty quotes "" */
263 13867 : if ((mip->parsing_type_ == EQuoteStyleParsing) &&
264 : (length <= 0) && (start_pos != NULL) &&
265 : (search_type == EQuoteStartSearch)) {
266 : /* Set new positions */
267 0 : start_pos--;
268 0 : end_pos--;
269 0 : extra_end_pos = INITPTR;
270 0 : length = end_pos - start_pos;
271 : }
272 :
273 14060 : EXIT:
274 : /* Start position is NULL or length is negative */
275 14060 : if ((start_pos == NULL) || (length <= 0)) {
276 758 : start_pos = INITPTR;
277 : }
278 :
279 14060 : if (start_pos == INITPTR) {
280 758 : end_pos = INITPTR;
281 758 : extra_end_pos = INITPTR;
282 758 : length = 0;
283 : /* Parsing failed, return error code */
284 758 : errno = EINVAL;
285 758 : retval = -1;
286 : }
287 :
288 14060 : *ref_start_pos = start_pos;
289 14060 : *ref_end_pos = end_pos;
290 14060 : *ref_extra_end_pos = extra_end_pos;
291 14060 : *ref_length = length;
292 :
293 14060 : return retval;
294 : }
295 :
296 : /* ------------------------------------------------------------------------- */
297 : /** Gets first string according to tag from MIN Item Parser section string.
298 : * @param mip Pointer to existing MIN Item Parser data structure.
299 : * @param tag Pointer to tag string for searching section part string.
300 : * @param string String reference for found first section part string.
301 : * @return Returns error code 0 if operation completes successfully,
302 : * else returns error code.
303 : *
304 : * Possible errors:
305 : * - EINVAL and error code -1 if searching operation failed.
306 : */
307 : int mip_get_string (MinItemParser * mip, TSChar * tag, TSChar ** string)
308 6582 : {
309 6582 : TSChar *start_pos = INITPTR;
310 6582 : TSChar *end_pos = INITPTR;
311 6582 : TSChar *extra_end_pos = INITPTR;
312 6582 : int length = 0;
313 : int retval;
314 :
315 6582 : errno = EINVAL;
316 6582 : retval = -1;
317 :
318 6582 : if (mip != INITPTR) {
319 6335 : if (strlen (mip->item_line_section_) > 0) {
320 6334 : mip->item_skip_and_mark_pos_ = INITPTR;
321 6334 : retval =
322 : mip_parse_start_and_end_pos (mip, tag, &start_pos,
323 : &end_pos, &length,
324 : &extra_end_pos);
325 6334 : if (retval == 0) {
326 6218 : *string = NEW2 (TSChar, length + 1);
327 6218 : if (string) {
328 6218 : STRCPY (*string, start_pos, length);
329 6218 : (*string)[length] = '\0';
330 :
331 6218 : if (extra_end_pos == INITPTR) {
332 6216 : mip->item_skip_and_mark_pos_ =
333 : end_pos;
334 : } else {
335 2 : mip->item_skip_and_mark_pos_ =
336 : extra_end_pos;
337 : }
338 :
339 6218 : mip->get_methods_indicator_ = ESTrue;
340 : /* Operation completed, no errors */
341 6218 : errno = 0;
342 6218 : retval = 0;
343 : }
344 : }
345 : }
346 : }
347 :
348 6582 : return retval;
349 : }
350 :
351 : /* ------------------------------------------------------------------------- */
352 : /** Gets next string according to previous section part string from
353 : * MIN Item Parser section string.
354 : * @param mip Pointer to existing MIN Item Parser data structure.
355 : * @param string String reference for found next section part string.
356 : * @return Returns error code 0 if operation completes successfully,
357 : * else returns error code.
358 : *
359 : * Possible errors:
360 : * - EINVAL and error code -1 if searching operation failed.
361 : */
362 : int mip_get_next_string (MinItemParser * mip, TSChar ** string)
363 5905 : {
364 5905 : TSChar *start_pos = INITPTR;
365 5905 : TSChar *end_pos = INITPTR;
366 5905 : TSChar *extra_end_pos = INITPTR;
367 5905 : int length = 0;
368 : int retval;
369 :
370 5905 : errno = EINVAL;
371 5905 : retval = -1;
372 :
373 5905 : if (mip != INITPTR) {
374 5905 : if ((mip->get_methods_indicator_ == ESTrue) &&
375 : (strlen (mip->item_line_section_) > 0)) {
376 :
377 5905 : retval = mip_parse_start_and_end_pos (mip, INITPTR,
378 : &start_pos,
379 : &end_pos,
380 : &length,
381 : &extra_end_pos);
382 :
383 5905 : if (retval == 0) {
384 5343 : if (extra_end_pos == INITPTR) {
385 5343 : mip->item_skip_and_mark_pos_ =
386 : end_pos;
387 : } else {
388 0 : mip->item_skip_and_mark_pos_ =
389 : extra_end_pos;
390 : }
391 :
392 5343 : if ((*string != INITPTR) && (*string != NULL)) {
393 343 : DELETE (*string);
394 : }
395 :
396 5343 : *string = NEW2 (TSChar, length + 1);
397 5343 : if (string) {
398 5343 : STRCPY (*string, start_pos, length);
399 5343 : (*string)[length] = '\0';
400 : /* Operation completed, no errors */
401 5343 : errno = 0;
402 5343 : retval = 0;
403 : }
404 : }
405 : }
406 : }
407 :
408 5905 : return retval;
409 : }
410 :
411 : /* ------------------------------------------------------------------------- */
412 : /** Gets next tagged string according to tag and earlier used
413 : * MIN Item Parser section string.
414 : * @param mip Pointer to existing MIN Item Parser data structure.
415 : * @param tag Pointer to tag string for searching next section part string.
416 : * @param string String reference for found section part string.
417 : * @return Returns error code 0 if operation completes successfully,
418 : * else returns error code.
419 : *
420 : * Possible errors:
421 : * - EINVAL and error code -1 if searching operation failed.
422 : */
423 : int mip_get_next_tagged_string (MinItemParser * mip, TSChar * tag,
424 : TSChar ** string)
425 72 : {
426 72 : TSChar *start_pos = INITPTR;
427 72 : TSChar *end_pos = INITPTR;
428 72 : TSChar *extra_end_pos = INITPTR;
429 72 : int length = 0;
430 : int retval;
431 :
432 72 : errno = EINVAL;
433 72 : retval = -1;
434 :
435 72 : if (mip != INITPTR) {
436 72 : if ((mip->get_methods_indicator_ == ESTrue) &&
437 : (strlen (mip->item_line_section_) > 0)) {
438 :
439 72 : retval = mip_parse_start_and_end_pos (mip, tag,
440 : &start_pos,
441 : &end_pos,
442 : &length,
443 : &extra_end_pos);
444 :
445 72 : if (retval == 0) {
446 14 : mip->item_skip_and_mark_pos_ = end_pos;
447 14 : *string = NEW2 (TSChar, length + 1);
448 14 : if (*string) {
449 14 : STRCPY (*string, start_pos, length);
450 14 : (*string)[length] = '\0';
451 : /* Operation completed, no errors */
452 14 : errno = 0;
453 14 : retval = 0;
454 : }
455 : }
456 : }
457 : }
458 :
459 72 : return retval;
460 : }
461 :
462 : /* ------------------------------------------------------------------------- */
463 : /** Gets first integer value according to tag from MIN Item Parser
464 : * section string.
465 : * @param mip Pointer to existing MIN Item Parser data structure.
466 : * @param tag Pointer to tag string for searching next section part string.
467 : * @param value Pointer to integer variable for be found first integer
468 : * section part.
469 : * @return Returns error code 0 if operation completes successfully,
470 : * else returns error code.
471 : *
472 : * Possible errors:
473 : * - EINVAL and error code -1 if searching operation failed.
474 : */
475 : int mip_get_int (MinItemParser * mip, TSChar * tag, int *value)
476 239 : {
477 239 : TSChar *start_pos = INITPTR;
478 239 : TSChar *end_pos = INITPTR;
479 239 : TSChar *extra_end_pos = INITPTR;
480 239 : int length = 0;
481 : int retval;
482 :
483 239 : errno = EINVAL;
484 239 : retval = -1;
485 :
486 239 : if (mip != INITPTR) {
487 239 : if (strlen (mip->item_line_section_) > 0) {
488 239 : retval = mip_parse_start_and_end_pos (mip, tag,
489 : &start_pos,
490 : &end_pos,
491 : &length,
492 : &extra_end_pos);
493 :
494 239 : if (retval == 0) {
495 239 : mip->item_skip_and_mark_pos_ = end_pos;
496 239 : mip->get_methods_indicator_ = ESTrue;
497 239 : *value = atoi (start_pos);
498 239 : errno = 0;
499 239 : retval = 0;
500 : }
501 : }
502 : }
503 :
504 239 : return retval;
505 : }
506 :
507 : /* ------------------------------------------------------------------------- */
508 : /** Gets next integer value according to earlier used MIN Item Parser
509 : * section string.
510 : * @param mip Pointer to existing MIN Item Parser data structure.
511 : * @param value Pointer to integer variable for be found next integer
512 : * section part.
513 : * @return Returns error code 0 if operation completes successfully,
514 : * else returns error code.
515 : *
516 : * Possible errors:
517 : * - EINVAL and error code -1 if searching operation failed.
518 : */
519 : int mip_get_next_int (MinItemParser * mip, int *value)
520 1481 : {
521 1481 : TSChar *start_pos = INITPTR;
522 1481 : TSChar *end_pos = INITPTR;
523 1481 : TSChar *extra_end_pos = INITPTR;
524 1481 : int length = 0;
525 : int retval;
526 :
527 1481 : errno = EINVAL;
528 1481 : retval = -1;
529 :
530 1481 : if (mip != INITPTR) {
531 1481 : if (strlen (mip->item_line_section_) > 0) {
532 1481 : retval = mip_parse_start_and_end_pos (mip, INITPTR,
533 : &start_pos,
534 : &end_pos,
535 : &length,
536 : &extra_end_pos);
537 :
538 1481 : if (retval == 0) {
539 1479 : mip->item_skip_and_mark_pos_ = end_pos;
540 1479 : *value = atoi (start_pos);
541 1479 : errno = 0;
542 1479 : retval = 0;
543 : }
544 : }
545 : }
546 :
547 1481 : return retval;
548 : }
549 :
550 : /* ------------------------------------------------------------------------- */
551 : /** Gets next tagged integer value according to given tag and earlier used
552 : * MIN Item Parser section string.
553 : * @param mip Pointer to existing MIN Item Parser data structure.
554 : * @param value Pointer to integer variable for be found next tagged
555 : * integer section part.
556 : * @return Returns error code 0 if operation completes successfully,
557 : * else returns error code.
558 : *
559 : * Possible errors:
560 : * - EINVAL and error code -1 if searching operation failed.
561 : */
562 : int mip_get_next_tagged_int (MinItemParser * mip, TSChar * tag, int *value)
563 20 : {
564 20 : TSChar *start_pos = INITPTR;
565 20 : TSChar *end_pos = INITPTR;
566 20 : TSChar *extra_end_pos = INITPTR;
567 20 : int length = 0;
568 : int retval;
569 :
570 20 : errno = EINVAL;
571 20 : retval = -1;
572 :
573 20 : if (mip != INITPTR) {
574 20 : if (strlen (mip->item_line_section_) > 0) {
575 20 : retval = mip_parse_start_and_end_pos (mip, tag,
576 : &start_pos,
577 : &end_pos,
578 : &length,
579 : &extra_end_pos);
580 :
581 20 : if (retval == 0) {
582 2 : mip->item_skip_and_mark_pos_ = end_pos;
583 2 : *value = atoi (start_pos);
584 2 : errno = 0;
585 2 : retval = 0;
586 : }
587 : }
588 : }
589 :
590 20 : return retval;
591 : }
592 :
593 : /* ------------------------------------------------------------------------- */
594 : /** Gets first unsigned integer value according to given tag from
595 : * MIN Item Parser section string.
596 : * @param mip Pointer to existing MIN Item Parser data structure.
597 : * @param tag Pointer to tag string for searching unsigned integer value.
598 : * @param value Pointer to unsigned integer variable for be found
599 : * first unsigned integer section part.
600 : * @return Returns error code 0 if operation completes successfully,
601 : * else returns error code.
602 : *
603 : * Possible errors:
604 : * - EINVAL and error code -1 if searching operation failed.
605 : */
606 : int mip_get_uint (MinItemParser * mip, TSChar * tag, unsigned int *value)
607 1 : {
608 1 : TSChar *start_pos = INITPTR;
609 1 : TSChar *end_pos = INITPTR;
610 1 : TSChar *extra_end_pos = INITPTR;
611 1 : int length = 0;
612 : int retval;
613 :
614 1 : errno = EINVAL;
615 1 : retval = -1;
616 :
617 1 : if (mip != INITPTR) {
618 1 : if (strlen (mip->item_line_section_) > 0) {
619 1 : retval = mip_parse_start_and_end_pos (mip, tag,
620 : &start_pos,
621 : &end_pos,
622 : &length,
623 : &extra_end_pos);
624 :
625 1 : if (retval == 0) {
626 1 : mip->item_skip_and_mark_pos_ = end_pos;
627 1 : mip->get_methods_indicator_ = ESTrue;
628 1 : *value = (unsigned int)atoi (start_pos);
629 1 : errno = 0;
630 1 : retval = 0;
631 : }
632 : }
633 : }
634 :
635 1 : return retval;
636 : }
637 :
638 : /* ------------------------------------------------------------------------- */
639 : /** Gets next unsigned integer value according to earlier used
640 : * MIN Item Parser section string.
641 : * @param mip Pointer to existing MIN Item Parser data structure.
642 : * @param value Pointer to unsigned integer variable for be found
643 : * next unsigned integer value section part.
644 : * @return Returns error code 0 if operation completes successfully,
645 : * else returns error code.
646 : *
647 : * Possible errors:
648 : * - EINVAL and error code -1 if searching operation failed.
649 : */
650 : int mip_get_next_uint (MinItemParser * mip, unsigned int *value)
651 1 : {
652 1 : TSChar *start_pos = INITPTR;
653 1 : TSChar *end_pos = INITPTR;
654 1 : TSChar *extra_end_pos = INITPTR;
655 1 : int length = 0;
656 : int retval;
657 :
658 1 : errno = EINVAL;
659 1 : retval = -1;
660 :
661 1 : if (mip != INITPTR) {
662 1 : if (strlen (mip->item_line_section_) > 0) {
663 1 : retval = mip_parse_start_and_end_pos (mip, INITPTR,
664 : &start_pos,
665 : &end_pos,
666 : &length,
667 : &extra_end_pos);
668 :
669 1 : if (retval == 0) {
670 1 : mip->item_skip_and_mark_pos_ = end_pos;
671 1 : *value = (unsigned int)atoi (start_pos);
672 1 : errno = 0;
673 1 : retval = 0;
674 : }
675 : }
676 : }
677 :
678 1 : return retval;
679 : }
680 :
681 : /* ------------------------------------------------------------------------- */
682 : /** Gets next tagged unsigned integer value according to given tag string
683 : * and earlier used MIN Item Parser section string.
684 : * @param mip Pointer to existing MIN Item Parser data structure.
685 : * @param tag Pointer to tag string for searching next tagged unsigned
686 : * integer value.
687 : * @param value Pointer to unsigned integer variable for be found
688 : * next tagged unsigned integer value section part.
689 : * @return Returns error code 0 if operation completes successfully,
690 : * else returns error code.
691 : *
692 : * Possible errors:
693 : * - EINVAL and error code -1 if searching operation failed.
694 : */
695 : int mip_get_next_tagged_uint (MinItemParser * mip, TSChar * tag,
696 : unsigned int *value)
697 1 : {
698 1 : TSChar *start_pos = INITPTR;
699 1 : TSChar *end_pos = INITPTR;
700 1 : TSChar *extra_end_pos = INITPTR;
701 1 : int length = 0;
702 : int retval;
703 :
704 1 : errno = EINVAL;
705 1 : retval = -1;
706 :
707 1 : if (mip != INITPTR) {
708 1 : if (strlen (mip->item_line_section_) > 0) {
709 1 : retval = mip_parse_start_and_end_pos (mip, tag,
710 : &start_pos,
711 : &end_pos,
712 : &length,
713 : &extra_end_pos);
714 :
715 1 : if (retval == 0) {
716 1 : mip->item_skip_and_mark_pos_ = end_pos;
717 1 : *value = (unsigned int)atoi (start_pos);
718 1 : errno = 0;
719 1 : retval = 0;
720 : }
721 : }
722 : }
723 :
724 1 : return retval;
725 : }
726 :
727 : /* ------------------------------------------------------------------------- */
728 : /** Gets first character according to given tag string from MIN Item Parser
729 : * section string.
730 : * @param mip Pointer to existing MIN Item Parser data structure.
731 : * @param tag Pointer to tag string for searching section part string.
732 : * @param chr Pointer to character variable for be found first character.
733 : * @return Returns error code 0 if operation completes successfully,
734 : * else returns error code.
735 : *
736 : * Possible errors:
737 : * - EINVAL and error code -1 if section string length is zero.
738 : * - EINVAL and error code -2 if parsing operation failed.
739 : */
740 : int mip_get_char (MinItemParser * mip, TSChar * tag, TSChar * chr)
741 1 : {
742 1 : TSChar *start_pos = INITPTR;
743 1 : TSChar *end_pos = INITPTR;
744 1 : TSChar *extra_end_pos = INITPTR;
745 1 : int length = 0;
746 : int retval;
747 :
748 1 : errno = EINVAL;
749 1 : retval = -1;
750 :
751 1 : if (mip != INITPTR) {
752 1 : if (strlen (mip->item_line_section_) > 0) {
753 1 : mip->item_skip_and_mark_pos_ = INITPTR;
754 1 : retval = mip_parse_start_and_end_pos (mip, tag,
755 : &start_pos,
756 : &end_pos,
757 : &length,
758 : &extra_end_pos);
759 :
760 1 : if (retval == 0) {
761 1 : mip->item_skip_and_mark_pos_ = end_pos;
762 1 : chr = start_pos;
763 1 : mip->get_methods_indicator_ = ESTrue;
764 : /* Parsing operation completed, no errros */
765 1 : errno = 0;
766 1 : retval = 0;
767 : }
768 : }
769 : }
770 :
771 1 : return retval;
772 : }
773 :
774 : /* ------------------------------------------------------------------------- */
775 : /** Gets next character according to earlier used MIN Item Parser
776 : * section string.
777 : * @param mip Pointer to existing MIN Item Parser data structure.
778 : * @param chr Pointer to character variable for be found next character.
779 : * @return Returns error code 0 if operation completes successfully,
780 : * else returns error code.
781 : *
782 : * Possible errors:
783 : * - EINVAL and error code -1 if next character searching failed.
784 : */
785 : int mip_get_next_char (MinItemParser * mip, TSChar * chr)
786 1 : {
787 1 : TSChar *start_pos = INITPTR;
788 1 : TSChar *end_pos = INITPTR;
789 1 : TSChar *extra_end_pos = INITPTR;
790 1 : int length = 0;
791 : int retval;
792 :
793 1 : errno = EINVAL;
794 1 : retval = -1;
795 :
796 1 : if (mip != INITPTR) {
797 1 : if ((mip->get_methods_indicator_ == ESTrue) &&
798 : (strlen (mip->item_line_section_) > 0)) {
799 :
800 1 : retval = mip_parse_start_and_end_pos (mip, INITPTR,
801 : &start_pos,
802 : &end_pos,
803 : &length,
804 : &extra_end_pos);
805 :
806 1 : if (retval == 0) {
807 1 : mip->item_skip_and_mark_pos_ = end_pos;
808 1 : chr = start_pos;
809 :
810 : /* Operation completed, no errors */
811 1 : errno = 0;
812 1 : retval = 0;
813 : }
814 : }
815 : }
816 :
817 1 : return retval;
818 : }
819 :
820 : /* ------------------------------------------------------------------------- */
821 : /** Gets next tagged character according to tag string and earlier used
822 : * MIN Item Parser section string.
823 : * @param mip Pointer to existing MIN Item Parser data structure.
824 : * @param tag Pointer to tag string for searching next tagged section part
825 : * string.
826 : * @param chr Pointer to character variable for be found next character.
827 : * @return Returns error code 0 if operation completes successfully,
828 : * else returns error code.
829 : *
830 : * Possible errors:
831 : * - EINVAL and error code -1 if next character searching failed.
832 : */
833 : int mip_get_next_tagged_char (MinItemParser * mip, TSChar * tag,
834 : TSChar * chr)
835 1 : {
836 1 : TSChar *start_pos = INITPTR;
837 1 : TSChar *end_pos = INITPTR;
838 1 : TSChar *extra_end_pos = INITPTR;
839 1 : int length = 0;
840 : int retval;
841 :
842 1 : errno = EINVAL;
843 1 : retval = -1;
844 :
845 1 : if (mip != INITPTR) {
846 1 : if ((mip->get_methods_indicator_ == ESTrue) &&
847 : (strlen (mip->item_line_section_) > 0)) {
848 :
849 1 : retval = mip_parse_start_and_end_pos (mip, tag,
850 : &start_pos,
851 : &end_pos,
852 : &length,
853 : &extra_end_pos);
854 :
855 1 : if (retval == 0) {
856 1 : mip->item_skip_and_mark_pos_ = end_pos;
857 1 : chr = start_pos;
858 :
859 : /* Operation completed, no errors */
860 1 : errno = 0;
861 1 : retval = 0;
862 : }
863 : }
864 : }
865 :
866 1 : return retval;
867 : }
868 :
869 : /* ------------------------------------------------------------------------- */
870 : /** Gets remainder string from MIN Item Parser section string.
871 : * @param mip Pointer to existing MIN Item Parser data structure.
872 : * @param string Reference to remainder string for be found section part.
873 : * @return Returns error code 0 if operation completes successfully,
874 : * else returns error code.
875 : *
876 : * Possible errors:
877 : * - EINVAL and error code -1 if next character searching failed.
878 : */
879 : int mip_get_remainder (MinItemParser * mip, TSChar ** string)
880 1 : {
881 1 : TSChar *pos = INITPTR;
882 : int retval;
883 :
884 1 : errno = EINVAL;
885 1 : retval = -1;
886 :
887 1 : if (mip != INITPTR) {
888 1 : if (mip->item_skip_and_mark_pos_ != INITPTR) {
889 1 : if ((strlen (mip->item_line_section_) > 0) &&
890 : ((strlen (mip->item_line_section_) >
891 : (mip->item_skip_and_mark_pos_ -
892 : mip->item_line_section_)))) {
893 1 : pos = mip->item_line_section_;
894 1 : pos = strtok (pos, " ");
895 :
896 1 : if (pos != NULL) {
897 1 : mip->item_skip_and_mark_pos_ = pos;
898 :
899 1 : *string =
900 : NEW2 (TSChar, strlen (pos) + 1);
901 1 : if (*string) {
902 1 : STRCPY (*string, pos,
903 : strlen (pos) + 1);
904 1 : errno = 0;
905 1 : retval = 0;
906 : }
907 : }
908 : }
909 : }
910 : }
911 :
912 1 : return retval;
913 : }
914 :
915 : /* ------------------------------------------------------------------------- */
916 : /** Sets parsing type value for MIN Item Parser data structure.
917 : * @param mip Pointer to existing MIN Item Parser data structure.
918 : * @param type New parsing type for parsing operations.
919 : * @return Returns error code 0 if operation completes successfully,
920 : * else returns error code.
921 : *
922 : * Possible errors:
923 : * - EINVAL and error code -1 if MIN Item Parser data structure not available
924 : */
925 : int mip_set_parsing_type (MinItemParser * mip, TParsingType type)
926 36 : {
927 36 : int retval = 0;
928 :
929 36 : if (mip != INITPTR) {
930 35 : mip->parsing_type_ = type;
931 : } else {
932 1 : errno = EINVAL;
933 1 : retval = -1;
934 : }
935 :
936 36 : return retval;
937 : }
938 :
939 : /* ------------------------------------------------------------------------- */
940 : /** Gets parsing type value from MIN Item Parser data structure.
941 : * @param mip Pointer to existing MIN Item Parser data structure.
942 : * @param type Returned parsing type in use of parsing operations.
943 : * @return Returns error code 0 if operation completes successfully,
944 : * else returns error code.
945 : *
946 : * Possible errors:
947 : * - EINVAL and error code -1 if MIN Item Parser data structure not available
948 : */
949 : TParsingType mip_get_parsing_type (MinItemParser * mip)
950 17 : {
951 : /* If SIP data not available, returns error value -1 */
952 17 : TParsingType type = -1;
953 :
954 17 : if (mip != INITPTR) {
955 16 : type = mip->parsing_type_;
956 : }
957 :
958 17 : return type;
959 : }
960 :
961 : /* ------------------------------------------------------------------------- */
962 : /** Replaces label inside of mip vith value if any occurence found.
963 : * @param mip [in:out] item parser instance which content will be examined.
964 : * @param label [in] label which occurence will be checked inside of mip
965 : * @param value [in] replacement for 'label'
966 : * @return 0 in case of success, -1 otherwise.
967 : * */
968 : int mip_replace (MinItemParser * mip, const TSChar * label,
969 : const TSChar * value)
970 8 : {
971 8 : int retval = ENOERR;
972 8 : char *c = INITPTR;
973 8 : char *c2 = INITPTR;
974 8 : unsigned int llen = 0;
975 8 : unsigned int vlen = 0;
976 8 : unsigned int length = 0;
977 8 : unsigned int i = 0;
978 8 : TSChar *newstr = INITPTR;
979 :
980 : /* do some error checking */
981 8 : if (mip == INITPTR) {
982 1 : retval = -1;
983 1 : goto EXIT;
984 : }
985 7 : if (label == INITPTR) {
986 1 : retval = -1;
987 1 : goto EXIT;
988 : }
989 6 : if (value == INITPTR) {
990 1 : retval = -1;
991 1 : goto EXIT;
992 : }
993 :
994 : /* Check if label used in this line */
995 5 : c = strstr (mip->item_line_section_, label);
996 :
997 : /* label found in current line, we need to replace it with value */
998 5 : if (c != NULL) {
999 :
1000 3 : llen = strlen (label);
1001 3 : vlen = strlen (value);
1002 :
1003 : /* length of the string after replacement */
1004 3 : length = strlen (mip->item_line_section_)
1005 : - llen + vlen + 1;
1006 :
1007 : /* allocate place for new string */
1008 3 : newstr = NEW2 (TSChar, length);
1009 3 : memset (newstr, '\0', length);
1010 :
1011 : /* copy content and replace label with value */
1012 3 : c2 = &mip->item_line_section_[0];
1013 27 : while (c2 != c) {
1014 21 : newstr[i] = *c2;
1015 21 : c2++;
1016 21 : i++;
1017 : }
1018 :
1019 3 : STRCPY (&newstr[i], value, vlen);
1020 3 : c = c + llen;
1021 3 : STRCPY (&newstr[i + vlen], c, strlen (c));
1022 :
1023 : /* replace buffers inside of item parser */
1024 3 : DELETE (mip->item_line_section_);
1025 3 : mip->item_line_section_ = newstr;
1026 : }
1027 8 : EXIT:
1028 8 : return retval;
1029 : }
1030 :
1031 : /* ------------------------------------------------------------------------- */
1032 : /* ================= OTHER EXPORTED FUNCTIONS ============================== */
1033 : /* None */
1034 :
1035 : /* ================= TESTS FOR LOCAL FUNCTIONS ============================= */
1036 : #ifdef MIN_UNIT_TEST
1037 : #include "min_item_parser.tests"
1038 : #endif /* MIN_UNIT_TEST */
1039 : /* ------------------------------------------------------------------------- */
1040 : /* End of file */
|