14f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin/* 24f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * Copyright (C) 2016 The Android Open Source Project 34f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * 44f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * Licensed under the Apache License, Version 2.0 (the "License"); 54f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * you may not use this file except in compliance with the License. 64f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * You may obtain a copy of the License at 74f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * 84f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * http://www.apache.org/licenses/LICENSE-2.0 94f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * 104f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * Unless required by applicable law or agreed to in writing, software 114f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * distributed under the License is distributed on an "AS IS" BASIS, 124f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * See the License for the specific language governing permissions and 144f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin * limitations under the License. 154f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin */ 164f00eda9fa05364edd719b05b88e4445682eeee5SzuWei Lin 172dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin#include <getopt.h> 182dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin#include <stdio.h> 192dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin#include <stdlib.h> 202dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin#include <string.h> 212dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin#include <unistd.h> 222dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 232dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin/* 242dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * The parameters to generate testing DTS 252dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * /dts-v1/ /plugin/; <- header and plugin 262dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * /{ 272dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * level0 { <- depth 282dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * level1 { 292dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * ... 302dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * node0: node0 { <- node 312dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * unused0 {} <- unused 322dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * unused1 {} 332dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * ... 342dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * status="disabled"; 352dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * } 362dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * ... 372dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * }; 382dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * }; 392dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * }; 402dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * 412dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * &node0 { <- append 422dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * new_prop="foo"; 432dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * } 442dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * ... 452dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * 462dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * &node0 { <- override 472dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * status="okay"; 482dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * } 492dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin * ... 502dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin */ 512dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 522dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Linstatic const char short_options[] = "Hpd:u:n:a:w:o:"; 532dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Linstatic struct option long_options[] = { 542dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin { "no-header", no_argument, NULL, 'H' }, 552dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin { "plugin", no_argument, NULL, 'p' }, 562dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin { "depth", required_argument, NULL, 'd' }, 572dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin { "unused", required_argument, NULL, 'u' }, 582dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin { "node", required_argument, NULL, 'n' }, 592dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin { "append", required_argument, NULL, 'a' }, 602dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin { "override", required_argument, NULL, 'w' }, 612dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin { "output", required_argument, NULL, 'o' }, 622dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin { 0, 0, NULL, 0 } 632dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin}; 642dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 652dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Linstruct gen_params { 662dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int no_header; /* Doesn't add header */ 672dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int plugin; /* Add /plugin/ in header */ 682dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int depth; /* the depth of a node, 0 means generate on root node */ 692dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int unused_num; /* unused child nodes per node */ 702dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int node_num; /* the number to generate nodes */ 712dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int append_num; /* the number to generate appending references */ 722dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int override_num; /* the number to generate overriding references */ 732dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin}; 742dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 752dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 762dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Linstatic void output_header(FILE *fp, int is_plugin) { 772dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fprintf(fp, "/dts-v1/;\n"); 782dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin if (is_plugin) { 792dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fprintf(fp, "/plugin/;\n"); 802dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin } 812dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fprintf(fp, "\n"); 822dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin} 832dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 842dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Linstatic void output_root_begin(FILE *fp, int depth) { 852dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fprintf(fp, "/ {\n"); 862dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 872dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int i; 882dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin for (i = 0; i < depth; i++) { 892dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fprintf(fp, "level%d {\n", i); 902dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin } 912dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin} 922dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 932dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Linstatic void output_root_end(FILE *fp, int depth) { 942dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int i; 952dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin for (i = 0; i < depth; i++) { 962dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fprintf(fp, "};\n"); 972dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin } 982dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 992dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fprintf(fp, "};\n\n"); 1002dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin} 1012dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 1022dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Linstatic void output_unused_nodes(FILE *fp, int count) { 1032dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int i; 1042dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin for (i = 0; i < count; i++) { 1052dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fprintf(fp, "unused%d {};\n", i); 1062dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin } 1072dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin} 1082dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 1092dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Linstatic void output_prop_str(FILE *fp, const char *prop, const char *value) { 1102dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin /* TODO: should escape value */ 1112dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fprintf(fp, "%s=\"%s\";\n", prop, value); 1122dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin} 1132dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 1142dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Linstatic void output_nodes(FILE *fp, int count, const char *prop, const char *value) { 1152dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int i; 1162dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin for (i = 0; i < count; i++) { 1172dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fprintf(fp, "node%d: node%d {\n", i, i); 1182dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin output_prop_str(fp, prop, value); 1192dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fprintf(fp, "};\n\n"); 1202dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin } 1212dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin} 1222dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 1232dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Linstatic void output_ref_nodes(FILE *fp, int start_id, int count, 1242dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin const char *prop, const char *value) { 1252dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int i; 1262dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin for (i = start_id; i < start_id + count; i++) { 1272dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fprintf(fp, "&node%d {\n", i); 1282dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin output_prop_str(fp, prop, value); 1292dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fprintf(fp, "};\n\n"); 1302dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin } 1312dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin} 1322dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 1332dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Linstatic int gen_dts(FILE *fp, const struct gen_params *params) { 1342dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin if (!params->no_header) { 1352dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin output_header(fp, params->plugin); 1362dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin } 1372dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 1382dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin if (params->node_num > 0) { 1392dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin output_root_begin(fp, params->depth); 1402dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin output_unused_nodes(fp, params->unused_num); 1412dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin output_nodes(fp, params->node_num, "status", "disabled"); 1422dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin output_root_end(fp, params->depth); 1432dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin } 1442dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 1452dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int start_id = 0; 1462dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin output_ref_nodes(fp, start_id, params->append_num, "new_prop", "bar"); 1472dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin start_id += params->append_num; 1482dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin output_ref_nodes(fp, start_id, params->override_num, "status", "okay"); 1492dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 1502dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin return 0; 1512dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin} 1522dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 1532dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Linint main(int argc, char *argv[]) { 1542dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin const char *filename = NULL; 1552dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin struct gen_params params; 1562dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin memset(¶ms, 0, sizeof(struct gen_params)); 1572dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 1582dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin while (1) { 1592dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int option_index = 0; 1602dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin int c = getopt_long(argc, argv, short_options, long_options, &option_index); 1612dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin if (c == -1) { 1622dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin break; 1632dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin } 1642dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin switch (c) { 1652dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin case 'H': 1662dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin params.no_header = 1; 1672dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin break; 1682dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin case 'p': 1692dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin params.plugin = 1; 1702dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin break; 1712dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin case 'd': 1722dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin params.depth = atoi(optarg); 1732dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin break; 1742dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin case 'u': 1752dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin params.unused_num = atoi(optarg); 1762dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin break; 1772dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin case 'n': 1782dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin params.node_num = atoi(optarg); 1792dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin break; 1802dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin case 'a': 1812dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin params.append_num = atoi(optarg); 1822dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin break; 1832dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin case 'w': 1842dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin params.override_num = atoi(optarg); 1852dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin break; 1862dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin case 'o': 1872dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin filename = optarg; 1882dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin break; 1892dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin case '?': 1902dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin break; 1912dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin } 1922dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin } 1932dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 1942dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin FILE *fp = NULL; 1952dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin if (filename) { 1962dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fp = fopen(filename, "wt"); 1972dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin if (fp == NULL) { 1982dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fprintf(stderr, "Can not create file: ", filename); 1992dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin return -1; 2002dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin } 2012dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin } 2022dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 2032dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin gen_dts(fp ? fp : stdout, ¶ms); 2042dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 2052dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin if (fp) { 2062dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin fclose(fp); 2072dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin } 2082dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin 2092dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin return 0; 2102dcb17e2252b17f56e1793bcf6ac479dc6e48319SzuWei Lin} 211