URI: 
       util.c - ploot - simple plotting tools
  HTML git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ploot
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
   DIR LICENSE
       ---
       util.c (3219B)
       ---
            1 #include "util.h"
            2 #include <assert.h>
            3 #include <ctype.h>
            4 #include <errno.h>
            5 #include <limits.h>
            6 #include <stdarg.h>
            7 #include <stdio.h>
            8 #include <stdlib.h>
            9 #include <string.h>
           10 
           11 char const *arg0;
           12 
           13 static void
           14 _log(char const *fmt, va_list va)
           15 {
           16         if (arg0 != NULL)
           17                 fprintf(stderr, "%s: ", arg0);
           18         vfprintf(stderr, fmt, va);
           19         fprintf(stderr, "\n");
           20         fflush(stderr);
           21 }
           22 
           23 void
           24 err(int e, char const *fmt, ...)
           25 {
           26         va_list va;
           27 
           28         va_start(va, fmt);
           29         _log( fmt, va);
           30         exit(e);
           31 }
           32 
           33 void
           34 warn(char const *fmt, ...)
           35 {
           36         va_list va;
           37 
           38         va_start(va, fmt);
           39         _log(fmt, va);
           40 }
           41 
           42 void
           43 debug(char const *fmt, ...)
           44 {
           45         static int verbose = -1;
           46         va_list va;
           47 
           48         if (verbose < 0)
           49                 verbose = (getenv("DEBUG") != NULL);
           50         if (!verbose)
           51                 return;
           52         va_start(va, fmt);
           53         _log(fmt, va);
           54 }
           55 
           56 size_t
           57 strlcpy(char *buf, const char *str, size_t sz)
           58 {
           59         size_t len, cpy;
           60 
           61         cpy = ((len = strlen(str)) > sz) ? (sz) : (len);
           62         memcpy(buf, str, cpy);
           63         buf[sz - 1] = '\0';
           64         return len;
           65 }
           66 
           67 void
           68 put3utf(long rune)
           69 {
           70         putchar((char)(0xe0 | (0x0f & (rune >> 12))));        /* 1110xxxx */
           71         putchar((char)(0x80 | (0x3f & (rune >> 6))));        /* 10xxxxxx */
           72         putchar((char)(0x80 | (0x3f & (rune))));        /* 10xxxxxx */
           73 }
           74 
           75 char *
           76 strsep(char **strp, const char *sep)
           77 {
           78         char *s, *prev;
           79 
           80         if (*strp == NULL)
           81                 return NULL;
           82         for (s = prev = *strp; strchr(sep, *s) == NULL; s++);
           83         if (*s == '\0') {
           84                 *strp = NULL;
           85                 return prev;
           86         }
           87         *s = '\0';
           88         *strp = s + 1;
           89 
           90         return prev;
           91 }
           92 
           93 void
           94 strchomp(char *s)
           95 {
           96         char *x = s + strlen(s);
           97 
           98         while (--x >= s && (*x == '\r' || *x == '\n'))
           99                 *x = '\0';
          100 }
          101 
          102 /*
          103  * Set 'str' to a human-readable form of 'num' with always a width of 8 (+1 for
          104  * the '\0' terminator).  Buffer overflow is ensured not to happen due to the
          105  * max size of a double.  Return the exponent.
          106  */
          107 int
          108 humanize(char *str, double val)
          109 {
          110         int exp, precision;
          111         char label[] = { '\0', 'M', 'G', 'T', 'E' };
          112 
          113         for (exp = 0; ABS(val) > 1000; exp++)
          114                 val /= 1000;
          115 
          116         precision = (ABS(val) < 10) ? 2 : (ABS(val) < 100) ? 1 : 0;
          117         precision += (exp == 0);
          118 
          119         snprintf(str, 9, "%+.*f %c", precision, val, label[exp]);
          120         str[8] = '\0';
          121         if (val >= 0)
          122                 str[0] = ' ';
          123 
          124         return exp * 3;
          125 }
          126 
          127 time_t
          128 scale_time_t(time_t min, time_t max, int dots)
          129 {
          130         time_t dt, scale[] = {
          131                 1, 5, 2, 10, 20, 30, 60, 60*2, 60*5, 60*10, 60*20, 60*30, 3600, 
          132                 3600*2, 3600*6, 3600*12, 3600*24, 3600*24*2, 
          133                 3600*24*7, 3600*24*14, 3600*24*20, 3600*24*21, 3600*24*28, 3600*24*50,
          134                 3600*24*100, 3600*24*365, 0
          135         };
          136 
          137         dt = max - min;
          138         for (time_t *sc = scale; *sc > 0; sc++)
          139                 if (dt < *sc * dots)
          140                         return *sc;
          141         return dt / dots;
          142 }
          143 
          144 /*
          145  * Make the value scale aligned with round values by changing the
          146  * minimal and maximal values.
          147  */
          148 double
          149 scale_double(double min, double max, int rows)
          150 {
          151         double dv, step, scale[] = { 1, 2, 2.5, 5, };
          152 
          153         dv = max - min;
          154         step = 1;
          155         if (dv > 1) {
          156                 for (double mant = 1;; mant *= 10) {
          157                         double *sc = scale;
          158                         for (; sc < scale + LEN(scale); sc++) {
          159                                 step = mant * *sc;
          160                                 if (dv < rows * step)
          161                                         return step;
          162                         }
          163                 }
          164         } else {
          165                 for (double mant = 1;; mant /= 10) {
          166                         double *sc = scale + LEN(scale) - 1;
          167                         for (; sc >= scale; sc--) {
          168                                 double tmp = mant * *sc;
          169                                 if (dv > rows * tmp)
          170                                         return step;
          171                                 step = tmp;
          172                         }
          173                 }
          174         }
          175         assert(!"not reached");
          176         return 0;
          177 }