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