Home | History | Annotate | Download | only in dtc
      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