- handle failure of getpwuid() more gracefully
[libfirm] / ir / libcore / lc_config_parser.y
1
2 %name-prefix="_lc_opt_"
3
4 %{
5
6 /*
7   libcore: library for basic data structures and algorithms.
8   Copyright (C) 2005  IPD Goos, Universit"at Karlsruhe, Germany
9
10   This library is free software; you can redistribute it and/or
11   modify it under the terms of the GNU Lesser General Public
12   License as published by the Free Software Foundation; either
13   version 2.1 of the License, or (at your option) any later version.
14
15   This library is distributed in the hope that it will be useful,
16   but WITHOUT ANY WARRANTY; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18   Lesser General Public License for more details.
19
20   You should have received a copy of the GNU Lesser General Public
21   License along with this library; if not, write to the Free Software
22   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23 */
24
25 #include <string.h>
26
27 #include "lc_opts_t.h"
28 #include "lc_parser_t.h"
29
30 static void group_open(void);
31 static void group_close(void);
32 static void lc_opt_set(void);
33 static void path_push(text_t text);
34
35 void PMANGLE(error)(const char *str);
36 int PMANGLE(linenr);
37
38 %}
39
40 %union {
41         text_t text;
42         int num;
43 }
44
45 %token SEP DATA
46 %token <text> IDENT
47
48 %%
49
50 main: dseq ;
51
52 decl: group
53         | option
54         ;
55
56 decls: decls decl
57         | decl
58         ;
59
60 dseq: decls | ;
61
62 group: path { group_open(); } '{' dseq '}' { group_close(); } ;
63
64 option: path DATA { lc_opt_set(); } ;
65
66 path: path SEP IDENT { path_push($3); }
67         | IDENT { path_push($1); }
68         ;
69
70 %%
71
72 static lc_opt_error_handler_t *handler;
73 static struct obstack obst;
74 const char *optfilename = "";
75
76 void PMANGLE(error)(const char *str)
77 {
78         fprintf(stderr, "At line %d: %s\n", PMANGLE(linenr), str);
79 }
80
81 static const char *path_stack[128];
82 static int path_sp = 0;
83
84 static lc_opt_entry_t *grp_stack[128];
85 static int grp_sp = 0;
86 #define CURR_GRP (grp_stack[grp_sp - 1])
87
88 void lc_opt_init_parser(const char *filename, lc_opt_error_handler_t *err_handler)
89 {
90         PMANGLE(linenr) = 1;
91         obstack_init(&obst);
92         handler = err_handler;
93         optfilename = filename;
94         grp_stack[grp_sp++] = lc_opt_root_grp();
95 }
96
97 void _lc_opt_add_to_data_char(char c)
98 {
99         obstack_1grow(&obst, c);
100 }
101
102 static void path_push(text_t text)
103 {
104         obstack_grow0(&obst, text.str, text.len);
105         path_stack[path_sp++] = obstack_finish(&obst);
106 }
107
108 static void path_free(void)
109 {
110         obstack_free(&obst, (void *) path_stack[0]);
111         path_sp = 0;
112 }
113
114 static void group_open(void)
115 {
116         lc_opt_err_info_t err;
117         lc_opt_entry_t *grp = lc_opt_resolve_grp(CURR_GRP, path_stack, path_sp, &err);
118
119         path_free();
120
121         grp_stack[grp_sp++] = grp;
122 }
123
124 static void group_close(void)
125 {
126         grp_sp--;
127 }
128
129 static void lc_opt_set(void)
130 {
131         char *str = obstack_finish(&obst);
132
133         lc_opt_err_info_t err;
134         lc_opt_entry_t *opt = lc_opt_resolve_opt(CURR_GRP, path_stack, path_sp, &err);
135         lc_opt_raise_error(&err, handler, "At %s(%d): ", optfilename, PMANGLE(linenr));
136
137         lc_opt_occurs(opt, str, &err);
138         lc_opt_raise_error(&err, handler, "At %s(%d): ", optfilename, PMANGLE(linenr));
139
140         obstack_free(&obst, str);
141         path_free();
142 }