Diff for /embedaddon/bmon/src/utils.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 22:19:56 version 1.1.1.2, 2014/07/30 07:55:27
Line 1 Line 1
 /*  /*
  * utils.c             General purpose utilities   * utils.c             General purpose utilities
  *   *
 * Copyright (c) 2001-2005 Thomas Graf <tgraf@suug.ch> * Copyright (c) 2001-2013 Thomas Graf <tgraf@suug.ch>
  * Copyright (c) 2013 Red Hat, Inc.
  *   *
  * Permission is hereby granted, free of charge, to any person obtaining a   * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),   * copy of this software and associated documentation files (the "Software"),
Line 26 Line 27
 #include <bmon/conf.h>  #include <bmon/conf.h>
 #include <bmon/utils.h>  #include <bmon/utils.h>
   
void * xcalloc(size_t n, size_t s)void *xcalloc(size_t n, size_t s)
 {  {
         void *d = calloc(n, s);          void *d = calloc(n, s);
   
Line 38  void * xcalloc(size_t n, size_t s) Line 39  void * xcalloc(size_t n, size_t s)
         return d;          return d;
 }  }
   
void * xrealloc(void *p, size_t s)void *xrealloc(void *p, size_t s)
 {  {
         void *d = realloc(p, s);          void *d = realloc(p, s);
   
Line 56  void xfree(void *d) Line 57  void xfree(void *d)
                 free(d);                  free(d);
 }  }
   
inline float ts_to_float(timestamp_t *src)float timestamp_to_float(timestamp_t *src)
 {  {
         return (float) src->tv_sec + ((float) src->tv_usec / 1000000.0f);          return (float) src->tv_sec + ((float) src->tv_usec / 1000000.0f);
 }  }
   
inline void float_to_ts(timestamp_t *dst, float src)int64_t timestamp_to_int(timestamp_t *src)
 {  {
           return (src->tv_sec * 1000000ULL) + src->tv_usec;
   }
   
   void float_to_timestamp(timestamp_t *dst, float src)
   {
         dst->tv_sec = (time_t) src;          dst->tv_sec = (time_t) src;
         dst->tv_usec = (src - ((float) ((time_t) src))) * 1000000.0f;          dst->tv_usec = (src - ((float) ((time_t) src))) * 1000000.0f;
 }  }
   
inline void ts_add(timestamp_t *dst, timestamp_t *src1, timestamp_t *src2)void timestamp_add(timestamp_t *dst, timestamp_t *src1, timestamp_t *src2)
 {  {
         dst->tv_sec = src1->tv_sec + src2->tv_sec;          dst->tv_sec = src1->tv_sec + src2->tv_sec;
         dst->tv_usec = src1->tv_usec + src2->tv_usec;          dst->tv_usec = src1->tv_usec + src2->tv_usec;
Line 78  inline void ts_add(timestamp_t *dst, timestamp_t *src1 Line 84  inline void ts_add(timestamp_t *dst, timestamp_t *src1
         }          }
 }  }
   
inline void ts_sub(timestamp_t *dst, timestamp_t *src1, timestamp_t *src2)void timestamp_sub(timestamp_t *dst, timestamp_t *src1, timestamp_t *src2)
 {  {
         dst->tv_sec = src1->tv_sec - src2->tv_sec;          dst->tv_sec = src1->tv_sec - src2->tv_sec;
         dst->tv_usec = src1->tv_usec - src2->tv_usec;          dst->tv_usec = src1->tv_usec - src2->tv_usec;
        if (dst->tv_usec <= -1000000) {        if (dst->tv_usec < 0) {
                 dst->tv_sec--;                  dst->tv_sec--;
                 dst->tv_usec += 1000000;                  dst->tv_usec += 1000000;
         }          }
 }  }
   
inline int ts_le(timestamp_t *a, timestamp_t *b)int timestamp_le(timestamp_t *a, timestamp_t *b)
 {  {
         if (a->tv_sec > b->tv_sec)          if (a->tv_sec > b->tv_sec)
                 return 0;                  return 0;
Line 99  inline int ts_le(timestamp_t *a, timestamp_t *b) Line 105  inline int ts_le(timestamp_t *a, timestamp_t *b)
         return 0;          return 0;
 }  }
   
inline void update_ts(timestamp_t *dst)int timestamp_is_negative(timestamp_t *ts)
 {  {
           return (ts->tv_sec < 0 || ts->tv_usec < 0);
   }
   
   void update_timestamp(timestamp_t *dst)
   {
         struct timeval tv;          struct timeval tv;
   
         gettimeofday(&tv, NULL);          gettimeofday(&tv, NULL);
Line 108  inline void update_ts(timestamp_t *dst) Line 119  inline void update_ts(timestamp_t *dst)
         dst->tv_sec = tv.tv_sec;          dst->tv_sec = tv.tv_sec;
         dst->tv_usec = tv.tv_usec;          dst->tv_usec = tv.tv_usec;
 }  }
           
   
float time_diff(timestamp_t *t1, timestamp_t *t2)void copy_timestamp(timestamp_t *ts1, timestamp_t *ts2)
 {  {
        timestamp_t ts;        ts1->tv_sec = ts2->tv_sec;
        ts_sub(&ts, t2, t1);        ts2->tv_usec = ts2->tv_usec;
        return ts_to_float(&ts); 
 }  }
   
float diff_now(timestamp_t *t1)float timestamp_diff(timestamp_t *t1, timestamp_t *t2)
 {  {
        timestamp_t now;        float diff;
        update_ts(&now); 
        return time_diff(t1, &now); 
} 
   
static inline b_cnt_t __divisor(int type, int exp)        diff = t2->tv_sec - t1->tv_sec;
{        diff += (((float) t2->tv_usec - (float) t1->tv_usec) / 1000000.0f);
        static b_cnt_t cache[2][32]; 
   
        if (exp) {        return diff;
                if (!cache[get_use_si()][exp]) { 
                        cache[get_use_si()][exp] = 
                                (b_cnt_t) pow(get_use_si() || 
                                               type == U_NUMBER ? 1000.0f : 1024.0f, exp); 
                } 
                return cache[get_use_si()][exp]; 
        } else 
                return 1; 
 }  }
   
static inline char * __unit(int type, int exp)#if 0
{ 
        static char *u[2][3][32] = { 
                [0] = { /* IEC */ 
                        [U_BITS]   = { " b ", "Kib", "Mib", "Gib", "Tib" }, 
                        [U_BYTES]  = { " B ", "KiB", "MiB", "GiB", "TiB" }, 
                        [U_NUMBER] = { " ", "K", "M", "G", "T" }, 
                }, 
                [1] = { /* SI */ 
                        [U_BITS]   = { "  b", "Kb ", "Mb ", "Gb ", "Tb " }, 
                        [U_BYTES]  = { " B ", "KB ", "MB ", "GB ", "TB " }, 
                        [U_NUMBER] = { " ", "K", "M", "G", "T" }, 
                } 
        }; 
   
         return u[get_use_si()][type][exp];  
           
 }  
   
