1 /* $NetBSD: treesource.c,v 1.1.1.2 2017/06/08 15:59:21 skrll Exp $ */ 2 3 /* 4 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. 5 * 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of the 10 * License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 20 * USA 21 */ 22 23 #include "dtc.h" 24 #include "srcpos.h" 25 26 extern FILE *yyin; 27 extern int yyparse(void); 28 extern YYLTYPE yylloc; 29 30 struct dt_info *parser_output; 31 bool treesource_error; 32 33 struct dt_info *dt_from_source(const char *fname) 34 { 35 parser_output = NULL; 36 treesource_error = false; 37 38 srcfile_push(fname); 39 yyin = current_srcfile->f; 40 yylloc.file = current_srcfile; 41 42 if (yyparse() != 0) 43 die("Unable to parse input tree\n"); 44 45 if (treesource_error) 46 die("Syntax error parsing input tree\n"); 47 48 return parser_output; 49 } 50 51 static void write_prefix(FILE *f, int level) 52 { 53 int i; 54 55 for (i = 0; i < level; i++) 56 fputc('\t', f); 57 } 58 59 static bool isstring(char c) 60 { 61 return (isprint((unsigned char)c) 62 || (c == '\0') 63 || strchr("\a\b\t\n\v\f\r", c)); 64 } 65 66 static void write_propval_string(FILE *f, struct data val) 67 { 68 const char *str = val.val; 69 int i; 70 struct marker *m = val.markers; 71 72 assert(str[val.len-1] == '\0'); 73 74 while (m && (m->offset == 0)) { 75 if (m->type == LABEL) 76 fprintf(f, "%s: ", m->ref); 77 m = m->next; 78 } 79 fprintf(f, "\""); 80 81 for (i = 0; i < (val.len-1); i++) { 82 char c = str[i]; 83 84 switch (c) { 85 case '\a': 86 fprintf(f, "\\a"); 87 break; 88 case '\b': 89 fprintf(f, "\\b"); 90 break; 91 case '\t': 92 fprintf(f, "\\t"); 93 break; 94 case '\n': 95 fprintf(f, "\\n"); 96 break; 97 case '\v': 98 fprintf(f, "\\v"); 99 break; 100 case '\f': 101 fprintf(f, "\\f"); 102 break; 103 case '\r': 104 fprintf(f, "\\r"); 105 break; 106 case '\\': 107 fprintf(f, "\\\\"); 108 break; 109 case '\"': 110 fprintf(f, "\\\""); 111 break; 112 case '\0': 113 fprintf(f, "\", "); 114 while (m && (m->offset <= (i + 1))) { 115 if (m->type == LABEL) { 116 assert(m->offset == (i+1)); 117 fprintf(f, "%s: ", m->ref); 118 } 119 m = m->next; 120 } 121 fprintf(f, "\""); 122 break; 123 default: 124 if (isprint((unsigned char)c)) 125 fprintf(f, "%c", c); 126 else 127 fprintf(f, "\\x%02hhx", c); 128 } 129 } 130 fprintf(f, "\""); 131 132 /* Wrap up any labels at the end of the value */ 133 for_each_marker_of_type(m, LABEL) { 134 assert (m->offset == val.len); 135 fprintf(f, " %s:", m->ref); 136 } 137 } 138 139 static void write_propval_cells(FILE *f, struct data val) 140 { 141 void *propend = val.val + val.len; 142 fdt32_t *cp = (fdt32_t *)val.val; 143 struct marker *m = val.markers; 144 145 fprintf(f, "<"); 146 for (;;) { 147 while (m && (m->offset <= ((char *)cp - val.val))) { 148 if (m->type == LABEL) { 149 assert(m->offset == ((char *)cp - val.val)); 150 fprintf(f, "%s: ", m->ref); 151 } 152 m = m->next; 153 } 154 155 fprintf(f, "0x%x", fdt32_to_cpu(*cp++)); 156 if ((void *)cp >= propend) 157 break; 158 fprintf(f, " "); 159 } 160 161 /* Wrap up any labels at the end of the value */ 162 for_each_marker_of_type(m, LABEL) { 163 assert (m->offset == val.len); 164 fprintf(f, " %s:", m->ref); 165 } 166 fprintf(f, ">"); 167 } 168 169 static void write_propval_bytes(FILE *f, struct data val) 170 { 171 void *propend = val.val + val.len; 172 const char *bp = val.val; 173 struct marker *m = val.markers; 174 175 fprintf(f, "["); 176 for (;;) { 177 while (m && (m->offset == (bp-val.val))) { 178 if (m->type == LABEL) 179 fprintf(f, "%s: ", m->ref); 180 m = m->next; 181 } 182 183 fprintf(f, "%02hhx", (unsigned char)(*bp++)); 184 if ((const void *)bp >= propend) 185 break; 186 fprintf(f, " "); 187 } 188 189 /* Wrap up any labels at the end of the value */ 190 for_each_marker_of_type(m, LABEL) { 191 assert (m->offset == val.len); 192 fprintf(f, " %s:", m->ref); 193 } 194 fprintf(f, "]"); 195 } 196 197 static void write_propval(FILE *f, struct property *prop) 198 { 199 int len = prop->val.len; 200 const char *p = prop->val.val; 201 struct marker *m = prop->val.markers; 202 int nnotstring = 0, nnul = 0; 203 int nnotstringlbl = 0, nnotcelllbl = 0; 204 int i; 205 206 if (len == 0) { 207 fprintf(f, ";\n"); 208 return; 209 } 210 211 for (i = 0; i < len; i++) { 212 if (! isstring(p[i])) 213 nnotstring++; 214 if (p[i] == '\0') 215 nnul++; 216 } 217 218 for_each_marker_of_type(m, LABEL) { 219 if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0')) 220 nnotstringlbl++; 221 if ((m->offset % sizeof(cell_t)) != 0) 222 nnotcelllbl++; 223 } 224 225 fprintf(f, " = "); 226 if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul)) 227 && (nnotstringlbl == 0)) { 228 write_propval_string(f, prop->val); 229 } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) { 230 write_propval_cells(f, prop->val); 231 } else { 232 write_propval_bytes(f, prop->val); 233 } 234 235 fprintf(f, ";\n"); 236 } 237 238 static void write_tree_source_node(FILE *f, struct node *tree, int level) 239 { 240 struct property *prop; 241 struct node *child; 242 struct label *l; 243 244 write_prefix(f, level); 245 for_each_label(tree->labels, l) 246 fprintf(f, "%s: ", l->label); 247 if (tree->name && (*tree->name)) 248 fprintf(f, "%s {\n", tree->name); 249 else 250 fprintf(f, "/ {\n"); 251 252 for_each_property(tree, prop) { 253 write_prefix(f, level+1); 254 for_each_label(prop->labels, l) 255 fprintf(f, "%s: ", l->label); 256 fprintf(f, "%s", prop->name); 257 write_propval(f, prop); 258 } 259 for_each_child(tree, child) { 260 fprintf(f, "\n"); 261 write_tree_source_node(f, child, level+1); 262 } 263 write_prefix(f, level); 264 fprintf(f, "};\n"); 265 } 266 267 268 void dt_to_source(FILE *f, struct dt_info *dti) 269 { 270 struct reserve_info *re; 271 272 fprintf(f, "/dts-v1/;\n\n"); 273 274 for (re = dti->reservelist; re; re = re->next) { 275 struct label *l; 276 277 for_each_label(re->labels, l) 278 fprintf(f, "%s: ", l->label); 279 fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n", 280 (unsigned long long)re->address, 281 (unsigned long long)re->size); 282 } 283 284 write_tree_source_node(f, dti->dt, 0); 285 } 286 287