1 /* -*- mode: C -*-
2 *
3 * File: rec-sex-parser.c
4 * Date: Tue Jan 12 18:01:37 2010
5 *
6 * GNU recutils - Sexy parser
7 *
8 */
9
10 /* Copyright (C) 2010-2019 Jose E. Marchesi */
11
12 /* This program is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26 #include <config.h>
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdio.h>
31
32 #include <rec-sex-parser.h>
33 #include "rec-sex-tab.h"
34 /*#include "rec-sex-lex.h" */
35
36 /*
37 * Data types
38 */
39
40 struct rec_sex_parser_s
41 {
42 char *in; /* String to be parsed. */
43 size_t index; /* Index in in_str. */
44 void *scanner; /* Flex scanner. */
45 bool case_insensitive;
46
47 rec_sex_ast_t ast;
48 };
49
50 /*
51 * Public functions
52 */
53
54 rec_sex_parser_t
rec_sex_parser_new(void)55 rec_sex_parser_new (void)
56 {
57 rec_sex_parser_t new;
58
59 new = malloc (sizeof (struct rec_sex_parser_s));
60 if (new)
61 {
62 new->in = NULL;
63 new->index = 0;
64 new->case_insensitive = false;
65
66 /* Initialize the sexy scanner. */
67 sexlex_init (&(new->scanner));
68 sexset_extra (new, new->scanner);
69 }
70
71 return new;
72 }
73
74 void *
rec_sex_parser_scanner(rec_sex_parser_t parser)75 rec_sex_parser_scanner (rec_sex_parser_t parser)
76 {
77 return parser->scanner;
78 }
79
80 void
rec_sex_parser_destroy(rec_sex_parser_t parser)81 rec_sex_parser_destroy (rec_sex_parser_t parser)
82 {
83 if (parser->scanner)
84 {
85 sexlex_destroy (parser->scanner);
86 }
87
88 free (parser->in);
89 free (parser);
90 }
91
92 rec_sex_ast_t
rec_sex_parser_ast(rec_sex_parser_t parser)93 rec_sex_parser_ast (rec_sex_parser_t parser)
94 {
95 return parser->ast;
96 }
97
98 void
rec_sex_parser_set_ast(rec_sex_parser_t parser,rec_sex_ast_t ast)99 rec_sex_parser_set_ast (rec_sex_parser_t parser,
100 rec_sex_ast_t ast)
101 {
102 parser->ast = ast;
103 }
104
105 bool
rec_sex_parser_case_insensitive(rec_sex_parser_t parser)106 rec_sex_parser_case_insensitive (rec_sex_parser_t parser)
107 {
108 return parser->case_insensitive;
109 }
110
111 void
rec_sex_parser_set_case_insensitive(rec_sex_parser_t parser,bool case_insensitive)112 rec_sex_parser_set_case_insensitive (rec_sex_parser_t parser,
113 bool case_insensitive)
114 {
115 parser->case_insensitive = case_insensitive;
116 }
117
118 void
rec_sex_parser_set_in(rec_sex_parser_t parser,const char * str)119 rec_sex_parser_set_in (rec_sex_parser_t parser,
120 const char *str)
121 {
122 if (parser->in)
123 {
124 free (parser->in);
125 parser->in = NULL;
126 }
127
128 parser->in = strdup (str);
129 parser->index = 0;
130 }
131
132 int
rec_sex_parser_getc(rec_sex_parser_t parser)133 rec_sex_parser_getc (rec_sex_parser_t parser)
134 {
135 int res;
136
137 res = -1;
138 if ((parser->in)
139 && (parser->index < strlen (parser->in)))
140 {
141 res = parser->in[parser->index++];
142 }
143
144 return res;
145 }
146
147 bool
rec_sex_parser_run(rec_sex_parser_t parser,const char * expr)148 rec_sex_parser_run (rec_sex_parser_t parser,
149 const char *expr)
150 {
151 int res;
152
153 rec_sex_parser_set_in (parser, expr);
154 if (!sexparse (parser))
155 {
156 res = true;
157 }
158 else
159 {
160 /* Parse error. */
161 res = false;
162 }
163
164 return res;
165 }
166
167 void
rec_sex_parser_print_ast(rec_sex_parser_t parser)168 rec_sex_parser_print_ast (rec_sex_parser_t parser)
169 {
170 rec_sex_ast_print (parser->ast);
171 }
172
173 /* End of rec-sex-parser.c */
174