top: convert to generic object payload
authorPhil Sutter <phil@nwl.cc>
Tue, 6 Oct 2009 20:33:28 +0000 (22:33 +0200)
committerPhil Sutter <phil@nwl.cc>
Tue, 3 Nov 2009 22:23:22 +0000 (23:23 +0100)
src/conky.c
src/core.c
src/text_object.h
src/top.c
src/top.h

index 05fce9a..fdc0a06 100644 (file)
@@ -711,46 +711,6 @@ void parse_conky_vars(struct text_object *root, const char *txt, char *p, struct
        generate_text_internal(p, max_user_text, *root, cur);
 }
 
-char *format_time(unsigned long timeval, const int width)
-{
-       char buf[10];
-       unsigned long nt;       // narrow time, for speed on 32-bit
-       unsigned cc;            // centiseconds
-       unsigned nn;            // multi-purpose whatever
-
-       nt = timeval;
-       cc = nt % 100;          // centiseconds past second
-       nt /= 100;                      // total seconds
-       nn = nt % 60;           // seconds past the minute
-       nt /= 60;                       // total minutes
-       if (width >= snprintf(buf, sizeof buf, "%lu:%02u.%02u",
-                               nt, nn, cc)) {
-               return strndup(buf, text_buffer_size);
-       }
-       if (width >= snprintf(buf, sizeof buf, "%lu:%02u", nt, nn)) {
-               return strndup(buf, text_buffer_size);
-       }
-       nn = nt % 60;           // minutes past the hour
-       nt /= 60;                       // total hours
-       if (width >= snprintf(buf, sizeof buf, "%lu,%02u", nt, nn)) {
-               return strndup(buf, text_buffer_size);
-       }
-       nn = nt;                        // now also hours
-       if (width >= snprintf(buf, sizeof buf, "%uh", nn)) {
-               return strndup(buf, text_buffer_size);
-       }
-       nn /= 24;                       // now days
-       if (width >= snprintf(buf, sizeof buf, "%ud", nn)) {
-               return strndup(buf, text_buffer_size);
-       }
-       nn /= 7;                        // now weeks
-       if (width >= snprintf(buf, sizeof buf, "%uw", nn)) {
-               return strndup(buf, text_buffer_size);
-       }
-       // well shoot, this outta' fit...
-       return strndup("<inf>", text_buffer_size);
-}
-
 static inline void format_media_player_time(char *buf, const int size,
                int seconds)
 {
@@ -2106,70 +2066,14 @@ void generate_text_internal(char *p, int p_max_size,
                         * times, we have this special handler. */
                        break;
                        case OBJ_top:
-                               parse_top_args("top", obj->data.top.s, obj);
-                               if (!needed) needed = cur->cpu;
                        case OBJ_top_mem:
-                               parse_top_args("top_mem", obj->data.top.s, obj);
-                               if (!needed) needed = cur->memu;
                        case OBJ_top_time:
-                               parse_top_args("top_time", obj->data.top.s, obj);
-                               if (!needed) needed = cur->time;
 #ifdef IOSTATS
                        case OBJ_top_io:
-                               parse_top_args("top_io", obj->data.top.s, obj);
-                               if (!needed) needed = cur->io;
 #endif
-
-                               if (needed[obj->data.top.num]) {
-                                       char *timeval;
-
-                                       switch (obj->data.top.type) {
-                                               case TOP_NAME:
-                                                       snprintf(p, top_name_width + 1, "%-*s", top_name_width,
-                                                                       needed[obj->data.top.num]->name);
-                                                       break;
-                                               case TOP_CPU:
-                                                       snprintf(p, 7, "%6.2f",
-                                                                       needed[obj->data.top.num]->amount);
-                                                       break;
-                                               case TOP_PID:
-                                                       snprintf(p, 6, "%5i",
-                                                                       needed[obj->data.top.num]->pid);
-                                                       break;
-                                               case TOP_MEM:
-                                                       snprintf(p, 7, "%6.2f",
-                                                                       needed[obj->data.top.num]->totalmem);
-                                                       break;
-                                               case TOP_TIME:
-                                                       timeval = format_time(
-                                                                       needed[obj->data.top.num]->total_cpu_time, 9);
-                                                       snprintf(p, 10, "%9s", timeval);
-                                                       free(timeval);
-                                                       break;
-                                               case TOP_MEM_RES:
-                                                       human_readable(needed[obj->data.top.num]->rss,
-                                                                       p, 255);
-                                                       break;
-                                               case TOP_MEM_VSIZE:
-                                                       human_readable(needed[obj->data.top.num]->vsize,
-                                                                       p, 255);
-                                                       break;
-#ifdef IOSTATS
-                                               case TOP_READ_BYTES:
-                                                       human_readable(needed[obj->data.top.num]->read_bytes / update_interval,
-                                                                       p, 255);
-                                                       break;
-                                               case TOP_WRITE_BYTES:
-                                                       human_readable(needed[obj->data.top.num]->write_bytes / update_interval,
-                                                                       p, 255);
-                                                       break;
-                                               case TOP_IO_PERC:
-                                                       snprintf(p, 7, "%6.2f",
-                                                                       needed[obj->data.top.num]->io_perc);
-                                                       break;
-#endif
-                                       }
-                               }
+                               /* yes, passing top_name_width instead
+                                * of p_max_size is intended here */
+                               print_top(obj, p, top_name_width);
                        OBJ(tail) {
                                print_tailhead("tail", obj, p, p_max_size);
                        }
index 49f2576..bb9d313 100644 (file)
@@ -1599,11 +1599,7 @@ void free_text_objects(struct text_object *root, int internal)
 #ifdef IOSTATS
                        case OBJ_top_io:
 #endif
-                               if (info.first_process && !internal) {
-                                       free_all_processes();
-                                       info.first_process = NULL;
-                               }
-                               if (data.top.s) free(data.top.s);
+                               free_top(obj, internal);
                                break;
 #ifdef HDDTEMP
                        case OBJ_hddtemp:
index 8731cd6..db57584 100644 (file)
@@ -458,13 +458,6 @@ struct text_object {
                } ifblock;
 
                struct {
-                       int num;
-                       int type;
-                       int was_parsed;
-                       char *s;
-               } top;
-
-               struct {
                        double last_update;
                        float interval;
                        char *cmd;
index da9f92e..76236ea 100644 (file)
--- a/src/top.c
+++ b/src/top.c
@@ -800,18 +800,26 @@ void process_find_top(struct process **cpu, struct process **mem,
 #endif /* IOSTATS */
 }
 
+struct top_data {
+       int num;
+       int type;
+       int was_parsed;
+       char *s;
+};
+
 int parse_top_args(const char *s, const char *arg, struct text_object *obj)
 {
+       struct top_data *td;
        char buf[64];
        int n;
 
-       if (obj->data.top.was_parsed) {
-               return 1;
+       if (!arg) {
+               NORM_ERR("top needs arguments");
+               return 0;
        }
-       obj->data.top.was_parsed = 1;
 
-       if (arg && !obj->data.top.s) {
-               obj->data.top.s = strndup(arg, text_buffer_size);
+       if (obj->data.opaque) {
+               return 1;
        }
 
        if (s[3] == 0) {
@@ -837,33 +845,32 @@ int parse_top_args(const char *s, const char *arg, struct text_object *obj)
                return 0;
        }
 
-       if (!arg) {
-               NORM_ERR("top needs arguments");
-               return 0;
-       }
+       obj->data.opaque = td = malloc(sizeof(struct top_data));
+       memset(td, 0, sizeof(struct top_data));
+       td->s = strndup(arg, text_buffer_size);
 
        if (sscanf(arg, "%63s %i", buf, &n) == 2) {
                if (strcmp(buf, "name") == EQUAL) {
-                       obj->data.top.type = TOP_NAME;
+                       td->type = TOP_NAME;
                } else if (strcmp(buf, "cpu") == EQUAL) {
-                       obj->data.top.type = TOP_CPU;
+                       td->type = TOP_CPU;
                } else if (strcmp(buf, "pid") == EQUAL) {
-                       obj->data.top.type = TOP_PID;
+                       td->type = TOP_PID;
                } else if (strcmp(buf, "mem") == EQUAL) {
-                       obj->data.top.type = TOP_MEM;
+                       td->type = TOP_MEM;
                } else if (strcmp(buf, "time") == EQUAL) {
-                       obj->data.top.type = TOP_TIME;
+                       td->type = TOP_TIME;
                } else if (strcmp(buf, "mem_res") == EQUAL) {
-                       obj->data.top.type = TOP_MEM_RES;
+                       td->type = TOP_MEM_RES;
                } else if (strcmp(buf, "mem_vsize") == EQUAL) {
-                       obj->data.top.type = TOP_MEM_VSIZE;
+                       td->type = TOP_MEM_VSIZE;
 #ifdef IOSTATS
                } else if (strcmp(buf, "io_read") == EQUAL) {
-                       obj->data.top.type = TOP_READ_BYTES;
+                       td->type = TOP_READ_BYTES;
                } else if (strcmp(buf, "io_write") == EQUAL) {
-                       obj->data.top.type = TOP_WRITE_BYTES;
+                       td->type = TOP_WRITE_BYTES;
                } else if (strcmp(buf, "io_perc") == EQUAL) {
-                       obj->data.top.type = TOP_IO_PERC;
+                       td->type = TOP_IO_PERC;
 #endif /* IOSTATS */
                } else {
                        NORM_ERR("invalid type arg for top");
@@ -879,7 +886,7 @@ int parse_top_args(const char *s, const char *arg, struct text_object *obj)
                        NORM_ERR("invalid num arg for top. Must be between 1 and 10.");
                        return 0;
                } else {
-                       obj->data.top.num = n - 1;
+                       td->num = n - 1;
                }
        } else {
                NORM_ERR("invalid argument count for top");
@@ -888,4 +895,137 @@ int parse_top_args(const char *s, const char *arg, struct text_object *obj)
        return 1;
 }
 
+static char *format_time(unsigned long timeval, const int width)
+{
+       char buf[10];
+       unsigned long nt;       // narrow time, for speed on 32-bit
+       unsigned cc;            // centiseconds
+       unsigned nn;            // multi-purpose whatever
+
+       nt = timeval;
+       cc = nt % 100;          // centiseconds past second
+       nt /= 100;                      // total seconds
+       nn = nt % 60;           // seconds past the minute
+       nt /= 60;                       // total minutes
+       if (width >= snprintf(buf, sizeof buf, "%lu:%02u.%02u",
+                               nt, nn, cc)) {
+               return strndup(buf, text_buffer_size);
+       }
+       if (width >= snprintf(buf, sizeof buf, "%lu:%02u", nt, nn)) {
+               return strndup(buf, text_buffer_size);
+       }
+       nn = nt % 60;           // minutes past the hour
+       nt /= 60;                       // total hours
+       if (width >= snprintf(buf, sizeof buf, "%lu,%02u", nt, nn)) {
+               return strndup(buf, text_buffer_size);
+       }
+       nn = nt;                        // now also hours
+       if (width >= snprintf(buf, sizeof buf, "%uh", nn)) {
+               return strndup(buf, text_buffer_size);
+       }
+       nn /= 24;                       // now days
+       if (width >= snprintf(buf, sizeof buf, "%ud", nn)) {
+               return strndup(buf, text_buffer_size);
+       }
+       nn /= 7;                        // now weeks
+       if (width >= snprintf(buf, sizeof buf, "%uw", nn)) {
+               return strndup(buf, text_buffer_size);
+       }
+       // well shoot, this outta' fit...
+       return strndup("<inf>", text_buffer_size);
+}
+
+void print_top(struct text_object *obj, char *p, int top_name_width)
+{
+       struct information *cur = &info;
+       struct top_data *td = obj->data.opaque;
+       struct process **needed = 0;
+
+       if (!td)
+               return;
+
+       switch (obj->type) {
+               case OBJ_top:
+                       needed = cur->cpu;
+                       break;
+               case OBJ_top_mem:
+                       needed = cur->memu;
+                       break;
+               case OBJ_top_time:
+                       needed = cur->time;
+                       break;
+               case OBJ_top_io:
+                       needed = cur->io;
+                       break;
+               default:
+                       return;
+       }
 
+       if (needed[td->num]) {
+               char *timeval;
+
+               switch (td->type) {
+                       case TOP_NAME:
+                               snprintf(p, top_name_width + 1, "%-*s", top_name_width,
+                                               needed[td->num]->name);
+                               break;
+                       case TOP_CPU:
+                               snprintf(p, 7, "%6.2f",
+                                               needed[td->num]->amount);
+                               break;
+                       case TOP_PID:
+                               snprintf(p, 6, "%5i",
+                                               needed[td->num]->pid);
+                               break;
+                       case TOP_MEM:
+                               snprintf(p, 7, "%6.2f",
+                                               needed[td->num]->totalmem);
+                               break;
+                       case TOP_TIME:
+                               timeval = format_time(
+                                               needed[td->num]->total_cpu_time, 9);
+                               snprintf(p, 10, "%9s", timeval);
+                               free(timeval);
+                               break;
+                       case TOP_MEM_RES:
+                               human_readable(needed[td->num]->rss,
+                                               p, 255);
+                               break;
+                       case TOP_MEM_VSIZE:
+                               human_readable(needed[td->num]->vsize,
+                                               p, 255);
+                               break;
+#ifdef IOSTATS
+                       case TOP_READ_BYTES:
+                               human_readable(needed[td->num]->read_bytes / update_interval,
+                                               p, 255);
+                               break;
+                       case TOP_WRITE_BYTES:
+                               human_readable(needed[td->num]->write_bytes / update_interval,
+                                               p, 255);
+                               break;
+                       case TOP_IO_PERC:
+                               snprintf(p, 7, "%6.2f",
+                                               needed[td->num]->io_perc);
+                               break;
+#endif
+               }
+       }
+}
+
+void free_top(struct text_object *obj, int internal)
+{
+       struct top_data *td = obj->data.opaque;
+
+       if (info.first_process && !internal) {
+               free_all_processes();
+               info.first_process = NULL;
+       }
+
+       if (!td)
+               return;
+       if (td->s)
+               free(td->s);
+       free(obj->data.opaque);
+       obj->data.opaque = NULL;
+}
index f15d782..e5773d1 100644 (file)
--- a/src/top.h
+++ b/src/top.h
@@ -143,5 +143,7 @@ void process_find_top(struct process **, struct process **, struct process **
 struct process *get_process_by_name(const char *);
 
 int parse_top_args(const char *s, const char *arg, struct text_object *obj);
+void print_top(struct text_object *, char *, int);
+void free_top(struct text_object *, int);
 
 #endif /* _top_h_ */