summaryrefslogtreecommitdiff
path: root/src/hbar.c
blob: 58db864453c8fd834003c27474025958d96a9d4a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
 * hbar
 *
 * create a horizontal progres bar across the screen
 */

#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <getopt.h>

#include "colors.h"

#define DEFAULT_COLOR BLACK BG_WHITE 
#define DEFAULT_RESET WHITE BG_BLACK

#define SAVE_POS "\033[s"
#define LOAD_POS "\033[u"

int main (int argc, char **argv) {
    struct winsize w;
    ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
    int width = w.ws_col;

    char *text = "";
    char *unit = "";
    int total = 0;
    int completed = 0;
    int line = 0;
    bool terminate = false;

    char *color = DEFAULT_COLOR;
    char *reset = DEFAULT_RESET;
 
    int opt;
    int option_index = 0;

    const char *optstring = "T:u:c:r:l:t";
    static const struct option opts[] = {
        {"text", required_argument, 0, 'T'},
        {"unit", optional_argument, 0, 'u'},
        {"color", optional_argument, 0, 'c'},
        {"reset", optional_argument, 0, 'r'},
        {"line", optional_argument, 0, ';'},
        {"terminate", no_argument, 0, 't'}
    };

    while ((opt = getopt_long(argc, argv, optstring, opts, &option_index)) != -1) {
        switch (opt) {
            case 'T':
                text = optarg;
                break;
            case 'c':
                color = optarg;
                break;
            case 'r':
                reset = optarg;
                break;
            case 'u':
                unit = optarg;
                break;
            case 't':
                terminate = true;
                break;
            case 'l':
                line = atoi(optarg);
                break;
        }
    }


    if (argc < optind + 2) {
        printf(RESET "\n");
        return 1;
    }

    completed = atoi(argv[optind]);
    total = atoi(argv[optind+1]);

    if (line != -1) {
        printf("\033[%dA", line, 0);
    }

    char *count = malloc(width);
    sprintf(count, "[%d%s/%d%s]", completed, unit, total, unit);

    printf(RESET "\r");
    printf(color);
    for (int i = 0; i < width; i++) {
        int reset_at = 0;
        if (total > 0) {
            float percent = (float) completed / (float) total;
            reset_at = percent * width;
        }

        if (i == reset_at) {
            printf(reset);
        }

        if (text && i < strlen(text)) {
            printf("%c", text[i]);
        } else if (i + 1 > width - strlen(count)) {
            printf("%c", count[i - width + strlen(count)]);
        } else {
            printf(" ");
        }
    }

    if (line != -1) {
        printf("\033[%dB", line, 0);
    }
    if (terminate) {
        printf(RESET "\n");
    }


    return 0;
}