diff options
Diffstat (limited to 'scripts/kconfig/lxdialog/textbox.c')
-rw-r--r-- | scripts/kconfig/lxdialog/textbox.c | 298 |
1 files changed, 64 insertions, 234 deletions
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c index 336793b03954..86b0770b0387 100644 --- a/scripts/kconfig/lxdialog/textbox.c +++ b/scripts/kconfig/lxdialog/textbox.c | |||
@@ -27,54 +27,27 @@ static void print_line(WINDOW * win, int row, int width); | |||
27 | static char *get_line(void); | 27 | static char *get_line(void); |
28 | static void print_position(WINDOW * win, int height, int width); | 28 | static void print_position(WINDOW * win, int height, int width); |
29 | 29 | ||
30 | static int hscroll, fd, file_size, bytes_read; | 30 | static int hscroll; |
31 | static int begin_reached = 1, end_reached, page_length; | 31 | static int begin_reached, end_reached, page_length; |
32 | static char *buf, *page; | 32 | static const char *buf; |
33 | static const char *page; | ||
33 | 34 | ||
34 | /* | 35 | /* |
35 | * Display text from a file in a dialog box. | 36 | * Display text from a file in a dialog box. |
36 | */ | 37 | */ |
37 | int dialog_textbox(const char *title, const char *file, int height, int width) | 38 | int dialog_textbox(const char *title, const char *tbuf, int height, int width) |
38 | { | 39 | { |
39 | int i, x, y, cur_x, cur_y, fpos, key = 0; | 40 | int i, x, y, cur_x, cur_y, key = 0; |
41 | int texth, textw; | ||
40 | int passed_end; | 42 | int passed_end; |
41 | char search_term[MAX_LEN + 1]; | ||
42 | WINDOW *dialog, *text; | 43 | WINDOW *dialog, *text; |
43 | 44 | ||
44 | search_term[0] = '\0'; /* no search term entered yet */ | 45 | begin_reached = 1; |
45 | 46 | end_reached = 0; | |
46 | /* Open input file for reading */ | 47 | page_length = 0; |
47 | if ((fd = open(file, O_RDONLY)) == -1) { | 48 | hscroll = 0; |
48 | endwin(); | 49 | buf = tbuf; |
49 | fprintf(stderr, "\nCan't open input file in dialog_textbox().\n"); | 50 | page = buf; /* page is pointer to start of page to be displayed */ |
50 | exit(-1); | ||
51 | } | ||
52 | /* Get file size. Actually, 'file_size' is the real file size - 1, | ||
53 | since it's only the last byte offset from the beginning */ | ||
54 | if ((file_size = lseek(fd, 0, SEEK_END)) == -1) { | ||
55 | endwin(); | ||
56 | fprintf(stderr, "\nError getting file size in dialog_textbox().\n"); | ||
57 | exit(-1); | ||
58 | } | ||
59 | /* Restore file pointer to beginning of file after getting file size */ | ||
60 | if (lseek(fd, 0, SEEK_SET) == -1) { | ||
61 | endwin(); | ||
62 | fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); | ||
63 | exit(-1); | ||
64 | } | ||
65 | /* Allocate space for read buffer */ | ||
66 | if ((buf = malloc(BUF_SIZE + 1)) == NULL) { | ||
67 | endwin(); | ||
68 | fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n"); | ||
69 | exit(-1); | ||
70 | } | ||
71 | if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) { | ||
72 | endwin(); | ||
73 | fprintf(stderr, "\nError reading file in dialog_textbox().\n"); | ||
74 | exit(-1); | ||
75 | } | ||
76 | buf[bytes_read] = '\0'; /* mark end of valid data */ | ||
77 | page = buf; /* page is pointer to start of page to be displayed */ | ||
78 | 51 | ||
79 | /* center dialog box on screen */ | 52 | /* center dialog box on screen */ |
80 | x = (COLS - width) / 2; | 53 | x = (COLS - width) / 2; |
@@ -86,7 +59,9 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
86 | keypad(dialog, TRUE); | 59 | keypad(dialog, TRUE); |
87 | 60 | ||
88 | /* Create window for text region, used for scrolling text */ | 61 | /* Create window for text region, used for scrolling text */ |
89 | text = subwin(dialog, height - 4, width - 2, y + 1, x + 1); | 62 | texth = height - 4; |
63 | textw = width - 2; | ||
64 | text = subwin(dialog, texth, textw, y + 1, x + 1); | ||
90 | wattrset(text, dlg.dialog.atr); | 65 | wattrset(text, dlg.dialog.atr); |
91 | wbkgdset(text, dlg.dialog.atr & A_COLOR); | 66 | wbkgdset(text, dlg.dialog.atr & A_COLOR); |
92 | 67 | ||
@@ -111,8 +86,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
111 | getyx(dialog, cur_y, cur_x); /* Save cursor position */ | 86 | getyx(dialog, cur_y, cur_x); /* Save cursor position */ |
112 | 87 | ||
113 | /* Print first page of text */ | 88 | /* Print first page of text */ |
114 | attr_clear(text, height - 4, width - 2, dlg.dialog.atr); | 89 | attr_clear(text, texth, textw, dlg.dialog.atr); |
115 | print_page(text, height - 4, width - 2); | 90 | print_page(text, texth, textw); |
116 | print_position(dialog, height, width); | 91 | print_position(dialog, height, width); |
117 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | 92 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ |
118 | wrefresh(dialog); | 93 | wrefresh(dialog); |
@@ -124,37 +99,15 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
124 | case 'e': | 99 | case 'e': |
125 | case 'X': | 100 | case 'X': |
126 | case 'x': | 101 | case 'x': |
102 | delwin(text); | ||
127 | delwin(dialog); | 103 | delwin(dialog); |
128 | free(buf); | ||
129 | close(fd); | ||
130 | return 0; | 104 | return 0; |
131 | case 'g': /* First page */ | 105 | case 'g': /* First page */ |
132 | case KEY_HOME: | 106 | case KEY_HOME: |
133 | if (!begin_reached) { | 107 | if (!begin_reached) { |
134 | begin_reached = 1; | 108 | begin_reached = 1; |
135 | /* First page not in buffer? */ | ||
136 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { | ||
137 | endwin(); | ||
138 | fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); | ||
139 | exit(-1); | ||
140 | } | ||
141 | if (fpos > bytes_read) { /* Yes, we have to read it in */ | ||
142 | if (lseek(fd, 0, SEEK_SET) == -1) { | ||
143 | endwin(); | ||
144 | fprintf(stderr, "\nError moving file pointer in " | ||
145 | "dialog_textbox().\n"); | ||
146 | exit(-1); | ||
147 | } | ||
148 | if ((bytes_read = | ||
149 | read(fd, buf, BUF_SIZE)) == -1) { | ||
150 | endwin(); | ||
151 | fprintf(stderr, "\nError reading file in dialog_textbox().\n"); | ||
152 | exit(-1); | ||
153 | } | ||
154 | buf[bytes_read] = '\0'; | ||
155 | } | ||
156 | page = buf; | 109 | page = buf; |
157 | print_page(text, height - 4, width - 2); | 110 | print_page(text, texth, textw); |
158 | print_position(dialog, height, width); | 111 | print_position(dialog, height, width); |
159 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | 112 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ |
160 | wrefresh(dialog); | 113 | wrefresh(dialog); |
@@ -164,29 +117,10 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
164 | case KEY_END: | 117 | case KEY_END: |
165 | 118 | ||
166 | end_reached = 1; | 119 | end_reached = 1; |
167 | /* Last page not in buffer? */ | 120 | /* point to last char in buf */ |
168 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { | 121 | page = buf + strlen(buf); |
169 | endwin(); | 122 | back_lines(texth); |
170 | fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); | 123 | print_page(text, texth, textw); |
171 | exit(-1); | ||
172 | } | ||
173 | if (fpos < file_size) { /* Yes, we have to read it in */ | ||
174 | if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) { | ||
175 | endwin(); | ||
176 | fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); | ||
177 | exit(-1); | ||
178 | } | ||
179 | if ((bytes_read = | ||
180 | read(fd, buf, BUF_SIZE)) == -1) { | ||
181 | endwin(); | ||
182 | fprintf(stderr, "\nError reading file in dialog_textbox().\n"); | ||
183 | exit(-1); | ||
184 | } | ||
185 | buf[bytes_read] = '\0'; | ||
186 | } | ||
187 | page = buf + bytes_read; | ||
188 | back_lines(height - 4); | ||
189 | print_page(text, height - 4, width - 2); | ||
190 | print_position(dialog, height, width); | 124 | print_position(dialog, height, width); |
191 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | 125 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ |
192 | wrefresh(dialog); | 126 | wrefresh(dialog); |
@@ -197,20 +131,22 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
197 | if (!begin_reached) { | 131 | if (!begin_reached) { |
198 | back_lines(page_length + 1); | 132 | back_lines(page_length + 1); |
199 | 133 | ||
200 | /* We don't call print_page() here but use scrolling to ensure | 134 | /* We don't call print_page() here but use |
201 | faster screen update. However, 'end_reached' and | 135 | * scrolling to ensure faster screen update. |
202 | 'page_length' should still be updated, and 'page' should | 136 | * However, 'end_reached' and 'page_length' |
203 | point to start of next page. This is done by calling | 137 | * should still be updated, and 'page' should |
204 | get_line() in the following 'for' loop. */ | 138 | * point to start of next page. This is done |
139 | * by calling get_line() in the following | ||
140 | * 'for' loop. */ | ||
205 | scrollok(text, TRUE); | 141 | scrollok(text, TRUE); |
206 | wscrl(text, -1); /* Scroll text region down one line */ | 142 | wscrl(text, -1); /* Scroll text region down one line */ |
207 | scrollok(text, FALSE); | 143 | scrollok(text, FALSE); |
208 | page_length = 0; | 144 | page_length = 0; |
209 | passed_end = 0; | 145 | passed_end = 0; |
210 | for (i = 0; i < height - 4; i++) { | 146 | for (i = 0; i < texth; i++) { |
211 | if (!i) { | 147 | if (!i) { |
212 | /* print first line of page */ | 148 | /* print first line of page */ |
213 | print_line(text, 0, width - 2); | 149 | print_line(text, 0, textw); |
214 | wnoutrefresh(text); | 150 | wnoutrefresh(text); |
215 | } else | 151 | } else |
216 | /* Called to update 'end_reached' and 'page' */ | 152 | /* Called to update 'end_reached' and 'page' */ |
@@ -231,8 +167,8 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
231 | case KEY_PPAGE: | 167 | case KEY_PPAGE: |
232 | if (begin_reached) | 168 | if (begin_reached) |
233 | break; | 169 | break; |
234 | back_lines(page_length + height - 4); | 170 | back_lines(page_length + texth); |
235 | print_page(text, height - 4, width - 2); | 171 | print_page(text, texth, textw); |
236 | print_position(dialog, height, width); | 172 | print_position(dialog, height, width); |
237 | wmove(dialog, cur_y, cur_x); | 173 | wmove(dialog, cur_y, cur_x); |
238 | wrefresh(dialog); | 174 | wrefresh(dialog); |
@@ -245,7 +181,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
245 | scrollok(text, TRUE); | 181 | scrollok(text, TRUE); |
246 | scroll(text); /* Scroll text region up one line */ | 182 | scroll(text); /* Scroll text region up one line */ |
247 | scrollok(text, FALSE); | 183 | scrollok(text, FALSE); |
248 | print_line(text, height - 5, width - 2); | 184 | print_line(text, texth - 1, textw); |
249 | wnoutrefresh(text); | 185 | wnoutrefresh(text); |
250 | print_position(dialog, height, width); | 186 | print_position(dialog, height, width); |
251 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | 187 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ |
@@ -258,7 +194,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
258 | break; | 194 | break; |
259 | 195 | ||
260 | begin_reached = 0; | 196 | begin_reached = 0; |
261 | print_page(text, height - 4, width - 2); | 197 | print_page(text, texth, textw); |
262 | print_position(dialog, height, width); | 198 | print_position(dialog, height, width); |
263 | wmove(dialog, cur_y, cur_x); | 199 | wmove(dialog, cur_y, cur_x); |
264 | wrefresh(dialog); | 200 | wrefresh(dialog); |
@@ -276,7 +212,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
276 | hscroll--; | 212 | hscroll--; |
277 | /* Reprint current page to scroll horizontally */ | 213 | /* Reprint current page to scroll horizontally */ |
278 | back_lines(page_length); | 214 | back_lines(page_length); |
279 | print_page(text, height - 4, width - 2); | 215 | print_page(text, texth, textw); |
280 | wmove(dialog, cur_y, cur_x); | 216 | wmove(dialog, cur_y, cur_x); |
281 | wrefresh(dialog); | 217 | wrefresh(dialog); |
282 | break; | 218 | break; |
@@ -288,7 +224,7 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
288 | hscroll++; | 224 | hscroll++; |
289 | /* Reprint current page to scroll horizontally */ | 225 | /* Reprint current page to scroll horizontally */ |
290 | back_lines(page_length); | 226 | back_lines(page_length); |
291 | print_page(text, height - 4, width - 2); | 227 | print_page(text, texth, textw); |
292 | wmove(dialog, cur_y, cur_x); | 228 | wmove(dialog, cur_y, cur_x); |
293 | wrefresh(dialog); | 229 | wrefresh(dialog); |
294 | break; | 230 | break; |
@@ -296,123 +232,42 @@ int dialog_textbox(const char *title, const char *file, int height, int width) | |||
296 | break; | 232 | break; |
297 | } | 233 | } |
298 | } | 234 | } |
299 | 235 | delwin(text); | |
300 | delwin(dialog); | 236 | delwin(dialog); |
301 | free(buf); | 237 | return 255; /* ESC pressed */ |
302 | close(fd); | ||
303 | return -1; /* ESC pressed */ | ||
304 | } | 238 | } |
305 | 239 | ||
306 | /* | 240 | /* |
307 | * Go back 'n' lines in text file. Called by dialog_textbox(). | 241 | * Go back 'n' lines in text. Called by dialog_textbox(). |
308 | * 'page' will be updated to point to the desired line in 'buf'. | 242 | * 'page' will be updated to point to the desired line in 'buf'. |
309 | */ | 243 | */ |
310 | static void back_lines(int n) | 244 | static void back_lines(int n) |
311 | { | 245 | { |
312 | int i, fpos; | 246 | int i; |
313 | 247 | ||
314 | begin_reached = 0; | 248 | begin_reached = 0; |
315 | /* We have to distinguish between end_reached and !end_reached | 249 | /* Go back 'n' lines */ |
316 | since at end of file, the line is not ended by a '\n'. | 250 | for (i = 0; i < n; i++) { |
317 | The code inside 'if' basically does a '--page' to move one | 251 | if (*page == '\0') { |
318 | character backward so as to skip '\n' of the previous line */ | 252 | if (end_reached) { |
319 | if (!end_reached) { | 253 | end_reached = 0; |
320 | /* Either beginning of buffer or beginning of file reached? */ | 254 | continue; |
321 | if (page == buf) { | ||
322 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { | ||
323 | endwin(); | ||
324 | fprintf(stderr, "\nError moving file pointer in " | ||
325 | "back_lines().\n"); | ||
326 | exit(-1); | ||
327 | } | ||
328 | if (fpos > bytes_read) { /* Not beginning of file yet */ | ||
329 | /* We've reached beginning of buffer, but not beginning of | ||
330 | file yet, so read previous part of file into buffer. | ||
331 | Note that we only move backward for BUF_SIZE/2 bytes, | ||
332 | but not BUF_SIZE bytes to avoid re-reading again in | ||
333 | print_page() later */ | ||
334 | /* Really possible to move backward BUF_SIZE/2 bytes? */ | ||
335 | if (fpos < BUF_SIZE / 2 + bytes_read) { | ||
336 | /* No, move less then */ | ||
337 | if (lseek(fd, 0, SEEK_SET) == -1) { | ||
338 | endwin(); | ||
339 | fprintf(stderr, "\nError moving file pointer in " | ||
340 | "back_lines().\n"); | ||
341 | exit(-1); | ||
342 | } | ||
343 | page = buf + fpos - bytes_read; | ||
344 | } else { /* Move backward BUF_SIZE/2 bytes */ | ||
345 | if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) { | ||
346 | endwin(); | ||
347 | fprintf(stderr, "\nError moving file pointer " | ||
348 | "in back_lines().\n"); | ||
349 | exit(-1); | ||
350 | } | ||
351 | page = buf + BUF_SIZE / 2; | ||
352 | } | ||
353 | if ((bytes_read = | ||
354 | read(fd, buf, BUF_SIZE)) == -1) { | ||
355 | endwin(); | ||
356 | fprintf(stderr, "\nError reading file in back_lines().\n"); | ||
357 | exit(-1); | ||
358 | } | ||
359 | buf[bytes_read] = '\0'; | ||
360 | } else { /* Beginning of file reached */ | ||
361 | begin_reached = 1; | ||
362 | return; | ||
363 | } | 255 | } |
364 | } | 256 | } |
365 | if (*(--page) != '\n') { /* '--page' here */ | 257 | if (page == buf) { |
366 | /* Something's wrong... */ | 258 | begin_reached = 1; |
367 | endwin(); | 259 | return; |
368 | fprintf(stderr, "\nInternal error in back_lines().\n"); | ||
369 | exit(-1); | ||
370 | } | 260 | } |
371 | } | 261 | page--; |
372 | /* Go back 'n' lines */ | ||
373 | for (i = 0; i < n; i++) | ||
374 | do { | 262 | do { |
375 | if (page == buf) { | 263 | if (page == buf) { |
376 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { | 264 | begin_reached = 1; |
377 | endwin(); | 265 | return; |
378 | fprintf(stderr, "\nError moving file pointer in back_lines().\n"); | ||
379 | exit(-1); | ||
380 | } | ||
381 | if (fpos > bytes_read) { | ||
382 | /* Really possible to move backward BUF_SIZE/2 bytes? */ | ||
383 | if (fpos < BUF_SIZE / 2 + bytes_read) { | ||
384 | /* No, move less then */ | ||
385 | if (lseek(fd, 0, SEEK_SET) == -1) { | ||
386 | endwin(); | ||
387 | fprintf(stderr, "\nError moving file pointer " | ||
388 | "in back_lines().\n"); | ||
389 | exit(-1); | ||
390 | } | ||
391 | page = buf + fpos - bytes_read; | ||
392 | } else { /* Move backward BUF_SIZE/2 bytes */ | ||
393 | if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) { | ||
394 | endwin(); | ||
395 | fprintf(stderr, "\nError moving file pointer" | ||
396 | " in back_lines().\n"); | ||
397 | exit(-1); | ||
398 | } | ||
399 | page = buf + BUF_SIZE / 2; | ||
400 | } | ||
401 | if ((bytes_read = | ||
402 | read(fd, buf, BUF_SIZE)) == -1) { | ||
403 | endwin(); | ||
404 | fprintf(stderr, "\nError reading file in " | ||
405 | "back_lines().\n"); | ||
406 | exit(-1); | ||
407 | } | ||
408 | buf[bytes_read] = '\0'; | ||
409 | } else { /* Beginning of file reached */ | ||
410 | begin_reached = 1; | ||
411 | return; | ||
412 | } | ||
413 | } | 266 | } |
414 | } while (*(--page) != '\n'); | 267 | page--; |
415 | page++; | 268 | } while (*page != '\n'); |
269 | page++; | ||
270 | } | ||
416 | } | 271 | } |
417 | 272 | ||
418 | /* | 273 | /* |
@@ -467,33 +322,14 @@ static void print_line(WINDOW * win, int row, int width) | |||
467 | */ | 322 | */ |
468 | static char *get_line(void) | 323 | static char *get_line(void) |
469 | { | 324 | { |
470 | int i = 0, fpos; | 325 | int i = 0; |
471 | static char line[MAX_LEN + 1]; | 326 | static char line[MAX_LEN + 1]; |
472 | 327 | ||
473 | end_reached = 0; | 328 | end_reached = 0; |
474 | while (*page != '\n') { | 329 | while (*page != '\n') { |
475 | if (*page == '\0') { | 330 | if (*page == '\0') { |
476 | /* Either end of file or end of buffer reached */ | 331 | if (!end_reached) { |
477 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { | 332 | end_reached = 1; |
478 | endwin(); | ||
479 | fprintf(stderr, "\nError moving file pointer in " | ||
480 | "get_line().\n"); | ||
481 | exit(-1); | ||
482 | } | ||
483 | if (fpos < file_size) { /* Not end of file yet */ | ||
484 | /* We've reached end of buffer, but not end of file yet, | ||
485 | so read next part of file into buffer */ | ||
486 | if ((bytes_read = | ||
487 | read(fd, buf, BUF_SIZE)) == -1) { | ||
488 | endwin(); | ||
489 | fprintf(stderr, "\nError reading file in get_line().\n"); | ||
490 | exit(-1); | ||
491 | } | ||
492 | buf[bytes_read] = '\0'; | ||
493 | page = buf; | ||
494 | } else { | ||
495 | if (!end_reached) | ||
496 | end_reached = 1; | ||
497 | break; | 333 | break; |
498 | } | 334 | } |
499 | } else if (i < MAX_LEN) | 335 | } else if (i < MAX_LEN) |
@@ -518,17 +354,11 @@ static char *get_line(void) | |||
518 | */ | 354 | */ |
519 | static void print_position(WINDOW * win, int height, int width) | 355 | static void print_position(WINDOW * win, int height, int width) |
520 | { | 356 | { |
521 | int fpos, percent; | 357 | int percent; |
522 | 358 | ||
523 | if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { | ||
524 | endwin(); | ||
525 | fprintf(stderr, "\nError moving file pointer in print_position().\n"); | ||
526 | exit(-1); | ||
527 | } | ||
528 | wattrset(win, dlg.position_indicator.atr); | 359 | wattrset(win, dlg.position_indicator.atr); |
529 | wbkgdset(win, dlg.position_indicator.atr & A_COLOR); | 360 | wbkgdset(win, dlg.position_indicator.atr & A_COLOR); |
530 | percent = !file_size ? | 361 | percent = (page - buf) * 100 / strlen(buf); |
531 | 100 : ((fpos - bytes_read + page - buf) * 100) / file_size; | ||
532 | wmove(win, height - 3, width - 9); | 362 | wmove(win, height - 3, width - 9); |
533 | wprintw(win, "(%3d%%)", percent); | 363 | wprintw(win, "(%3d%%)", percent); |
534 | } | 364 | } |