1 /* -*- c-basic-offset:2; tab-width:2; indent-tabs-mode:nil -*- */
2 
3 #include "ef_parser.h"
4 
5 #include <stdio.h> /* NULL */
6 #include <pobl/bl_debug.h>
7 
8 /* --- global functions --- */
9 
ef_parser_init(ef_parser_t * parser)10 void ef_parser_init(ef_parser_t *parser) {
11   parser->str = NULL;
12   parser->marked_left = 0;
13   parser->left = 0;
14 
15   parser->is_eos = 0;
16 }
17 
__ef_parser_increment(ef_parser_t * parser)18 size_t __ef_parser_increment(ef_parser_t *parser) {
19   if (parser->left <= 1) {
20     parser->str += parser->left;
21     parser->left = 0;
22     parser->is_eos = 1;
23   } else {
24     parser->str++;
25     parser->left--;
26   }
27 
28   return parser->left;
29 }
30 
__ef_parser_n_increment(ef_parser_t * parser,size_t n)31 size_t __ef_parser_n_increment(ef_parser_t *parser, size_t n) {
32   if (parser->left <= n) {
33     parser->str += parser->left;
34     parser->left = 0;
35     parser->is_eos = 1;
36   } else {
37     parser->str += n;
38     parser->left -= n;
39   }
40 
41   return parser->left;
42 }
43 
__ef_parser_mark(ef_parser_t * parser)44 void __ef_parser_mark(ef_parser_t *parser) { parser->marked_left = parser->left; }
45 
__ef_parser_reset(ef_parser_t * parser)46 void __ef_parser_reset(ef_parser_t *parser) {
47   parser->str -= (parser->marked_left - parser->left);
48   parser->left = parser->marked_left;
49 }
50 
__ef_parser_full_reset(ef_parser_t * parser)51 void __ef_parser_full_reset(ef_parser_t *parser) {
52   if (parser->is_eos && parser->marked_left > parser->left) {
53     parser->is_eos = 0;
54   }
55 
56   __ef_parser_reset(parser);
57 }
58 
59 /*
60  * short cut function. (ignoring error)
61  */
ef_parser_next_char(ef_parser_t * parser,ef_char_t * ch)62 int ef_parser_next_char(ef_parser_t *parser, ef_char_t *ch) {
63   while (1) {
64 #if 0
65     /*
66      * just to be sure...
67      * ef_parser_mark() should be called inside [encoding]_next_char()
68      * function.
69      */
70     ef_parser_mark(parser);
71 #endif
72 
73     if ((*parser->next_char)(parser, ch)) {
74       return 1;
75     } else if (parser->is_eos ||
76                /* parser->next_char() returns error and skip to next char */
77                ef_parser_increment(parser) == 0) {
78 #ifdef __DEBUG
79       bl_debug_printf(BL_DEBUG_TAG " parser reached the end of string.\n");
80 #endif
81 
82       return 0;
83     }
84 #ifdef DEBUG
85     else {
86       bl_warn_printf(BL_DEBUG_TAG " parser->next_char() returns error , continuing...\n");
87     }
88 #endif
89   }
90 }
91