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