1 /*
2     gauge.c -- libreiserfs gauge functions
3     Copyright (C) 2001, 2002 Yury Umanets <torque@ukrpost.net>, see COPYING for
4     licensing and copyright details.
5 */
6 
7 #ifdef HAVE_CONFIG_H
8 #  include <config.h>
9 #endif
10 
11 #include <string.h>
12 #include <stdio.h>
13 #include <unistd.h>
14 
15 #include <reiserfs/reiserfs.h>
16 #include <reiserfs/debug.h>
17 
18 #define N_(String) (String)
19 #if ENABLE_NLS
20 #  include <libintl.h>
21 #  define _(String) dgettext (PACKAGE, String)
22 #else
23 #  define _(String) (String)
24 #endif
25 
26 #define GAUGE_BITS_SIZE 4
27 
default_gauge_blit(void)28 static inline void default_gauge_blit(void) {
29     static short bitc = 0;
30     static const char bits[] = "|/-\\";
31 
32     putc(bits[bitc], stderr);
33     putc('\b', stderr);
34     fflush(stderr);
35     bitc++;
36     bitc %= GAUGE_BITS_SIZE;
37 }
38 
default_gauge_header(const char * desc,reiserfs_gauge_type_t type)39 static inline void default_gauge_header(const char *desc,
40     reiserfs_gauge_type_t type)
41 {
42     if (desc) {
43 	if (type != REISERFS_GAUGE_SILENT)
44 	    fprintf(stderr, "\r%s: ", desc);
45 	else
46 	    fprintf(stderr, "\r%s...", desc);
47     }
48 }
49 
default_gauge_footer(const char * desc,reiserfs_gauge_type_t type)50 static inline void default_gauge_footer(const char *desc,
51     reiserfs_gauge_type_t type)
52 {
53     if (desc)
54 	fputs(desc, stderr);
55 }
56 
default_gauge_handler(const char * name,unsigned int value,void * data,reiserfs_gauge_type_t type,reiserfs_gauge_state_t state)57 static void default_gauge_handler(const char *name, unsigned int value,
58     void *data, reiserfs_gauge_type_t type, reiserfs_gauge_state_t state)
59 {
60     if (state == REISERFS_GAUGE_STARTED)
61 	default_gauge_header(name, type);
62 
63     switch (type) {
64 	case REISERFS_GAUGE_PERCENTAGE: {
65 	    unsigned int i;
66 	    char display[10] = {0};
67 
68 	    sprintf(display, "%d%%", value);
69 	    fputs(display, stderr);
70 
71 	    for (i = 0; i < strlen(display); i++)
72 		fputc('\b', stderr);
73 	    break;
74 	}
75 	case REISERFS_GAUGE_INDICATOR: {
76 	    default_gauge_blit();
77 	    break;
78 	}
79     }
80 
81     if (state == REISERFS_GAUGE_DONE)
82 	default_gauge_footer(_("done\n"), type);
83 
84     if (state == REISERFS_GAUGE_FAILED)
85 	default_gauge_footer(_("failed\n"), type);
86 
87     fflush(stderr);
88 }
89 
libreiserfs_gauge_create(reiserfs_gauge_type_t type,const char * name,void * data)90 reiserfs_gauge_t *libreiserfs_gauge_create(reiserfs_gauge_type_t type,
91     const char *name, void *data)
92 {
93     reiserfs_gauge_t *gauge;
94 
95     if (!(gauge = libreiserfs_calloc(sizeof(*gauge), 0)))
96 	return NULL;
97 
98     if (name) {
99 	int name_len = (strlen(name) < sizeof(gauge->name) ? strlen(name) :
100 	    sizeof(gauge->name) - 1);
101 	memcpy(gauge->name, name, name_len);
102     }
103 
104     gauge->handler = default_gauge_handler;
105     gauge->data = data;
106     gauge->type = type;
107 
108     libreiserfs_gauge_reset(gauge);
109 
110     if (name)
111 	libreiserfs_gauge_touch(gauge);
112 
113     return gauge;
114 }
115 
libreiserfs_gauge_free(reiserfs_gauge_t * gauge)116 void libreiserfs_gauge_free(reiserfs_gauge_t *gauge) {
117     ASSERT(gauge != NULL, return);
118     libreiserfs_free(gauge);
119 }
120 
libreiserfs_gauge_reset(reiserfs_gauge_t * gauge)121 void libreiserfs_gauge_reset(reiserfs_gauge_t *gauge) {
122     ASSERT(gauge != NULL, return);
123 
124     gauge->value = 0;
125     gauge->state = REISERFS_GAUGE_STARTED;
126 }
127 
libreiserfs_gauge_set_handler(reiserfs_gauge_t * gauge,reiserfs_gauge_handler_t handler)128 void libreiserfs_gauge_set_handler(reiserfs_gauge_t *gauge,
129     reiserfs_gauge_handler_t handler)
130 {
131     ASSERT(gauge != NULL, return);
132     gauge->handler = handler;
133 }
134 
libreiserfs_gauge_get_handler(reiserfs_gauge_t * gauge)135 reiserfs_gauge_handler_t libreiserfs_gauge_get_handler(reiserfs_gauge_t *gauge) {
136     ASSERT(gauge != NULL, return NULL);
137     return gauge->handler;
138 }
139 
libreiserfs_gauge_set_type(reiserfs_gauge_t * gauge,reiserfs_gauge_type_t type)140 void libreiserfs_gauge_set_type(reiserfs_gauge_t *gauge, reiserfs_gauge_type_t type) {
141     ASSERT(gauge != NULL, return);
142 
143     if (gauge->type == type)
144 	return;
145 
146     gauge->type = type;
147 
148     if (type == REISERFS_GAUGE_INDICATOR)
149 	setlinebuf(stderr);
150 }
151 
libreiserfs_gauge_get_type(reiserfs_gauge_t * gauge)152 reiserfs_gauge_type_t libreiserfs_gauge_get_type(reiserfs_gauge_t *gauge) {
153     ASSERT(gauge != NULL, return 0);
154     return gauge->type;
155 }
156 
libreiserfs_gauge_set_data(reiserfs_gauge_t * gauge,void * data)157 void libreiserfs_gauge_set_data(reiserfs_gauge_t *gauge, void *data) {
158     ASSERT(gauge != NULL, return);
159     gauge->data = data;
160 }
161 
libreiserfs_gauge_get_data(reiserfs_gauge_t * gauge)162 void *libreiserfs_gauge_get_data(reiserfs_gauge_t *gauge) {
163     ASSERT(gauge != NULL, return NULL);
164     return gauge->data;
165 }
166 
libreiserfs_gauge_set_name(reiserfs_gauge_t * gauge,const char * name)167 void libreiserfs_gauge_set_name(reiserfs_gauge_t *gauge, const char *name) {
168     int name_len;
169 
170     ASSERT(gauge != NULL, return);
171     ASSERT(name != NULL, return);
172 
173     if (!strncmp(gauge->name, name, sizeof(gauge->name)))
174 	return;
175 
176     /*name_len = (strlen(name) < sizeof(gauge->name) ?
177 	strlen(name) : sizeof(gauge->name) - 1);
178 
179     memcpy(gauge->name, name, name_len);
180     gauge->name[strlen(name)] = '\0';
181 */
182 	strncpy(gauge->name, name, (sizeof(gauge->name)-1));
183 
184     gauge->state = REISERFS_GAUGE_STARTED;
185     libreiserfs_gauge_touch(gauge);
186 }
187 
libreiserfs_gauge_get_name(reiserfs_gauge_t * gauge)188 char *libreiserfs_gauge_get_name(reiserfs_gauge_t *gauge) {
189     ASSERT(gauge != NULL, return NULL);
190     return gauge->name;
191 }
192 
libreiserfs_gauge_set_value(reiserfs_gauge_t * gauge,unsigned int value)193 void libreiserfs_gauge_set_value(reiserfs_gauge_t *gauge, unsigned int value) {
194     ASSERT(gauge != NULL, return);
195 
196     if (gauge->value == value)
197 	return;
198 
199     gauge->value = value;
200     libreiserfs_gauge_touch(gauge);
201     gauge->state = REISERFS_GAUGE_RUNNING;
202 }
203 
libreiserfs_gauge_get_value(reiserfs_gauge_t * gauge)204 unsigned int libreiserfs_gauge_get_value(reiserfs_gauge_t *gauge) {
205     ASSERT(gauge != NULL, return 0);
206     return gauge->value;
207 }
208 
libreiserfs_gauge_set_state(reiserfs_gauge_t * gauge,reiserfs_gauge_state_t state)209 void libreiserfs_gauge_set_state(reiserfs_gauge_t *gauge, reiserfs_gauge_state_t state) {
210     ASSERT(gauge != NULL, return);
211     gauge->state = state;
212 }
213 
libreiserfs_gauge_get_state(reiserfs_gauge_t * gauge)214 reiserfs_gauge_state_t libreiserfs_gauge_get_state(reiserfs_gauge_t *gauge) {
215     ASSERT(gauge != NULL, return 0);
216     return gauge->state;
217 }
218 
libreiserfs_gauge_touch(reiserfs_gauge_t * gauge)219 void libreiserfs_gauge_touch(reiserfs_gauge_t *gauge) {
220     ASSERT(gauge != NULL, return);
221 
222     if (gauge->handler && gauge->state != REISERFS_GAUGE_STOPED) {
223 
224 	gauge->handler(gauge->name, gauge->value, gauge->data,
225 	    gauge->type, gauge->state);
226     }
227 }
228 
libreiserfs_gauge_finish(reiserfs_gauge_t * gauge,int success)229 void libreiserfs_gauge_finish(reiserfs_gauge_t *gauge, int success) {
230     ASSERT(gauge != NULL, return);
231 
232     if (gauge->state == REISERFS_GAUGE_DONE ||
233 	    gauge->state == REISERFS_GAUGE_FAILED)
234 	return;
235 
236     gauge->value = 100;
237     gauge->state = success ? REISERFS_GAUGE_DONE : REISERFS_GAUGE_FAILED;
238     libreiserfs_gauge_touch(gauge);
239 }
240 
241