xref: /freebsd/usr.bin/mkesdb/yacc.y (revision 5e3934b15a2741b2de6b217e77dc9d798d740804)
1ad30f8e7SGabor Kovesdan /* $NetBSD: yacc.y,v 1.4 2005/06/02 02:09:25 lukem Exp $	*/
2ad30f8e7SGabor Kovesdan 
3ad30f8e7SGabor Kovesdan %{
4ad30f8e7SGabor Kovesdan /*-
5*1de7b4b8SPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause
6*1de7b4b8SPedro F. Giffuni  *
7ad30f8e7SGabor Kovesdan  * Copyright (c)2003 Citrus Project,
8ad30f8e7SGabor Kovesdan  * All rights reserved.
9ad30f8e7SGabor Kovesdan  *
10ad30f8e7SGabor Kovesdan  * Redistribution and use in source and binary forms, with or without
11ad30f8e7SGabor Kovesdan  * modification, are permitted provided that the following conditions
12ad30f8e7SGabor Kovesdan  * are met:
13ad30f8e7SGabor Kovesdan  * 1. Redistributions of source code must retain the above copyright
14ad30f8e7SGabor Kovesdan  *    notice, this list of conditions and the following disclaimer.
15ad30f8e7SGabor Kovesdan  * 2. Redistributions in binary form must reproduce the above copyright
16ad30f8e7SGabor Kovesdan  *    notice, this list of conditions and the following disclaimer in the
17ad30f8e7SGabor Kovesdan  *    documentation and/or other materials provided with the distribution.
18ad30f8e7SGabor Kovesdan  *
19ad30f8e7SGabor Kovesdan  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20ad30f8e7SGabor Kovesdan  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21ad30f8e7SGabor Kovesdan  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22ad30f8e7SGabor Kovesdan  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23ad30f8e7SGabor Kovesdan  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24ad30f8e7SGabor Kovesdan  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25ad30f8e7SGabor Kovesdan  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26ad30f8e7SGabor Kovesdan  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27ad30f8e7SGabor Kovesdan  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28ad30f8e7SGabor Kovesdan  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29ad30f8e7SGabor Kovesdan  * SUCH DAMAGE.
30ad30f8e7SGabor Kovesdan  */
31ad30f8e7SGabor Kovesdan 
32ad30f8e7SGabor Kovesdan #include <sys/types.h>
33ad30f8e7SGabor Kovesdan #include <sys/queue.h>
34ad30f8e7SGabor Kovesdan 
35ad30f8e7SGabor Kovesdan #include <assert.h>
36ad30f8e7SGabor Kovesdan #include <err.h>
37ad30f8e7SGabor Kovesdan #include <errno.h>
38ad30f8e7SGabor Kovesdan #include <limits.h>
39ad30f8e7SGabor Kovesdan #include <stdio.h>
40ad30f8e7SGabor Kovesdan #include <stdlib.h>
41ad30f8e7SGabor Kovesdan #include <string.h>
42ad30f8e7SGabor Kovesdan #include <unistd.h>
43ad30f8e7SGabor Kovesdan 
44ad30f8e7SGabor Kovesdan #include "citrus_namespace.h"
45ad30f8e7SGabor Kovesdan #include "citrus_types.h"
46ad30f8e7SGabor Kovesdan #include "citrus_region.h"
47ad30f8e7SGabor Kovesdan #include "citrus_esdb_file.h"
48ad30f8e7SGabor Kovesdan #include "citrus_db_hash.h"
49ad30f8e7SGabor Kovesdan #include "citrus_db_factory.h"
50ad30f8e7SGabor Kovesdan #include "citrus_lookup_factory.h"
51ad30f8e7SGabor Kovesdan 
52ad30f8e7SGabor Kovesdan #include "ldef.h"
53ad30f8e7SGabor Kovesdan 
54ad30f8e7SGabor Kovesdan extern FILE			*yyin;
55ad30f8e7SGabor Kovesdan 
56ad30f8e7SGabor Kovesdan static struct named_csid_list	 named_csids;
57ad30f8e7SGabor Kovesdan static char			*encoding, *name, *output = NULL, *variable;
58ad30f8e7SGabor Kovesdan static u_int32_t		 invalid;
59ad30f8e7SGabor Kovesdan static int			 debug = 0, num_csids = 0, use_invalid = 0;
60ad30f8e7SGabor Kovesdan 
61ad30f8e7SGabor Kovesdan static void	 dump_file(void);
62ad30f8e7SGabor Kovesdan static void	 register_named_csid(char *, u_int32_t);
63ad30f8e7SGabor Kovesdan static void	 set_invalid(u_int32_t);
64ad30f8e7SGabor Kovesdan static void	 set_prop_string(const char *, char **, char **);
65ad30f8e7SGabor Kovesdan %}
66ad30f8e7SGabor Kovesdan %union {
67ad30f8e7SGabor Kovesdan 	u_int32_t	i_value;
68ad30f8e7SGabor Kovesdan 	char		*s_value;
69ad30f8e7SGabor Kovesdan }
70ad30f8e7SGabor Kovesdan 
71ad30f8e7SGabor Kovesdan %token			R_NAME R_ENCODING R_VARIABLE R_DEFCSID R_INVALID
72ad30f8e7SGabor Kovesdan %token			R_LN
73ad30f8e7SGabor Kovesdan %token <i_value>	L_IMM
74ad30f8e7SGabor Kovesdan %token <s_value>	L_STRING
75ad30f8e7SGabor Kovesdan 
76ad30f8e7SGabor Kovesdan %%
77ad30f8e7SGabor Kovesdan 
78ad30f8e7SGabor Kovesdan file		: property
79ad30f8e7SGabor Kovesdan 		{ dump_file(); }
80ad30f8e7SGabor Kovesdan 
81ad30f8e7SGabor Kovesdan property	: /* empty */
82ad30f8e7SGabor Kovesdan 		| property R_LN
83ad30f8e7SGabor Kovesdan 		| property name R_LN
84ad30f8e7SGabor Kovesdan 		| property encoding R_LN
85ad30f8e7SGabor Kovesdan 		| property variable R_LN
86ad30f8e7SGabor Kovesdan 		| property defcsid R_LN
87ad30f8e7SGabor Kovesdan 		| property invalid R_LN
88ad30f8e7SGabor Kovesdan 
89ad30f8e7SGabor Kovesdan name		: R_NAME L_STRING
90ad30f8e7SGabor Kovesdan 		{
91ad30f8e7SGabor Kovesdan 			set_prop_string("NAME", &name, &$2);
92ad30f8e7SGabor Kovesdan 		}
93ad30f8e7SGabor Kovesdan 
94ad30f8e7SGabor Kovesdan encoding	: R_ENCODING L_STRING
95ad30f8e7SGabor Kovesdan 		{
96ad30f8e7SGabor Kovesdan 			set_prop_string("ENCODING", &encoding, &$2);
97ad30f8e7SGabor Kovesdan 		}
98ad30f8e7SGabor Kovesdan variable	: R_VARIABLE L_STRING
99ad30f8e7SGabor Kovesdan 		{
100ad30f8e7SGabor Kovesdan 			set_prop_string("VARIABLE", &variable, &$2);
101ad30f8e7SGabor Kovesdan 		}
102ad30f8e7SGabor Kovesdan defcsid		: R_DEFCSID L_STRING L_IMM
103ad30f8e7SGabor Kovesdan 		{
104ad30f8e7SGabor Kovesdan 			register_named_csid($2, $3);
105ad30f8e7SGabor Kovesdan 			$2 = NULL;
106ad30f8e7SGabor Kovesdan 		}
107ad30f8e7SGabor Kovesdan invalid		: R_INVALID L_IMM
108ad30f8e7SGabor Kovesdan 		{
109ad30f8e7SGabor Kovesdan 			set_invalid($2);
110ad30f8e7SGabor Kovesdan 		}
111ad30f8e7SGabor Kovesdan %%
112ad30f8e7SGabor Kovesdan 
113ad30f8e7SGabor Kovesdan int
114ad30f8e7SGabor Kovesdan yyerror(const char *s)
115ad30f8e7SGabor Kovesdan {
116ad30f8e7SGabor Kovesdan 
117af8e44c8SEd Schouten 	fprintf(stderr, "%s in %d\n", s, linenumber);
118ad30f8e7SGabor Kovesdan 
119ad30f8e7SGabor Kovesdan 	return (0);
120ad30f8e7SGabor Kovesdan }
121ad30f8e7SGabor Kovesdan 
122ad30f8e7SGabor Kovesdan #define CHKERR(ret, func, a)						\
123ad30f8e7SGabor Kovesdan do {									\
124ad30f8e7SGabor Kovesdan 	ret = func a;							\
125ad30f8e7SGabor Kovesdan 	if (ret)							\
126ad30f8e7SGabor Kovesdan 		errx(EXIT_FAILURE, "%s: %s", #func, strerror(ret));	\
127ad30f8e7SGabor Kovesdan } while (/*CONSTCOND*/0)
128ad30f8e7SGabor Kovesdan static void
dump_file(void)129ad30f8e7SGabor Kovesdan dump_file(void)
130ad30f8e7SGabor Kovesdan {
131ad30f8e7SGabor Kovesdan 	struct _db_factory *df;
132ad30f8e7SGabor Kovesdan 	struct _region data;
133ad30f8e7SGabor Kovesdan 	struct named_csid *csid;
134ad30f8e7SGabor Kovesdan 	FILE *fp;
135ad30f8e7SGabor Kovesdan 	char buf[100];
136ad30f8e7SGabor Kovesdan 	void *serialized;
137ad30f8e7SGabor Kovesdan 	size_t size;
138ad30f8e7SGabor Kovesdan 	int i, ret;
139ad30f8e7SGabor Kovesdan 
140ad30f8e7SGabor Kovesdan 	ret = 0;
141ad30f8e7SGabor Kovesdan 	if (!name) {
142ad30f8e7SGabor Kovesdan 		fprintf(stderr, "NAME is mandatory.\n");
143ad30f8e7SGabor Kovesdan 		ret = 1;
144ad30f8e7SGabor Kovesdan 	}
145ad30f8e7SGabor Kovesdan 	if (!encoding) {
146ad30f8e7SGabor Kovesdan 		fprintf(stderr, "ENCODING is mandatory.\n");
147ad30f8e7SGabor Kovesdan 		ret = 1;
148ad30f8e7SGabor Kovesdan 	}
149ad30f8e7SGabor Kovesdan 	if (ret)
150ad30f8e7SGabor Kovesdan 		exit(1);
151ad30f8e7SGabor Kovesdan 
152ad30f8e7SGabor Kovesdan 	/*
153ad30f8e7SGabor Kovesdan 	 * build database
154ad30f8e7SGabor Kovesdan 	 */
155ad30f8e7SGabor Kovesdan 	CHKERR(ret, _db_factory_create, (&df, _db_hash_std, NULL));
156ad30f8e7SGabor Kovesdan 
157ad30f8e7SGabor Kovesdan 	/* store version */
158ad30f8e7SGabor Kovesdan 	CHKERR(ret, _db_factory_add32_by_s, (df, _CITRUS_ESDB_SYM_VERSION,
159ad30f8e7SGabor Kovesdan 	    _CITRUS_ESDB_VERSION));
160ad30f8e7SGabor Kovesdan 
161ad30f8e7SGabor Kovesdan 	/* store encoding */
162ad30f8e7SGabor Kovesdan 	CHKERR(ret, _db_factory_addstr_by_s, (df, _CITRUS_ESDB_SYM_ENCODING,
163ad30f8e7SGabor Kovesdan 	    encoding));
164ad30f8e7SGabor Kovesdan 
165ad30f8e7SGabor Kovesdan 	/* store variable */
166ad30f8e7SGabor Kovesdan 	if (variable)
167ad30f8e7SGabor Kovesdan 		CHKERR(ret, _db_factory_addstr_by_s,
168ad30f8e7SGabor Kovesdan 		    (df, _CITRUS_ESDB_SYM_VARIABLE, variable));
169ad30f8e7SGabor Kovesdan 
170ad30f8e7SGabor Kovesdan 	/* store invalid */
171ad30f8e7SGabor Kovesdan 	if (use_invalid)
172ad30f8e7SGabor Kovesdan 		CHKERR(ret, _db_factory_add32_by_s, (df,
173ad30f8e7SGabor Kovesdan 		    _CITRUS_ESDB_SYM_INVALID, invalid));
174ad30f8e7SGabor Kovesdan 
175ad30f8e7SGabor Kovesdan 	/* store num of charsets */
176ad30f8e7SGabor Kovesdan 	CHKERR(ret, _db_factory_add32_by_s, (df, _CITRUS_ESDB_SYM_NUM_CHARSETS,
177ad30f8e7SGabor Kovesdan 	    num_csids));
178ad30f8e7SGabor Kovesdan 	i = 0;
179ad30f8e7SGabor Kovesdan 	STAILQ_FOREACH(csid, &named_csids, ci_entry) {
180ad30f8e7SGabor Kovesdan 		snprintf(buf, sizeof(buf), _CITRUS_ESDB_SYM_CSNAME_PREFIX "%d",
181ad30f8e7SGabor Kovesdan 		    i);
182ad30f8e7SGabor Kovesdan 		CHKERR(ret, _db_factory_addstr_by_s,
183ad30f8e7SGabor Kovesdan 		    (df, buf, csid->ci_symbol));
184ad30f8e7SGabor Kovesdan 		snprintf(buf, sizeof(buf), _CITRUS_ESDB_SYM_CSID_PREFIX "%d",
185ad30f8e7SGabor Kovesdan 		    i);
186ad30f8e7SGabor Kovesdan 		CHKERR(ret, _db_factory_add32_by_s, (df, buf, csid->ci_csid));
187ad30f8e7SGabor Kovesdan 		i++;
188ad30f8e7SGabor Kovesdan 	}
189ad30f8e7SGabor Kovesdan 
190ad30f8e7SGabor Kovesdan 	/*
191ad30f8e7SGabor Kovesdan 	 * dump database to file
192ad30f8e7SGabor Kovesdan 	 */
193ad30f8e7SGabor Kovesdan 	fp = output ? fopen(output, "wb") : stdout;
194ad30f8e7SGabor Kovesdan 	if (fp == NULL) {
195ad30f8e7SGabor Kovesdan 		perror("fopen");
196ad30f8e7SGabor Kovesdan 		exit(1);
197ad30f8e7SGabor Kovesdan 	}
198ad30f8e7SGabor Kovesdan 
199ad30f8e7SGabor Kovesdan 	/* dump database body */
200ad30f8e7SGabor Kovesdan 	size = _db_factory_calc_size(df);
201ad30f8e7SGabor Kovesdan 	serialized = malloc(size);
202ad30f8e7SGabor Kovesdan 	_region_init(&data, serialized, size);
203ad30f8e7SGabor Kovesdan 	CHKERR(ret, _db_factory_serialize, (df, _CITRUS_ESDB_MAGIC, &data));
204ad30f8e7SGabor Kovesdan 	if (fwrite(serialized, size, 1, fp) != 1)
205ad30f8e7SGabor Kovesdan 		err(EXIT_FAILURE, "fwrite");
206ad30f8e7SGabor Kovesdan 
207ad30f8e7SGabor Kovesdan 	fclose(fp);
208ad30f8e7SGabor Kovesdan }
209ad30f8e7SGabor Kovesdan 
210ad30f8e7SGabor Kovesdan static void
set_prop_string(const char * res,char ** store,char ** data)211ad30f8e7SGabor Kovesdan set_prop_string(const char *res, char **store, char **data)
212ad30f8e7SGabor Kovesdan {
213ad30f8e7SGabor Kovesdan 	char buf[256];
214ad30f8e7SGabor Kovesdan 
215ad30f8e7SGabor Kovesdan 	if (*store) {
216ad30f8e7SGabor Kovesdan 		snprintf(buf, sizeof(buf),
217ad30f8e7SGabor Kovesdan 		    "%s is duplicated. ignored the one", res);
218ad30f8e7SGabor Kovesdan 		yyerror(buf);
219ad30f8e7SGabor Kovesdan 		return;
220ad30f8e7SGabor Kovesdan 	}
221ad30f8e7SGabor Kovesdan 
222ad30f8e7SGabor Kovesdan 	*store = *data;
223ad30f8e7SGabor Kovesdan 	*data = NULL;
224ad30f8e7SGabor Kovesdan }
225ad30f8e7SGabor Kovesdan 
226ad30f8e7SGabor Kovesdan static void
set_invalid(u_int32_t inv)227ad30f8e7SGabor Kovesdan set_invalid(u_int32_t inv)
228ad30f8e7SGabor Kovesdan {
229ad30f8e7SGabor Kovesdan 
230ad30f8e7SGabor Kovesdan 	invalid = inv;
231ad30f8e7SGabor Kovesdan 	use_invalid = 1;
232ad30f8e7SGabor Kovesdan }
233ad30f8e7SGabor Kovesdan 
234ad30f8e7SGabor Kovesdan static void
register_named_csid(char * sym,u_int32_t val)235ad30f8e7SGabor Kovesdan register_named_csid(char *sym, u_int32_t val)
236ad30f8e7SGabor Kovesdan {
237ad30f8e7SGabor Kovesdan 	struct named_csid *csid;
238ad30f8e7SGabor Kovesdan 
239ad30f8e7SGabor Kovesdan 	STAILQ_FOREACH(csid, &named_csids, ci_entry) {
240ad30f8e7SGabor Kovesdan 		if (strcmp(csid->ci_symbol, sym) == 0) {
241ad30f8e7SGabor Kovesdan 			yyerror("multiply defined CSID");
242ad30f8e7SGabor Kovesdan 			exit(1);
243ad30f8e7SGabor Kovesdan 		}
244ad30f8e7SGabor Kovesdan 	}
245ad30f8e7SGabor Kovesdan 
246ad30f8e7SGabor Kovesdan 	csid = malloc(sizeof(*csid));
247ad30f8e7SGabor Kovesdan 	if (csid == NULL) {
248ad30f8e7SGabor Kovesdan 		perror("malloc");
249ad30f8e7SGabor Kovesdan 		exit(1);
250ad30f8e7SGabor Kovesdan 	}
251ad30f8e7SGabor Kovesdan 	csid->ci_symbol = sym;
252ad30f8e7SGabor Kovesdan 	csid->ci_csid = val;
253ad30f8e7SGabor Kovesdan 	STAILQ_INSERT_TAIL(&named_csids, csid, ci_entry);
254ad30f8e7SGabor Kovesdan 	num_csids++;
255ad30f8e7SGabor Kovesdan }
256ad30f8e7SGabor Kovesdan 
257ad30f8e7SGabor Kovesdan static void
do_mkdb(FILE * in)258ad30f8e7SGabor Kovesdan do_mkdb(FILE *in)
259ad30f8e7SGabor Kovesdan {
260ad30f8e7SGabor Kovesdan 	FILE *out;
261ad30f8e7SGabor Kovesdan 	int ret;
262ad30f8e7SGabor Kovesdan 
263ad30f8e7SGabor Kovesdan         /* dump DB to file */
264ad30f8e7SGabor Kovesdan 	out = output ? fopen(output, "wb") : stdout;
265ad30f8e7SGabor Kovesdan 	if (out == NULL)
266ad30f8e7SGabor Kovesdan 		err(EXIT_FAILURE, "fopen");
267ad30f8e7SGabor Kovesdan 
268ad30f8e7SGabor Kovesdan 	ret = _lookup_factory_convert(out, in);
269ad30f8e7SGabor Kovesdan 	fclose(out);
270ad30f8e7SGabor Kovesdan 	if (ret && output)
271ad30f8e7SGabor Kovesdan 		unlink(output); /* dump failure */
272ad30f8e7SGabor Kovesdan 	if (ret)
273ad30f8e7SGabor Kovesdan 		errx(EXIT_FAILURE, "%s\n", strerror(ret));
274ad30f8e7SGabor Kovesdan }
275ad30f8e7SGabor Kovesdan 
276ad30f8e7SGabor Kovesdan static void
usage(void)277ad30f8e7SGabor Kovesdan usage(void)
278ad30f8e7SGabor Kovesdan {
279ad30f8e7SGabor Kovesdan 	errx(EXIT_FAILURE,
280ad30f8e7SGabor Kovesdan 	    "usage:\n"
281b9c0f392SSevan Janiyan 	    "\t%s [-d] [-o outfile] [infile]\n"
282b9c0f392SSevan Janiyan 	    "\t%s -m [-d] [-o outfile] [infile]",
283ad30f8e7SGabor Kovesdan 	    getprogname(), getprogname());
284ad30f8e7SGabor Kovesdan }
285ad30f8e7SGabor Kovesdan 
286ad30f8e7SGabor Kovesdan int
main(int argc,char ** argv)287ad30f8e7SGabor Kovesdan main(int argc, char **argv)
288ad30f8e7SGabor Kovesdan {
289ad30f8e7SGabor Kovesdan 	FILE *in = NULL;
290ad30f8e7SGabor Kovesdan 	int ch, mkdb = 0;
291ad30f8e7SGabor Kovesdan 
292ad30f8e7SGabor Kovesdan 	while ((ch = getopt(argc, argv, "do:m")) != EOF) {
293ad30f8e7SGabor Kovesdan 		switch (ch) {
294ad30f8e7SGabor Kovesdan 		case 'd':
295ad30f8e7SGabor Kovesdan 			debug = 1;
296ad30f8e7SGabor Kovesdan 			break;
297ad30f8e7SGabor Kovesdan 		case 'o':
298ad30f8e7SGabor Kovesdan 			output = strdup(optarg);
299ad30f8e7SGabor Kovesdan 			break;
300ad30f8e7SGabor Kovesdan 		case 'm':
301ad30f8e7SGabor Kovesdan 			mkdb = 1;
302ad30f8e7SGabor Kovesdan 			break;
303ad30f8e7SGabor Kovesdan 		default:
304ad30f8e7SGabor Kovesdan 			usage();
305ad30f8e7SGabor Kovesdan 		}
306ad30f8e7SGabor Kovesdan 	}
307ad30f8e7SGabor Kovesdan 
308ad30f8e7SGabor Kovesdan 	argc -= optind;
309ad30f8e7SGabor Kovesdan 	argv += optind;
310ad30f8e7SGabor Kovesdan 	switch (argc) {
311ad30f8e7SGabor Kovesdan 	case 0:
312ad30f8e7SGabor Kovesdan 		in = stdin;
313ad30f8e7SGabor Kovesdan 		break;
314ad30f8e7SGabor Kovesdan 	case 1:
315ad30f8e7SGabor Kovesdan 		in = fopen(argv[0], "r");
316ad30f8e7SGabor Kovesdan 		if (!in)
317ad30f8e7SGabor Kovesdan 			err(EXIT_FAILURE, "%s", argv[0]);
318ad30f8e7SGabor Kovesdan 		break;
319ad30f8e7SGabor Kovesdan 	default:
320ad30f8e7SGabor Kovesdan 		usage();
321ad30f8e7SGabor Kovesdan 	}
322ad30f8e7SGabor Kovesdan 
323ad30f8e7SGabor Kovesdan 	if (mkdb)
324ad30f8e7SGabor Kovesdan 		do_mkdb(in);
325ad30f8e7SGabor Kovesdan 	else {
326ad30f8e7SGabor Kovesdan 		STAILQ_INIT(&named_csids);
327ad30f8e7SGabor Kovesdan 		yyin = in;
328ad30f8e7SGabor Kovesdan 		yyparse();
329ad30f8e7SGabor Kovesdan 	}
330ad30f8e7SGabor Kovesdan 
331ad30f8e7SGabor Kovesdan 	return (0);
332ad30f8e7SGabor Kovesdan }
333