1/*	$NetBSD: convert-dtsv0-lexer.l,v 1.1.1.3 2019/12/22 12:34:04 skrll Exp $	*/
2
3/* SPDX-License-Identifier: GPL-2.0-or-later */
4/*
5 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005, 2008.
6 */
7
8%option noyywrap nounput noinput never-interactive
9
10%x BYTESTRING
11%x PROPNODENAME
12
13PROPNODECHAR	[a-zA-Z0-9,._+*#?@-]
14PATHCHAR	({PROPNODECHAR}|[/])
15LABEL		[a-zA-Z_][a-zA-Z0-9_]*
16STRING		\"([^\\"]|\\.)*\"
17WS		[[:space:]]
18COMMENT		"/*"([^*]|\*+[^*/])*\*+"/"
19LINECOMMENT	"//".*\n
20GAP		({WS}|{COMMENT}|{LINECOMMENT})*
21
22%{
23#include <string.h>
24#include <stdlib.h>
25#include <stdarg.h>
26
27#include <errno.h>
28#include <assert.h>
29#include <fnmatch.h>
30
31#include "srcpos.h"
32#include "util.h"
33
34static int v1_tagged; /* = 0 */
35static int cbase = 16;
36static int saw_hyphen; /* = 0 */
37static unsigned long long last_val;
38static char *last_name; /* = NULL */
39
40static const struct {
41	const char *pattern;
42	int obase, width;
43} guess_table[] = {
44	{ "*-frequency", 10, 0 },
45	{ "num-*", 10, 0 },
46	{ "#*-cells", 10, 0 },
47	{ "*cache-line-size", 10, 0 },
48	{ "*cache-block-size", 10, 0 },
49	{ "*cache-size", 10, 0 },
50	{ "*cache-sets", 10, 0 },
51	{ "cell-index", 10, 0 },
52	{ "bank-width", 10, 0 },
53	{ "*-fifo-size", 10, 0 },
54	{ "*-frame-size", 10, 0 },
55	{ "*-channel", 10, 0 },
56	{ "current-speed", 10, 0 },
57	{ "phy-map", 16, 8 },
58	{ "dcr-reg", 16, 3 },
59	{ "reg", 16, 8 },
60	{ "ranges", 16, 8},
61};
62%}
63
64%%
65<*>"/include/"{GAP}{STRING}	ECHO;
66
67<*>\"([^\\"]|\\.)*\"	ECHO;
68
69<*>"/dts-v1/"	{
70			die("Input dts file is already version 1\n");
71		}
72
73<*>"/memreserve/"	{
74			if (!v1_tagged) {
75				fprintf(yyout, "/dts-v1/;\n\n");
76				v1_tagged = 1;
77			}
78
79			ECHO;
80			BEGIN(INITIAL);
81		}
82
83<*>{LABEL}:		ECHO;
84
85<INITIAL>[bodh]# {
86			if (*yytext == 'b')
87				cbase = 2;
88			else if (*yytext == 'o')
89				cbase = 8;
90			else if (*yytext == 'd')
91				cbase = 10;
92			else
93				cbase = 16;
94		}
95
96<INITIAL>[0-9a-fA-F]+	{
97			unsigned long long val;
98			int obase = 16, width = 0;
99			int i;
100
101			val = strtoull(yytext, NULL, cbase);
102
103			if (saw_hyphen)
104				val = val - last_val + 1;
105
106			if (last_name) {
107				for (i = 0; i < ARRAY_SIZE(guess_table); i++)
108					if (fnmatch(guess_table[i].pattern,
109					    last_name, 0) == 0) {
110						obase = guess_table[i].obase;
111						width = guess_table[i].width;
112					}
113			} else {
114				obase = 16;
115				width = 16;
116			}
117
118			if (cbase != 16)
119				obase = cbase;
120
121			switch (obase) {
122			case 2:
123			case 16:
124				fprintf(yyout, "0x%0*llx", width, val);
125				break;
126			case 8:
127				fprintf(yyout, "0%0*llo", width, val);
128				break;
129			case 10:
130				fprintf(yyout, "%*llu", width, val);
131				break;
132			}
133
134			cbase = 16;
135			last_val = val;
136			saw_hyphen = 0;
137		}
138
139\&{LABEL}		ECHO;
140
141"&{/"{PATHCHAR}+\}	ECHO;
142
143<INITIAL>"&/"{PATHCHAR}+ fprintf(yyout, "&{/%s}", yytext + 2);
144
145<BYTESTRING>[0-9a-fA-F]{2} ECHO;
146
147<BYTESTRING>"]"	{
148			ECHO;
149			BEGIN(INITIAL);
150		}
151
152<PROPNODENAME>{PROPNODECHAR}+ {
153			ECHO;
154			last_name = xstrdup(yytext);
155			BEGIN(INITIAL);
156		}
157
158<*>{GAP}	ECHO;
159
160<*>-		{	/* Hack to convert old style memreserves */
161			saw_hyphen = 1;
162			fprintf(yyout, " ");
163		}
164
165<*>.		{
166			if (!v1_tagged) {
167				fprintf(yyout, "/dts-v1/;\n\n");
168				v1_tagged = 1;
169			}
170
171			ECHO;
172			if (yytext[0] == '[') {
173				BEGIN(BYTESTRING);
174			}
175			if ((yytext[0] == '{')
176			    || (yytext[0] == ';')) {
177				BEGIN(PROPNODENAME);
178			}
179		}
180
181%%
182/* Usage related data. */
183static const char usage_synopsis[] = "convert-dtsv0 [options] <v0 dts file>...";
184static const char usage_short_opts[] = "" USAGE_COMMON_SHORT_OPTS;
185static struct option const usage_long_opts[] = {
186	USAGE_COMMON_LONG_OPTS
187};
188static const char * const usage_opts_help[] = {
189	USAGE_COMMON_OPTS_HELP
190};
191
192static void convert_file(const char *fname)
193{
194	const char suffix[] = "v1";
195	int len = strlen(fname);
196	char *newname;
197
198	newname = xmalloc(len + sizeof(suffix));
199	memcpy(newname, fname, len);
200	memcpy(newname + len, suffix, sizeof(suffix));
201
202	yyin = fopen(fname, "r");
203	if (!yyin)
204		die("Couldn't open input file %s: %s\n",
205		    fname, strerror(errno));
206
207	yyout = fopen(newname, "w");
208	if (!yyout)
209		die("Couldn't open output file %s: %s\n",
210		    newname, strerror(errno));
211
212	while(yylex())
213		;
214
215	free(newname);
216}
217
218int main(int argc, char *argv[])
219{
220	int opt;
221	int i;
222
223	while ((opt = util_getopt_long()) != EOF) {
224		switch (opt) {
225		case_USAGE_COMMON_FLAGS
226		}
227	}
228	if (argc < 2)
229		usage("missing filename");
230
231	for (i = 1; i < argc; i++) {
232		fprintf(stderr, "Converting %s from dts v0 to dts v1\n", argv[i]);
233		convert_file(argv[i]);
234	}
235
236	exit(0);
237}
238