b_cnt_t get_divisor(b_cnt_t hint, int unit, char **dst_unit, int *prec)float diff_now(timestamp_t *t1)
 {  {
        int yunit = get_y_unit();        timestamp_t now;
        update_ts(&now);
        if (prec)        return time_diff(t1, &now);
                *prec = 2; 
 
        if (yunit == Y_DYNAMIC) { 
                if (hint >= __divisor(unit, 3)) { 
                        *dst_unit = __unit(unit, 3); 
                        return __divisor(unit, 3); 
                } else if (hint >= __divisor(unit, 2)) { 
                        *dst_unit = __unit(unit, 2); 
                        return __divisor(unit, 2); 
                } else if (hint >= __divisor(unit, 1)) { 
                        *dst_unit = __unit(unit, 1); 
                        return __divisor(unit, 1); 
                } else { 
                        *dst_unit = __unit(unit, 0); 
                        if (prec) 
                                *prec = 0; 
                        return 1; 
                } 
        } else { 
                *dst_unit = __unit(unit, yunit); 
                return __divisor(unit, yunit); 
        } 
 
        return 1; 
 }  }
   
double cancel_down(b_cnt_t l, int unit, char **dst_unit, int *prec)const char *xinet_ntop(struct sockaddr *src, char *dst, socklen_t cnt)
 {  {
         return ((double) l / (double) get_divisor(l, unit, dst_unit, prec));  
 }  
   
 const char * xinet_ntop(struct sockaddr *src, char *dst, socklen_t cnt)  
 {  
         void *s;          void *s;
         int family;          int family;
   
Line 211  const char * xinet_ntop(struct sockaddr *src, char *ds Line 163  const char * xinet_ntop(struct sockaddr *src, char *ds
         return inet_ntop(family, s, dst, cnt);          return inet_ntop(family, s, dst, cnt);
 }  }
   
b_cnt_t parse_size(const char *str)uint64_t parse_size(const char *str)
 {  {
         char *p;          char *p;
        b_cnt_t l = strtol(str, &p, 0);        uint64_t l = strtol(str, &p, 0);
         if (p == str)          if (p == str)
                 return -1;                  return -1;
   
Line 244  char *strdup(const char *s) Line 196  char *strdup(const char *s)
         char *t = xcalloc(1, strlen(s) + 1);          char *t = xcalloc(1, strlen(s) + 1);
         memcpy(t, s, strlen(s));          memcpy(t, s, strlen(s));
         return s;          return s;
   }
   #endif
   
   char *timestamp2str(timestamp_t *ts, char *buf, size_t len)
   {
           int i, split[5];
           char *units[] = {"d", "h", "m", "s", "usec"};
           time_t sec = ts->tv_sec;
   
   #define _SPLIT(idx, unit) if ((split[idx] = sec / unit) > 0) sec %= unit
           _SPLIT(0, 86400);       /* days */
           _SPLIT(1, 3600);        /* hours */
           _SPLIT(2, 60);          /* minutes */
           _SPLIT(3, 1);           /* seconds */
   #undef  _SPLIT
           split[4] = ts->tv_usec;
   
           memset(buf, 0, len);
   
           for (i = 0; i < ARRAY_SIZE(split); i++) {
                   if (split[i] > 0) {
                           char t[64];
                           snprintf(t, sizeof(t), "%s%d%s",
                                    strlen(buf) ? " " : "", split[i], units[i]);
                           strncat(buf, t, len - strlen(buf) - 1);
                   }
           }
   
           return buf;
   }
   
   int parse_date(const char *str, xdate_t *dst)
   {
           time_t now = time(NULL);
           struct tm *now_tm = localtime(&now);
           const char *next;
           char *p;
           struct tm backup;
   
           memset(dst, 0, sizeof(*dst));
   
           if (strchr(str, '-')) {
                   next = strptime(str, "%Y-%m-%d", &dst->d_tm);
                   if (next == NULL ||
                       (*next != '\0' && *next != ' '))
                           goto invalid_date;
           } else {
                   dst->d_tm.tm_mday  = now_tm->tm_mday;
                   dst->d_tm.tm_mon   = now_tm->tm_mon;
                   dst->d_tm.tm_year  = now_tm->tm_year;
                   dst->d_tm.tm_wday  = now_tm->tm_wday;
                   dst->d_tm.tm_yday  = now_tm->tm_yday;
                   dst->d_tm.tm_isdst = now_tm->tm_isdst;
                   next = str;
           }
   
           if (*next == '\0')
                   return 0;
   
           while (*next == ' ')
                   next++;
   
           if (*next == '.')
                   goto read_us;
   
           /* Make a backup, we can't rely on strptime to not screw
            * up what we've got so far. */
           memset(&backup, 0, sizeof(backup));
           memcpy(&backup, &dst->d_tm, sizeof(backup));
   
           next = strptime(next, "%H:%M:%S", &dst->d_tm);
           if (next == NULL ||
               (*next != '\0' && *next != '.'))
                   goto invalid_date;
   
           dst->d_tm.tm_mday  = backup.tm_mday;
           dst->d_tm.tm_mon   = backup.tm_mon;
           dst->d_tm.tm_year  = backup.tm_year;
           dst->d_tm.tm_wday  = backup.tm_wday;
           dst->d_tm.tm_yday  = backup.tm_yday;
           dst->d_tm.tm_isdst = backup.tm_isdst;
   
           if (*next == '\0')
                   return 0;
   read_us:
           if (*next == '.')
                   next++;
           else
                   BUG();
   
           dst->d_usec = strtoul(next, &p, 10);
   
           if (*p != '\0')
                   goto invalid_date;
           
           return 0;
   
   invalid_date:
           fprintf(stderr, "Invalid date \"%s\"\n", str);
           return -1;
   }
   
   static inline void print_token(FILE *fd, struct db_token *tok)
   {
           fprintf(fd, "%s", tok->t_name);
   
           if (tok->t_flags & DB_T_ATTR)
                   fprintf(fd, "<attr>");
   }
   
   void db_print_filter(FILE *fd, struct db_filter *filter)
   {
           if (filter->f_node)
                   print_token(fd, filter->f_node);
   
           if (filter->f_group) {
                   fprintf(fd, ".");
                   print_token(fd, filter->f_group);
           }
   
           if (filter->f_item) {
                   fprintf(fd, ".");
                   print_token(fd, filter->f_item);
           }
   
           if (filter->f_attr) {
                   fprintf(fd, ".");
                   print_token(fd, filter->f_attr);
           }
   
           if (filter->f_field)
                   fprintf(fd, "@%s", filter->f_field);
   }
   
   void *db_filter__scan_string(const char *);
   void db_filter__switch_to_buffer(void *);
   int db_filter_parse(void);
   
   struct db_filter * parse_db_filter(const char *buf)
   {
           struct db_filter *f;
           struct db_token *tok, *t;
   
           void *state = db_filter__scan_string(buf);
           db_filter__switch_to_buffer(state);
   
           if (db_filter_parse()) {
                   fprintf(stderr, "Failed to parse filter \"%s\"\n", buf);
                   return NULL;
           }
   
           tok = db_filter_out; /* generated by yacc */
           if (tok == NULL)
                   return NULL;
           
           f = xcalloc(1, sizeof(*f));
   
           f->f_node = tok;
   
           if (!tok->t_next)
                   goto out;
           tok = tok->t_next;
   
           if (tok->t_flags & DB_T_ATTR) {
                   fprintf(stderr, "Node may not contain an attribute field\n");
                   goto errout;
           }
   
           f->f_group = tok;
           if (!tok->t_next)
                   goto out;
           tok = tok->t_next;
   
           if (tok->t_flags & DB_T_ATTR) {
                   fprintf(stderr, "Group may not contain an attribute field\n");
                   goto errout;
           }
   
           f->f_item = tok;
   
           if (!tok->t_next)
                   goto out;
           tok = tok->t_next;
   
           if (tok->t_flags & DB_T_ATTR) {
                   if (!tok->t_name)
                           BUG();
                   f->f_field = tok->t_name;
                   goto out;
           } else
                   f->f_attr = tok;
   
           if (!tok->t_next)
                   goto out;
           tok = tok->t_next;
   
           if (tok->t_flags & DB_T_ATTR) {
                   if (!tok->t_name)
                           BUG();
                   f->f_field = tok->t_name;
           } else {
                   fprintf(stderr, "Unexpected additional token after attribute\n");
                   goto errout;
           }
   
   out:
           /* free unused tokens */
           for (tok = tok->t_next ; tok; tok = t) {
                   t = tok->t_next;
                   if (tok->t_name)
                           free(tok->t_name);
                   free(tok);
           }
   
           return f;
   
   errout:
           free(f);
           f = NULL;
           tok = db_filter_out;
           goto out;
 }  }
 #endif  #endif

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>