Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <getopt.h>
     18 #include <stdio.h>
     19 #include <stdlib.h>
     20 #include <string.h>
     21 #include <unistd.h>
     22 
     23 /*
     24  * The parameters to generate testing DTS
     25  * /dts-v1/ /plugin/;           <- header and plugin
     26  * /{
     27  *   level0 {                   <- depth
     28  *     level1 {
     29  *       ...
     30  *       node0: node0 {         <- node
     31  *         unused0 {}           <- unused
     32  *         unused1 {}
     33  *         ...
     34  *         status="disabled";
     35  *       }
     36  *       ...
     37  *     };
     38  *   };
     39  * };
     40  *
     41  * &node0 {                     <- append
     42  *    new_prop="foo";
     43  * }
     44  * ...
     45  *
     46  * &node0 {                     <- override
     47  *    status="okay";
     48  * }
     49  * ...
     50  */
     51 
     52 static const char short_options[] = "Hpd:u:n:a:w:o:";
     53 static struct option long_options[] = {
     54   { "no-header",    no_argument,       NULL, 'H' },
     55   { "plugin",       no_argument,       NULL, 'p' },
     56   { "depth",        required_argument, NULL, 'd' },
     57   { "unused",       required_argument, NULL, 'u' },
     58   { "node",         required_argument, NULL, 'n' },
     59   { "append",       required_argument, NULL, 'a' },
     60   { "override",     required_argument, NULL, 'w' },
     61   { "output",       required_argument, NULL, 'o' },
     62   { 0,              0,                 NULL, 0 }
     63 };
     64 
     65 struct gen_params {
     66   int no_header;    /* Doesn't add header */
     67   int plugin;       /* Add /plugin/ in header */
     68   int depth;        /* the depth of a node, 0 means generate on root node */
     69   int unused_num;   /* unused child nodes per node */
     70   int node_num;     /* the number to generate nodes */
     71   int append_num;   /* the number to generate appending references */
     72   int override_num; /* the number to generate overriding references */
     73 };
     74 
     75 
     76 static void output_header(FILE *fp, int is_plugin) {
     77   fprintf(fp, "/dts-v1/;\n");
     78   if (is_plugin) {
     79     fprintf(fp, "/plugin/;\n");
     80   }
     81   fprintf(fp, "\n");
     82 }
     83 
     84 static void output_root_begin(FILE *fp, int depth) {
     85   fprintf(fp, "/ {\n");
     86 
     87   int i;
     88   for (i = 0; i < depth; i++) {
     89     fprintf(fp, "level%d {\n", i);
     90   }
     91 }
     92 
     93 static void output_root_end(FILE *fp, int depth) {
     94   int i;
     95   for (i = 0; i < depth; i++) {
     96     fprintf(fp, "};\n");
     97   }
     98 
     99   fprintf(fp, "};\n\n");
    100 }
    101 
    102 static void output_unused_nodes(FILE *fp, int count) {
    103   int i;
    104   for (i = 0; i < count; i++) {
    105     fprintf(fp, "unused%d {};\n", i);
    106   }
    107 }
    108 
    109 static void output_prop_str(FILE *fp, const char *prop, const char *value) {
    110   /* TODO: should escape value */
    111   fprintf(fp, "%s=\"%s\";\n", prop, value);
    112 }
    113 
    114 static void output_nodes(FILE *fp, int count, const char *prop, const char *value) {
    115   int i;
    116   for (i = 0; i < count; i++) {
    117     fprintf(fp, "node%d: node%d {\n", i, i);
    118     output_prop_str(fp, prop, value);
    119     fprintf(fp, "};\n\n");
    120   }
    121 }
    122 
    123 static void output_ref_nodes(FILE *fp, int start_id, int count,
    124                       const char *prop, const char *value) {
    125   int i;
    126   for (i = start_id; i < start_id + count; i++) {
    127     fprintf(fp, "&node%d {\n", i);
    128     output_prop_str(fp, prop, value);
    129     fprintf(fp, "};\n\n");
    130   }
    131 }
    132 
    133 static int gen_dts(FILE *fp, const struct gen_params *params) {
    134   if (!params->no_header) {
    135     output_header(fp, params->plugin);
    136   }
    137 
    138   if (params->node_num > 0) {
    139     output_root_begin(fp, params->depth);
    140     output_unused_nodes(fp, params->unused_num);
    141     output_nodes(fp, params->node_num, "status", "disabled");
    142     output_root_end(fp, params->depth);
    143   }
    144 
    145   int start_id = 0;
    146   output_ref_nodes(fp, start_id, params->append_num, "new_prop", "bar");
    147   start_id += params->append_num;
    148   output_ref_nodes(fp, start_id, params->override_num, "status", "okay");
    149 
    150   return 0;
    151 }
    152 
    153 int main(int argc, char *argv[]) {
    154   const char *filename = NULL;
    155   struct gen_params params;
    156   memset(&params, 0, sizeof(struct gen_params));
    157 
    158   while (1) {
    159     int option_index = 0;
    160     int c = getopt_long(argc, argv, short_options, long_options, &option_index);
    161     if (c == -1) {
    162       break;
    163     }
    164     switch (c) {
    165     case 'H':
    166       params.no_header = 1;
    167       break;
    168     case 'p':
    169       params.plugin = 1;
    170       break;
    171     case 'd':
    172       params.depth = atoi(optarg);
    173       break;
    174     case 'u':
    175       params.unused_num = atoi(optarg);
    176       break;
    177     case 'n':
    178       params.node_num = atoi(optarg);
    179       break;
    180     case 'a':
    181       params.append_num = atoi(optarg);
    182       break;
    183     case 'w':
    184       params.override_num = atoi(optarg);
    185       break;
    186     case 'o':
    187       filename = optarg;
    188       break;
    189     case '?':
    190       break;
    191     }
    192   }
    193 
    194   FILE *fp = NULL;
    195   if (filename) {
    196     fp = fopen(filename, "wt");
    197     if (fp == NULL) {
    198       fprintf(stderr, "Can not create file: %s\n", filename);
    199       return -1;
    200     }
    201   }
    202 
    203   gen_dts(fp ? fp : stdout, &params);
    204 
    205   if (fp) {
    206     fclose(fp);
    207   }
    208 
    209   return 0;
    210 }
    211