1 /* 2 * (C) Copyright David Gibson <dwg (at) 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 static 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 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