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