xref: /netbsd-src/external/gpl2/dtc/dist/convert-dtsv0-lexer.l (revision cc7d2833ecf67da5a5ddc470841931eb9f6723e4)
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 
13 PROPNODECHAR	[a-zA-Z0-9,._+*#?@-]
14 PATHCHAR	({PROPNODECHAR}|[/])
15 LABEL		[a-zA-Z_][a-zA-Z0-9_]*
16 STRING		\"([^\\"]|\\.)*\"
17 WS		[[:space:]]
18 COMMENT		"/*"([^*]|\*+[^*/])*\*+"/"
19 LINECOMMENT	"//".*\n
20 GAP		({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 
34 static int v1_tagged; /* = 0 */
35 static int cbase = 16;
36 static int saw_hyphen; /* = 0 */
37 static unsigned long long last_val;
38 static char *last_name; /* = NULL */
39 
40 static 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. */
183 static const char usage_synopsis[] = "convert-dtsv0 [options] <v0 dts file>...";
184 static const char usage_short_opts[] = "" USAGE_COMMON_SHORT_OPTS;
185 static struct option const usage_long_opts[] = {
186 	USAGE_COMMON_LONG_OPTS
187 };
188 static const char * const usage_opts_help[] = {
189 	USAGE_COMMON_OPTS_HELP
190 };
191 
192 static 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 
main(int argc,char * argv[])218 int 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