URI: 
       util.c - slstatus - status monitor
  HTML git clone git://git.suckless.org/slstatus
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       util.c (2539B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include <errno.h>
            3 #include <stdarg.h>
            4 #include <stdint.h>
            5 #include <stdio.h>
            6 #include <stdlib.h>
            7 #include <string.h>
            8 
            9 #include "util.h"
           10 
           11 char *argv0;
           12 
           13 static void
           14 verr(const char *fmt, va_list ap)
           15 {
           16         vfprintf(stderr, fmt, ap);
           17 
           18         if (fmt[0] && fmt[strlen(fmt) - 1] == ':') {
           19                 fputc(' ', stderr);
           20                 perror(NULL);
           21         } else {
           22                 fputc('\n', stderr);
           23         }
           24 }
           25 
           26 void
           27 warn(const char *fmt, ...)
           28 {
           29         va_list ap;
           30 
           31         va_start(ap, fmt);
           32         verr(fmt, ap);
           33         va_end(ap);
           34 }
           35 
           36 void
           37 die(const char *fmt, ...)
           38 {
           39         va_list ap;
           40 
           41         va_start(ap, fmt);
           42         verr(fmt, ap);
           43         va_end(ap);
           44 
           45         exit(1);
           46 }
           47 
           48 static int
           49 evsnprintf(char *str, size_t size, const char *fmt, va_list ap)
           50 {
           51         int ret;
           52 
           53         ret = vsnprintf(str, size, fmt, ap);
           54 
           55         if (ret < 0) {
           56                 warn("vsnprintf:");
           57                 return -1;
           58         } else if ((size_t)ret >= size) {
           59                 warn("vsnprintf: Output truncated");
           60                 return -1;
           61         }
           62 
           63         return ret;
           64 }
           65 
           66 int
           67 esnprintf(char *str, size_t size, const char *fmt, ...)
           68 {
           69         va_list ap;
           70         int ret;
           71 
           72         va_start(ap, fmt);
           73         ret = evsnprintf(str, size, fmt, ap);
           74         va_end(ap);
           75 
           76         return ret;
           77 }
           78 
           79 const char *
           80 bprintf(const char *fmt, ...)
           81 {
           82         va_list ap;
           83         int ret;
           84 
           85         va_start(ap, fmt);
           86         ret = evsnprintf(buf, sizeof(buf), fmt, ap);
           87         va_end(ap);
           88 
           89         return (ret < 0) ? NULL : buf;
           90 }
           91 
           92 const char *
           93 fmt_human(uintmax_t num, int base)
           94 {
           95         double scaled;
           96         size_t i, prefixlen;
           97         const char **prefix;
           98         const char *prefix_1000[] = { "", "k", "M", "G", "T", "P", "E", "Z",
           99                                       "Y" };
          100         const char *prefix_1024[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei",
          101                                       "Zi", "Yi" };
          102 
          103         switch (base) {
          104         case 1000:
          105                 prefix = prefix_1000;
          106                 prefixlen = LEN(prefix_1000);
          107                 break;
          108         case 1024:
          109                 prefix = prefix_1024;
          110                 prefixlen = LEN(prefix_1024);
          111                 break;
          112         default:
          113                 warn("fmt_human: Invalid base");
          114                 return NULL;
          115         }
          116 
          117         scaled = num;
          118         for (i = 0; i < prefixlen && scaled >= base; i++)
          119                 scaled /= base;
          120 
          121         return bprintf("%.1f %s", scaled, prefix[i]);
          122 }
          123 
          124 int
          125 pscanf(const char *path, const char *fmt, ...)
          126 {
          127         FILE *fp;
          128         va_list ap;
          129         int n;
          130 
          131         if (!(fp = fopen(path, "r"))) {
          132                 warn("fopen '%s':", path);
          133                 return -1;
          134         }
          135         va_start(ap, fmt);
          136         n = vfscanf(fp, fmt, ap);
          137         va_end(ap);
          138         fclose(fp);
          139 
          140         return (n == EOF) ? -1 : n;
          141 }
          142 
          143 int
          144 lscanf(FILE *fp, const char *key, const char *fmt, void *res)
          145 {
          146                 int n;
          147                 char line[256];
          148 
          149                 n = -1;
          150                 while (fgets(line, sizeof(line), fp))
          151                         if (strncmp(line, key, strlen(key)) == 0) {
          152                                 n = sscanf(line + strlen(key), fmt, res);
          153                                 break;
          154                         }
          155 
          156                 rewind(fp);
          157                 return (n == 1) ? 1 : -1;
          158 }