Make the code consistent with the clocks and use the tree to
build the regulators.

Signed-off-by: Daniel Lezcano <daniel.lezc...@linaro.org>
---
 display.c    |   50 ++++++----
 powerdebug.c |   50 +++++----
 powerdebug.h |    4 +-
 regulator.c  |  322 ++++++++++++++++++++++++++++++----------------------------
 regulator.h  |   29 +-----
 5 files changed, 227 insertions(+), 228 deletions(-)

diff --git a/display.c b/display.c
index 8712023..3795547 100644
--- a/display.c
+++ b/display.c
@@ -190,13 +190,8 @@ void show_header(int selectedwindow)
        wrefresh(footer_win);
 }
 
-
-void show_regulator_info(struct regulator_info *reg_info, int nr_reg, int 
verbose)
+void print_regulator_header(void)
 {
-       int i, count = 1;
-
-       (void)verbose;
-
        werase(regulator_win);
        wattron(regulator_win, A_BOLD);
        print(regulator_win, 0, 0, "Name");
@@ -208,6 +203,34 @@ void show_regulator_info(struct regulator_info *reg_info, 
int nr_reg, int verbos
        print(regulator_win, 72, 0, "Min u-volts");
        print(regulator_win, 84, 0, "Max u-volts");
        wattroff(regulator_win, A_BOLD);
+       wrefresh(regulator_win);
+}
+
+void print_clock_header(void)
+{
+       werase(clock_labels);
+       wattron(clock_labels, A_BOLD);
+       print(clock_labels, 0, 0, "Name");
+       print(clock_labels, 56, 0, "Flags");
+       print(clock_labels, 75, 0, "Rate");
+       print(clock_labels, 88, 0, "Usecount");
+       print(clock_labels, 98, 0, "Children");
+       wattroff(clock_labels, A_BOLD);
+       wrefresh(clock_labels);
+}
+
+#if 0
+void show_regulator_info(struct regulator_info *reg_info, int nr_reg, int 
verbose)
+{
+       int i, count = 1;
+
+       print_regulator_header();
+
+       wrefresh(regulator_win);
+
+       return;
+
+       (void)verbose;
 
        for (i = 0; i < nr_reg; i++) {
                int col = 0;
@@ -248,20 +271,7 @@ void show_regulator_info(struct regulator_info *reg_info, 
int nr_reg, int verbos
        }
        wrefresh(regulator_win);
 }
-
-
-void print_clock_header(void)
-{
-       werase(clock_labels);
-       wattron(clock_labels, A_BOLD);
-       print(clock_labels, 0, 0, "Name");
-       print(clock_labels, 56, 0, "Flags");
-       print(clock_labels, 75, 0, "Rate");
-       print(clock_labels, 88, 0, "Usecount");
-       print(clock_labels, 98, 0, "Children");
-       wattroff(clock_labels, A_BOLD);
-       wrefresh(clock_labels);
-}
+#endif
 
 void print_sensor_header(void)
 {
diff --git a/powerdebug.c b/powerdebug.c
index 3a2edac..a303757 100644
--- a/powerdebug.c
+++ b/powerdebug.c
@@ -174,6 +174,21 @@ int keystroke_callback(bool *enter_hit, bool 
*findparent_ncurses,
                        options->selectedwindow = TOTAL_FEATURE_WINS - 1;
        }
 
+#if 0 /* TODO */
+       if (options->selectedwindow == REGULATOR) {
+
+               if (keystroke == KEY_DOWN) {
+                       display_next_line();
+                       *cont = true;
+               }
+
+               if (keystroke == KEY_UP) {
+                       display_prev_line();
+                       *cont = true;
+               }
+
+       }
+#endif
        if (options->selectedwindow == CLOCK) {
 
                if (keystroke == KEY_DOWN) {
@@ -242,8 +257,7 @@ int keystroke_callback(bool *enter_hit, bool 
*findparent_ncurses,
        return 0;
 }
 
-int mainloop(struct powerdebug_options *options,
-            struct regulator_info *reg_info, int nr_reg)
+int mainloop(struct powerdebug_options *options)
 {
        bool findparent_ncurses = false;
        bool refreshwin = false;
@@ -264,11 +278,8 @@ int mainloop(struct powerdebug_options *options,
                        create_selectedwindow(options->selectedwindow);
                }
 
-               if (options->selectedwindow == REGULATOR) {
-                       regulator_read_info(reg_info, nr_reg);
-                       show_regulator_info(reg_info, nr_reg,
-                                           options->verbose);
-               }
+               if (options->selectedwindow == REGULATOR)
+                       regulator_display();
 
                if (options->selectedwindow == CLOCK) {
 
@@ -315,13 +326,10 @@ int mainloop(struct powerdebug_options *options,
        return 0;
 }
 
-static int powerdebug_dump(struct powerdebug_options *options,
-                          struct regulator_info *reg_info, int nr_reg)
+static int powerdebug_dump(struct powerdebug_options *options)
 {
-       if (options->regulators) {
-               regulator_read_info(reg_info, nr_reg);
-               regulator_print_info(reg_info, nr_reg, options->verbose);
-       }
+       if (options->regulators)
+               regulator_dump();
 
        if (options->clocks)
                read_and_dump_clock_info(options->clkname);
@@ -332,15 +340,14 @@ static int powerdebug_dump(struct powerdebug_options 
*options,
        return 0;
 }
 
-static int powerdebug_display(struct powerdebug_options *options,
-                             struct regulator_info *reg_info, int nr_reg)
+static int powerdebug_display(struct powerdebug_options *options)
 {
        if (display_init()) {
                printf("failed to initialize display\n");
                return -1;
        }
 
-       if (mainloop(options, reg_info, nr_reg))
+       if (mainloop(options))
                return -1;
 
        return 0;
@@ -362,8 +369,7 @@ static struct powerdebug_options *powerdebug_init(void)
 int main(int argc, char **argv)
 {
        struct powerdebug_options *options;
-       struct regulator_info *regulators_info;
-       int numregulators, ret;
+       int ret;
 
        options = powerdebug_init();
        if (!options) {
@@ -376,8 +382,7 @@ int main(int argc, char **argv)
                return 1;
        }
 
-       regulators_info = regulator_init(&numregulators);
-       if (!regulators_info) {
+       if (regulator_init()) {
                printf("not enough memory to allocate regulators info\n");
                options->regulators = false;
        }
@@ -387,9 +392,8 @@ int main(int argc, char **argv)
                options->clocks = false;
        }
 
-       ret = options->dump ?
-               powerdebug_dump(options, regulators_info, numregulators) :
-               powerdebug_display(options, regulators_info, numregulators);
+       ret = options->dump ? powerdebug_dump(options) :
+               powerdebug_display(options);
 
        return ret < 0;
 }
diff --git a/powerdebug.h b/powerdebug.h
index 8fd2775..ab1e6f0 100644
--- a/powerdebug.h
+++ b/powerdebug.h
@@ -57,6 +57,4 @@ extern void show_header(int selectedwindow);
 extern void create_windows(int selectedwindow);
 extern void create_selectedwindow(int selectedwindow);
 
-struct regulator_info;
-extern void show_regulator_info(struct regulator_info *reg_info,
-                               int nr_reg, int verbose);
+extern int regulator_display(void);
diff --git a/regulator.c b/regulator.c
index 60529ed..d4b41e1 100644
--- a/regulator.c
+++ b/regulator.c
@@ -11,197 +11,209 @@
  * Contributors:
  *     Amit Arora <amit.ar...@linaro.org> (IBM Corporation)
  *       - initial API and implementation
+ *     Daniel Lezcano <daniel.lezc...@linaro.org> (IBM Corporation)
+ *       - rewrote code and API based on the tree
  
*******************************************************************************/
 
 #include "regulator.h"
 
 #define SYSFS_REGULATOR "/sys/class/regulator"
-
-struct regulator_info *regulator_init(int *nr_regulators)
+#define _GNU_SOURCE
+#include <stdio.h>
+#undef _GNU_SOURCE
+#include <sys/types.h>
+#include <stdbool.h>
+#include <dirent.h>
+#include <string.h>
+#include <stdlib.h>
+#include "powerdebug.h"
+#include "tree.h"
+#include "utils.h"
+
+struct regulator_info {
+       char name[NAME_MAX];
+       char state[VALUE_MAX];
+       char status[VALUE_MAX];
+       char type[VALUE_MAX];
+       char opmode[VALUE_MAX];
+       int microvolts;
+       int min_microvolts;
+       int max_microvolts;
+       int microamps;
+       int min_microamps;
+       int max_microamps;
+       int requested_microamps;
+       int num_users;
+};
+
+struct regulator_data {
+       const char *name;
+       const char *ifmt;
+       const char *ofmt;
+       bool derefme;
+};
+
+static struct regulator_data regdata[] = {
+       { "name",           "%s", "\tname: %s\n"                 },
+       { "status",         "%s", "\tstatus: %s\n"               },
+       { "state",          "%s", "\tstate: %s\n"                },
+       { "type",           "%s", "\ttype: %s\n"                 },
+       { "num_users",      "%d", "\tnum_users: %d\n",      true },
+       { "microvolts",     "%d", "\tmicrovolts: %d\n",     true },
+       { "max_microvolts", "%d", "\tmax_microvolts: %d\n", true },
+       { "min_microvolts", "%d", "\tmin_microvolts: %d\n", true },
+};
+
+static struct tree *reg_tree;
+
+static struct regulator_info *regulator_alloc(void)
 {
-       DIR *regdir;
-       struct dirent *item;
+       struct regulator_info *regi;
 
-       *nr_regulators = 0;
+       regi = malloc(sizeof(*regi));
+       if (regi)
+               memset(regi, 0, sizeof(*regi));
 
-       regdir = opendir(SYSFS_REGULATOR);
-       if (!regdir) {
-               fprintf(stderr, "failed to open '%s': %m\n", SYSFS_REGULATOR);
-               return NULL;
-       }
+       return regi;
+}
 
-       while ((item = readdir(regdir))) {
+static int regulator_dump_cb(struct tree *tree, void *data)
+{
+       int i;
+       char buffer[NAME_MAX];
+       size_t nregdata = sizeof(regdata) / sizeof(regdata[0]);
 
-               if (!strcmp(item->d_name, "."))
-                       continue;
+       if (!strncmp("regulator.", tree->name, strlen("regulator.")))
+               printf("\n%s:\n", tree->name);
 
-               if (!strcmp(item->d_name, ".."))
+       for (i = 0; i < nregdata; i++) {
+
+               if (file_read_value(tree->path, regdata[i].name,
+                                   regdata[i].ifmt, buffer))
                        continue;
 
-               (*nr_regulators)++;
+               printf(regdata[i].ofmt, regdata[i].derefme ?
+                      *((int *)buffer) : buffer);
        }
 
-       closedir(regdir);
+       return 0;
+}
 
-       return malloc(*nr_regulators * sizeof(struct regulator_info));
+int regulator_dump(void)
+{
+       printf("\nRegulator Information:\n");
+       printf("*********************\n\n");
+
+       return tree_for_each(reg_tree, regulator_dump_cb, NULL);
 }
 
-static void print_string_val(char *name, char *val)
+static int regulator_display_cb(struct tree *t, void *data)
 {
-       printf("\t%s=%s", name, val);
-       if (!strchr(val, '\n'))
-               printf("\n");
+       struct regulator_info *reg = t->private;
+       int *line = data;
+       char *buf;
+
+        /* we skip the root node of the tree */
+       if (!t->parent)
+               return 0;
+
+       if (!strlen(reg->name))
+               return 0;
+
+       if (asprintf(&buf, "%-11s %-11s %-11s %-11s %-11d %-11d %-11d %-12d",
+                    reg->name, reg->status, reg->state, reg->type,
+                    reg->num_users, reg->microvolts, reg->min_microvolts,
+                    reg->max_microvolts) < 0)
+               return -1;
+
+       display_print_line(REGULATOR, *line, buf, reg->num_users, t);
+
+       (*line)++;
+
+       free(buf);
+
+       return 0;
 }
 
-void regulator_print_info(struct regulator_info *reg_info, int nr_reg, int 
verbose)
+int regulator_display(void)
 {
-       int i;
+       int ret, line = 0;
 
-       printf("\nRegulator Information:\n");
-       printf("*********************\n\n");
+       display_reset_cursor(REGULATOR);
 
-       for (i = 0; i < nr_reg; i++) {
-               printf("Regulator %d:\n", i + 1);
-               print_string_val("name", reg_info[i].name);
-               if (strcmp(reg_info[i].status, ""))
-                       print_string_val("status", reg_info[i].status);
-               if (strcmp(reg_info[i].state, ""))
-                       print_string_val("state", reg_info[i].state);
+       print_regulator_header();
 
-               if (!verbose)
-                       continue;
+       ret = tree_for_each(reg_tree, regulator_display_cb, &line);
 
-               if (strcmp(reg_info[i].type, ""))
-                       print_string_val("type", reg_info[i].type);
-               if (strcmp(reg_info[i].opmode, ""))
-                       print_string_val("opmode", reg_info[i].opmode);
-
-               if (reg_info[i].microvolts)
-                       printf("\tmicrovolts=%d\n",
-                               reg_info[i].microvolts);
-               if (reg_info[i].min_microvolts)
-                       printf("\tmin_microvolts=%d\n",
-                               reg_info[i].min_microvolts);
-               if (reg_info[i].max_microvolts)
-                       printf("\tmax_microvolts=%d\n",
-                               reg_info[i].max_microvolts);
-
-               if (reg_info[i].microamps)
-                       printf("\tmicroamps=%d\n",
-                               reg_info[i].microamps);
-               if (reg_info[i].min_microamps)
-                       printf("\tmin_microamps=%d\n",
-                               reg_info[i].min_microamps);
-               if (reg_info[i].max_microamps)
-                       printf("\tmax_microamps=%d\n",
-                               reg_info[i].max_microamps);
-               if (reg_info[i].requested_microamps)
-                       printf("\trequested_microamps=%d\n",
-                               reg_info[i].requested_microamps);
-
-               if (reg_info[i].num_users)
-                       printf("\tnum_users=%d\n",
-                               reg_info[i].num_users);
-               printf("\n");
-       }
+       display_refresh_pad(REGULATOR);
 
-       if (!nr_reg && verbose) {
-               printf("Could not find regulator information!");
-               printf(" Looks like %s is empty.\n\n", SYSFS_REGULATOR);
-       }
+       return ret;
+}
 
-       printf("\n\n");
+static int regulator_filter_cb(const char *name)
+{
+       /* let's ignore some directories in order to avoid to be
+        * pulled inside the sysfs circular symlinks mess/hell
+        * (choose the word which fit better)
+        */
+       if (!strcmp(name, "device"))
+               return 1;
+
+       if (!strcmp(name, "subsystem"))
+               return 1;
+
+       if (!strcmp(name, "driver"))
+               return 1;
+
+       return 0;
 }
 
-static void read_info_from_dirent(struct regulator_info *reg_info,
-                                 struct dirent *ritem, char *str, int idx)
+static inline int read_regulator_cb(struct tree *t, void *data)
 {
-       if (!strcmp(ritem->d_name, "name"))
-               strcpy(reg_info[idx].name, str);
-       if (!strcmp(ritem->d_name, "state"))
-               strcpy(reg_info[idx].state, str);
-       if (!strcmp(ritem->d_name, "status"))
-               strcpy(reg_info[idx].status, str);
-
-       if (!strcmp(ritem->d_name, "type"))
-               strcpy(reg_info[idx].type, str);
-       if (!strcmp(ritem->d_name, "opmode"))
-               strcpy(reg_info[idx].opmode, str);
-
-       if (!strcmp(ritem->d_name, "microvolts"))
-               reg_info[idx].microvolts = atoi(str);
-       if (!strcmp(ritem->d_name, "min_microvolts"))
-               reg_info[idx].min_microvolts = atoi(str);
-       if (!strcmp(ritem->d_name, "max_microvolts"))
-               reg_info[idx].max_microvolts = atoi(str);
-
-       if (!strcmp(ritem->d_name, "microamps"))
-               reg_info[idx].microamps = atoi(str);
-       if (!strcmp(ritem->d_name, "min_microamps"))
-               reg_info[idx].min_microamps = atoi(str);
-       if (!strcmp(ritem->d_name, "max_microamps"))
-               reg_info[idx].max_microamps = atoi(str);
-       if (!strcmp(ritem->d_name, "requested_microamps"))
-               reg_info[idx].requested_microamps = atoi(str);
-
-       if (!strcmp(ritem->d_name, "num_users"))
-               reg_info[idx].num_users = atoi(str);
+       struct regulator_info *reg = t->private;
+
+       file_read_value(t->path, "name", "%s", reg->name);
+       file_read_value(t->path, "state", "%s", reg->state);
+       file_read_value(t->path, "status", "%s", reg->status);
+       file_read_value(t->path, "type", "%s", reg->type);
+       file_read_value(t->path, "opmode", "%s", reg->opmode);
+       file_read_value(t->path, "num_users", "%d", &reg->num_users);
+       file_read_value(t->path, "microvolts", "%d", &reg->microvolts);
+       file_read_value(t->path, "min_microvolts", "%d", &reg->min_microvolts);
+       file_read_value(t->path, "max_microvolts", "%d", &reg->max_microvolts);
+       file_read_value(t->path, "microamps", "%d", &reg->microamps);
+       file_read_value(t->path, "min_microamps", "%d", &reg->min_microamps);
+       file_read_value(t->path, "max_microamps", "%d", &reg->max_microamps);
+
+       return 0;
 }
 
-int regulator_read_info(struct regulator_info *reg_info, int nr_reg)
+static int fill_regulator_cb(struct tree *t, void *data)
 {
-       FILE *file = NULL;
-       DIR *regdir, *dir;
-       int len, count = 0, ret = 0;
-       char line[1024], filename[1024], *fptr;
-       struct dirent *item, *ritem;
-
-       regdir = opendir(SYSFS_REGULATOR);
-       if (!regdir)
-               return(1);
-       while ((item = readdir(regdir))) {
-               if (strlen(item->d_name) < 3)
-                       continue;
+       struct regulator_info *reg;
 
-               if (strncmp(item->d_name, "regulator", 9))
-                       continue;
+       reg = regulator_alloc();
+       if (!reg)
+               return -1;
+       t->private = reg;
 
-               len = sprintf(filename, "%s/%s", SYSFS_REGULATOR, item->d_name);
+        /* we skip the root node but we set it expanded for its children */
+       if (!t->parent)
+               return 0;
 
-               dir = opendir(filename);
-               if (!dir)
-                       continue;
-               count++;
-
-               if (count > nr_reg) {
-                       ret = 1;
-                       goto exit;
-               }
-
-               strcpy(reg_info[count-1].name, item->d_name);
-               while ((ritem = readdir(dir))) {
-                       if (strlen(ritem->d_name) < 3)
-                               continue;
-
-                       sprintf(filename + len, "/%s", ritem->d_name);
-                       file = fopen(filename, "r");
-                       if (!file)
-                               continue;
-                       memset(line, 0, 1024);
-                       fptr = fgets(line, 1024, file);
-                       fclose(file);
-                       if (!fptr)
-                               continue;
-
-                       read_info_from_dirent(reg_info, ritem,
-                                             fptr, count - 1);
-               }
-       exit:
-               closedir(dir);
-               if (ret)
-                       break;
-       }
-       closedir(regdir);
+       return read_regulator_cb(t, data);
+}
 
-       return ret;
+static int fill_regulator_tree(void)
+{
+       return tree_for_each(reg_tree, fill_regulator_cb, NULL);
+}
+
+int regulator_init(void)
+{
+       reg_tree = tree_load(SYSFS_REGULATOR, regulator_filter_cb);
+       if (!reg_tree)
+               return -1;
+
+       return fill_regulator_tree();
 }
diff --git a/regulator.h b/regulator.h
index 1633cfd..5f8c473 100644
--- a/regulator.h
+++ b/regulator.h
@@ -13,32 +13,7 @@
  *       - initial API and implementation
  
*******************************************************************************/
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <dirent.h>
-#include <getopt.h>
-
 #define VALUE_MAX 16
 
-struct regulator_info {
-       char name[NAME_MAX];
-       char state[VALUE_MAX];
-       char status[VALUE_MAX];
-       char type[VALUE_MAX];
-       char opmode[VALUE_MAX];
-       int microvolts;
-       int min_microvolts;
-       int max_microvolts;
-       int microamps;
-       int min_microamps;
-       int max_microamps;
-       int requested_microamps;
-       int num_users;
-};
-
-extern struct regulator_info *regulator_init(int *nr_regulators);
-extern int regulator_read_info(struct regulator_info *reg_info, int nr_reg);
-extern void regulator_print_info(struct regulator_info *reg_info,
-                                int nr_reg, int verbose);
+extern int regulator_init(void);
+extern int regulator_dump(void);
-- 
1.7.1


_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to