/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include /* * The parameters to generate testing DTS * /dts-v1/ /plugin/; <- header and plugin * /{ * level0 { <- depth * level1 { * ... * node0: node0 { <- node * unused0 {} <- unused * unused1 {} * ... * status="disabled"; * } * ... * }; * }; * }; * * &node0 { <- append * new_prop="foo"; * } * ... * * &node0 { <- override * status="okay"; * } * ... */ static const char short_options[] = "Hpd:u:n:a:w:o:"; static struct option long_options[] = { { "no-header", no_argument, NULL, 'H' }, { "plugin", no_argument, NULL, 'p' }, { "depth", required_argument, NULL, 'd' }, { "unused", required_argument, NULL, 'u' }, { "node", required_argument, NULL, 'n' }, { "append", required_argument, NULL, 'a' }, { "override", required_argument, NULL, 'w' }, { "output", required_argument, NULL, 'o' }, { 0, 0, NULL, 0 } }; struct gen_params { int no_header; /* Doesn't add header */ int plugin; /* Add /plugin/ in header */ int depth; /* the depth of a node, 0 means generate on root node */ int unused_num; /* unused child nodes per node */ int node_num; /* the number to generate nodes */ int append_num; /* the number to generate appending references */ int override_num; /* the number to generate overriding references */ }; static void output_header(FILE *fp, int is_plugin) { fprintf(fp, "/dts-v1/;\n"); if (is_plugin) { fprintf(fp, "/plugin/;\n"); } fprintf(fp, "\n"); } static void output_root_begin(FILE *fp, int depth) { fprintf(fp, "/ {\n"); int i; for (i = 0; i < depth; i++) { fprintf(fp, "level%d {\n", i); } } static void output_root_end(FILE *fp, int depth) { int i; for (i = 0; i < depth; i++) { fprintf(fp, "};\n"); } fprintf(fp, "};\n\n"); } static void output_unused_nodes(FILE *fp, int count) { int i; for (i = 0; i < count; i++) { fprintf(fp, "unused%d {};\n", i); } } static void output_prop_str(FILE *fp, const char *prop, const char *value) { /* TODO: should escape value */ fprintf(fp, "%s=\"%s\";\n", prop, value); } static void output_nodes(FILE *fp, int count, const char *prop, const char *value) { int i; for (i = 0; i < count; i++) { fprintf(fp, "node%d: node%d {\n", i, i); output_prop_str(fp, prop, value); fprintf(fp, "};\n\n"); } } static void output_ref_nodes(FILE *fp, int start_id, int count, const char *prop, const char *value) { int i; for (i = start_id; i < start_id + count; i++) { fprintf(fp, "&node%d {\n", i); output_prop_str(fp, prop, value); fprintf(fp, "};\n\n"); } } static int gen_dts(FILE *fp, const struct gen_params *params) { if (!params->no_header) { output_header(fp, params->plugin); } if (params->node_num > 0) { output_root_begin(fp, params->depth); output_unused_nodes(fp, params->unused_num); output_nodes(fp, params->node_num, "status", "disabled"); output_root_end(fp, params->depth); } int start_id = 0; output_ref_nodes(fp, start_id, params->append_num, "new_prop", "bar"); start_id += params->append_num; output_ref_nodes(fp, start_id, params->override_num, "status", "okay"); return 0; } int main(int argc, char *argv[]) { const char *filename = NULL; struct gen_params params; memset(¶ms, 0, sizeof(struct gen_params)); while (1) { int option_index = 0; int c = getopt_long(argc, argv, short_options, long_options, &option_index); if (c == -1) { break; } switch (c) { case 'H': params.no_header = 1; break; case 'p': params.plugin = 1; break; case 'd': params.depth = atoi(optarg); break; case 'u': params.unused_num = atoi(optarg); break; case 'n': params.node_num = atoi(optarg); break; case 'a': params.append_num = atoi(optarg); break; case 'w': params.override_num = atoi(optarg); break; case 'o': filename = optarg; break; case '?': break; } } FILE *fp = NULL; if (filename) { fp = fopen(filename, "wt"); if (fp == NULL) { fprintf(stderr, "Can not create file: %s\n", filename); return -1; } } gen_dts(fp ? fp : stdout, ¶ms); if (fp) { fclose(fp); } return 0; }