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