summaryrefslogtreecommitdiff
path: root/apps/plugins/lib/printcell_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/lib/printcell_helper.c')
-rw-r--r--apps/plugins/lib/printcell_helper.c297
1 files changed, 222 insertions, 75 deletions
diff --git a/apps/plugins/lib/printcell_helper.c b/apps/plugins/lib/printcell_helper.c
index 42de444c57..48b8b2c9d2 100644
--- a/apps/plugins/lib/printcell_helper.c
+++ b/apps/plugins/lib/printcell_helper.c
@@ -22,10 +22,6 @@
22#include "plugin.h" 22#include "plugin.h"
23#include "lib/printcell_helper.h" 23#include "lib/printcell_helper.h"
24 24
25#ifndef PRINTCELL_MAX_COLUMNS
26#define PRINTCELL_MAX_COLUMNS 16
27#endif
28
29#define COLUMN_ENDLEN 3 25#define COLUMN_ENDLEN 3
30#define TITLE_FLAG 0xFF 26#define TITLE_FLAG 0xFF
31#define SELECTED_FLAG 0x1 27#define SELECTED_FLAG 0x1
@@ -37,48 +33,54 @@
37#endif 33#endif
38 34
39struct printcell_info_t { 35struct printcell_info_t {
40 int offw[NB_SCREENS]; 36 struct gui_synclist *gui_list; /* list to display */
41 int iconw[NB_SCREENS]; 37 int offw[NB_SCREENS]; /* padding between column boundries and text */
42 int selcol_offw[NB_SCREENS]; 38 int iconw[NB_SCREENS]; /* width of an icon */
43 int totalcolw[NB_SCREENS]; 39 int selcol_offw[NB_SCREENS]; /* offset width calculated for selected item */
44 int firstcolxw[NB_SCREENS]; 40 int totalcolw[NB_SCREENS]; /* total width of all columns */
45 uint16_t colw[NB_SCREENS][PRINTCELL_MAX_COLUMNS]; 41 int firstcolxw[NB_SCREENS]; /* first column x + width, save recalculating */
46 int ncols; 42 int ncols; /* number of columns */
47 int selcol; 43 int selcol; /* selected column (-1 to ncols-1) */
48 int selcol_index; 44 uint32_t hidecol_flags; /*bits 0-31 set bit to 1 to hide a column (1<<col#) */
49 char title[PRINTCELL_MAXLINELEN]; 45 uint16_t colw[NB_SCREENS][PRINTCELL_MAX_COLUMNS]; /* width of title text
50 bool separator; 46 or MIN(or user defined width / screen width) */
47 char title[PRINTCELL_MAXLINELEN]; /* title buffer */
48 char titlesep; /* character that separates title column items (ex '$') */
49 char colsep; /* character that separates text column items (ex ',') */
50 bool separator; /* draw grid */
51}; 51};
52
52static struct printcell_info_t printcell; 53static struct printcell_info_t printcell;
53 54
54static void parse_dsptext(int ncols, const char *dsp_text, char* buffer, uint16_t *sidx) 55static void parse_dsptext(char splitchr, int ncols, const char *dsp_text,
56 char* buffer, size_t bufsz, uint16_t *sidx)
55{ 57{
56 /*Internal function loads sidx with split offsets indexing 58 /*Internal function loads sidx with split offsets indexing
57 the buffer of null terminated strings, splits on '$' 59 the buffer of null terminated strings, splits on 'splitchr'
58 _assumptions_: 60 _assumptions_:
59 dsp_text[len - 1] = \0, 61 dsp_text[len - 1] = \0,
60 buffer[PRINTCELL_MAXLINELEN],
61 sidx[PRINTCELL_MAX_COLUMNS] 62 sidx[PRINTCELL_MAX_COLUMNS]
62 */ 63 */
63 int i = 0; 64 int i = 0;
64 int j = 0; 65 size_t j = 0;
65 int ch = '$'; /* first column $ is optional */ 66 int ch = splitchr; /* first column $ is optional */
66 if (*dsp_text == '$') 67 if (*dsp_text == splitchr)
67 dsp_text++; 68 dsp_text++;
68 /* add null to the start of the text buffer */ 69 /* add null to the start of the text buffer */
69 buffer[j++] = '\0'; 70 buffer[j++] = '\0';
70 do 71 do
71 { 72 {
72 if (ch == '$') 73 if (ch == splitchr)
73 { 74 {
74 sidx[i] = j; 75 sidx[i] = j; /* save start index and copy next column to the buffer */
75 if (*dsp_text == '$') /* $$ escaped user must want to display $*/ 76 while (*dsp_text != '\0' && *dsp_text != splitchr && j < (bufsz - 1))
76 buffer[j++] = *dsp_text++; 77 {
77 while (*dsp_text != '\0' && *dsp_text != '$' && j < PRINTCELL_MAXLINELEN - 1)
78 buffer[j++] = *dsp_text++; 78 buffer[j++] = *dsp_text++;
79 }
79 buffer[j++] = '\0'; 80 buffer[j++] = '\0';
81
80 i++; 82 i++;
81 if (i >= ncols || j >= (PRINTCELL_MAXLINELEN - 1)) 83 if (i >= ncols || j >= (bufsz - 1))
82 break; 84 break;
83 } 85 }
84 ch = *dsp_text++; 86 ch = *dsp_text++;
@@ -146,23 +148,39 @@ static inline void set_cell_width(struct viewport *vp, int max_w, int new_w)
146static inline int printcells(struct screen *display, char* buffer, 148static inline int printcells(struct screen *display, char* buffer,
147 uint16_t *sidx, struct line_desc *linedes, 149 uint16_t *sidx, struct line_desc *linedes,
148 struct viewport *vp, int vp_w, int separator, 150 struct viewport *vp, int vp_w, int separator,
149 int x, int y, int offw, int selected_flag, bool scroll) 151 int x, int y, int offw, int selected_flag, int last_col,
152 bool scroll, bool is_title)
150{ 153{
151 /* Internal function prints remaining cells */ 154 /* Internal function prints remaining cells */
152 int text_offset = offw + offw; 155 int text_offset = offw + offw;
153 int ncols = printcell.ncols;
154 int screen = display->screen_type; 156 int screen = display->screen_type;
155 int height = linedes->height; 157 int height = linedes->height;
156 int selsep = (selected_flag == 0) ? 0: separator; 158 int selsep = (selected_flag == 0) ? 0: separator;
157 uint16_t *screencolwidth = printcell.colw[screen]; 159 uint16_t *screencolwidth = printcell.colw[screen];
158 160
159 for(int i = 1; i < ncols; i++) 161 for(int i = 1; i <= last_col; i++)
160 { 162 {
161 int ny = y; 163 int ny = y;
162 int nw = screencolwidth[i] + text_offset; 164 int nw = screencolwidth[i] + text_offset;
165 int offx = 0;
166
167 if (i == last_col || x + nw >= vp_w - offw + 1)
168 { /* not enough space for next column use up excess */
169 if (nw < (vp_w - x))
170 {
171 if (is_title)
172 offx = ((vp_w - x) - nw) / 2;
173 nw = vp_w - x;
174 }
175 }
176
177 if (!PRINTCELL_COLUMN_IS_VISIBLE(printcell.hidecol_flags, i))
178 nw = 0;
179
163 int nx = x + nw; 180 int nx = x + nw;
164 char *buftext; 181 char *buftext;
165 if (nx > 0 && x < vp_w) 182
183 if (nx > 0 && nw > offw && x < vp_w)
166 { 184 {
167 set_cell_width(vp, vp_w, nx); 185 set_cell_width(vp, vp_w, nx);
168 186
@@ -173,11 +191,15 @@ static inline int printcells(struct screen *display, char* buffer,
173 } 191 }
174 else 192 else
175 { 193 {
194 if (vp_w < x + text_offset)
195 {
196 scroll = false;
197 }
176 linedes->scroll = scroll; 198 linedes->scroll = scroll;
177 linedes->separator_height = separator; 199 linedes->separator_height = separator;
178 } 200 }
179 buftext = &buffer[sidx[i]]; 201 buftext = &buffer[sidx[i]];
180 display->put_line(x + offw, ny, linedes, "$t", buftext); 202 display->put_line(x + offw + offx, ny, linedes, "$t", buftext);
181 vp->width += COLUMN_ENDLEN + 1; 203 vp->width += COLUMN_ENDLEN + 1;
182 draw_selector(display, linedes, selected_flag, i, separator, x, ny, nw, height); 204 draw_selector(display, linedes, selected_flag, i, separator, x, ny, nw, height);
183 } 205 }
@@ -200,6 +222,10 @@ static inline int calcvisible(int screen, int vp_w, int text_offset, int sbwidth
200 for (int i = printcell.selcol - 1; i >= 0; i--) 222 for (int i = printcell.selcol - 1; i >= 0; i--)
201 { 223 {
202 int cw = screencolwidth[i] + text_offset; 224 int cw = screencolwidth[i] + text_offset;
225
226 if (!PRINTCELL_COLUMN_IS_VISIBLE(printcell.hidecol_flags, i))
227 cw = 0;
228
203 if (i == 0) 229 if (i == 0)
204 cw += screenicnwidth; 230 cw += screenicnwidth;
205 if (offset > 0 || cw > maxw) 231 if (offset > 0 || cw > maxw)
@@ -257,15 +283,30 @@ static void printcell_listdraw_fn(struct list_putlineinfo_t *list_info)
257 separator = 1; 283 separator = 1;
258 284
259 int nx = x; 285 int nx = x;
286 int last_col = printcell.ncols - 1;
287 int hidden_w = 0;
260 int nw, colxw; 288 int nw, colxw;
261 289 char *buftext;
262 printcell_buffer[0] = '\0'; 290 printcell_buffer[0] = '\0';
263 parse_dsptext(printcell.ncols, dsp_text, printcell_buffer, sidx); 291
264 char *buftext = &printcell_buffer[sidx[0]];
265 uint16_t *screencolwidth = printcell.colw[screen]; 292 uint16_t *screencolwidth = printcell.colw[screen];
293 if (printcell.hidecol_flags > 0)
294 {
295 for (int i = 0; i < printcell.ncols; i++)
296 {
297 if (PRINTCELL_COLUMN_IS_VISIBLE(printcell.hidecol_flags, i))
298 last_col = i;
299 else
300 hidden_w += (screencolwidth[i] + text_offset);
301 }
302 }
266 303
267 if (is_title) 304 if (is_title)
268 { 305 {
306 parse_dsptext(printcell.titlesep, printcell.ncols, dsp_text,
307 printcell_buffer, sizeof(printcell_buffer), sidx);
308
309 buftext = &printcell_buffer[sidx[0]]; /* set to first column text */
269 int sbwidth = 0; 310 int sbwidth = 0;
270 if (rb->global_settings->scrollbar == SCROLLBAR_LEFT) 311 if (rb->global_settings->scrollbar == SCROLLBAR_LEFT)
271 sbwidth = rb->global_settings->scrollbar_width; 312 sbwidth = rb->global_settings->scrollbar_width;
@@ -278,6 +319,9 @@ static void printcell_listdraw_fn(struct list_putlineinfo_t *list_info)
278 nx -= printcell.selcol_offw[screen]; 319 nx -= printcell.selcol_offw[screen];
279 320
280 nw = screencolwidth[0] + printcell.iconw[screen] + text_offset; 321 nw = screencolwidth[0] + printcell.iconw[screen] + text_offset;
322
323 if (!PRINTCELL_COLUMN_IS_VISIBLE(printcell.hidecol_flags, 0))
324 nw = printcell.iconw[screen] - 1;
281 nw += sbwidth; 325 nw += sbwidth;
282 326
283 colxw = nx + nw; 327 colxw = nx + nw;
@@ -301,20 +345,21 @@ static void printcell_listdraw_fn(struct list_putlineinfo_t *list_info)
301 } 345 }
302 else 346 else
303 { 347 {
348 parse_dsptext(printcell.colsep, printcell.ncols, dsp_text,
349 printcell_buffer, sizeof(printcell_buffer), sidx);
350
351 buftext = &printcell_buffer[sidx[0]]; /* set to first column text */
304 int cursor = Icon_NOICON; 352 int cursor = Icon_NOICON;
305 nx -= printcell.selcol_offw[screen]; 353 nx -= printcell.selcol_offw[screen];
306 354
307 if (selected_flag & SELECTED_FLAG) 355 if (selected_flag & SELECTED_FLAG)
308 { 356 {
309 if (printcell.selcol >= 0)
310 printcell.selcol_index = sidx[printcell.selcol]; /* save the item offset*/
311 else
312 printcell.selcol_index = -1;
313
314 cursor = Icon_Cursor; 357 cursor = Icon_Cursor;
315 /* limit length of selection if columns don't reach end */ 358 /* limit length of selection if columns don't reach end */
316 int maxw = nx + printcell.totalcolw[screen] + printcell.iconw[screen]; 359 int maxw = nx + printcell.totalcolw[screen] + printcell.iconw[screen];
317 maxw += text_offset * printcell.ncols; 360 maxw += text_offset * printcell.ncols;
361 maxw -= hidden_w;
362
318 if (vp_w > maxw) 363 if (vp_w > maxw)
319 vp->width = maxw; 364 vp->width = maxw;
320 /* display a blank line first to draw selector across all cells */ 365 /* display a blank line first to draw selector across all cells */
@@ -364,7 +409,7 @@ static void printcell_listdraw_fn(struct list_putlineinfo_t *list_info)
364 nx += nw; 409 nx += nw;
365 /* display remaining cells */ 410 /* display remaining cells */
366 printcells(display, printcell_buffer, sidx, linedes, vp, vp_w, separator, 411 printcells(display, printcell_buffer, sidx, linedes, vp, vp_w, separator,
367 nx, y, col_offset_width, selected_flag, scroll_items); 412 nx, y, col_offset_width, selected_flag, last_col, scroll_items, is_title);
368 413
369 /* draw a line at the bottom of the list */ 414 /* draw a line at the bottom of the list */
370 if (separator > 0 && line == list->nb_items - 1) 415 if (separator > 0 && line == list->nb_items - 1)
@@ -377,14 +422,17 @@ static void printcell_listdraw_fn(struct list_putlineinfo_t *list_info)
377 vp->width = vp_w; 422 vp->width = vp_w;
378} 423}
379 424
380void printcell_enable(struct gui_synclist *gui_list, bool enable, bool separator) 425void printcell_enable(bool enable)
381{ 426{
382 printcell.separator = separator; 427 if (!printcell.gui_list)
428 return;
429 struct gui_synclist *gui_list = printcell.gui_list;
383#ifdef HAVE_LCD_COLOR 430#ifdef HAVE_LCD_COLOR
384 static int list_sep_color = INT_MIN; 431 static int list_sep_color = INT_MIN;
385 if (enable) 432 if (enable)
386 { 433 {
387 list_sep_color = rb->global_settings->list_separator_color; 434 if (list_sep_color == INT_MIN)
435 list_sep_color = rb->global_settings->list_separator_color;
388 rb->global_settings->list_separator_color = rb->global_settings->fg_color; 436 rb->global_settings->list_separator_color = rb->global_settings->fg_color;
389 gui_list->callback_draw_item = printcell_listdraw_fn; 437 gui_list->callback_draw_item = printcell_listdraw_fn;
390 } 438 }
@@ -404,8 +452,11 @@ void printcell_enable(struct gui_synclist *gui_list, bool enable, bool separator
404 452
405} 453}
406 454
407int printcell_increment_column(struct gui_synclist *gui_list, int increment, bool wrap) 455int printcell_increment_column(int increment, bool wrap)
408{ 456{
457 if (!printcell.gui_list)
458 return -1;
459 struct gui_synclist *gui_list = printcell.gui_list;
409 int item = printcell.selcol + increment; 460 int item = printcell.selcol + increment;
410 int imin = -1; 461 int imin = -1;
411 int imax = printcell.ncols - 1; 462 int imax = printcell.ncols - 1;
@@ -425,36 +476,94 @@ int printcell_increment_column(struct gui_synclist *gui_list, int increment, boo
425 FOR_NB_SCREENS(n) /* offset needs recalculated */ 476 FOR_NB_SCREENS(n) /* offset needs recalculated */
426 printcell.selcol_offw[n] = 0; 477 printcell.selcol_offw[n] = 0;
427 printcell.selcol = item; 478 printcell.selcol = item;
428 printcell.selcol_index = 0; 479
429 rb->gui_synclist_draw(gui_list); 480 rb->gui_synclist_draw(gui_list);
481 rb->gui_synclist_speak_item(gui_list);
430 } 482 }
431 return item; 483 return item;
432} 484}
433 485
486int printcell_get_column_selected(void)
487{
488 if (!printcell.gui_list)
489 return -1;
490 return printcell.selcol;
491}
492
493uint32_t printcell_get_column_visibility(int col)
494{
495 if (col >= 0)
496 return (PRINTCELL_COLUMN_IS_VISIBLE(printcell.hidecol_flags, col) ? 0:1);
497 else /* return flag of all columns */
498 return printcell.hidecol_flags;
499}
500
501void printcell_set_column_visible(int col, bool visible)
502{
503 /* visible columns have 0 for the column bit hidden columns have the bit set */
504 if (col >= 0)
505 {
506 if (visible)
507 printcell.hidecol_flags &= ~(PRINTCELL_COLUMN_FLAG(col));
508 else
509 printcell.hidecol_flags |= PRINTCELL_COLUMN_FLAG(col);
510 }
511 else
512 {
513 if (visible) /* set to everything visible */
514 printcell.hidecol_flags = 0;
515 else /* set to everything hidden */
516 printcell.hidecol_flags = ((uint32_t)-1);
517 }
518}
519
434int printcell_set_columns(struct gui_synclist *gui_list, 520int printcell_set_columns(struct gui_synclist *gui_list,
435 char * title, enum themable_icons icon) 521 struct printcell_settings * pcs,
522 char * title, enum themable_icons icon)
436{ 523{
524
437 if (title == NULL) 525 if (title == NULL)
438 title = "$PRINTCELL NOT SETUP"; 526 title = "$PRINTCELL NOT SETUP";
527
528 if (pcs == NULL) /* DEFAULTS */
529 {
530#if LCD_DEPTH > 1
531 /* If line sep is set to automatic then outline cells */
532 bool sep = (rb->global_settings->list_separator_height < 0);
533#else
534 bool sep = (rb->global_settings->cursor_style == 0);
535#endif
536 pcs = &(struct printcell_settings){ .cell_separator = sep,
537 .title_delimeter = '$',
538 .text_delimeter = '$',
539 .hidecol_flags = 0};
540 }
541
439 uint16_t sidx[PRINTCELL_MAX_COLUMNS]; /* starting position of column in title string */ 542 uint16_t sidx[PRINTCELL_MAX_COLUMNS]; /* starting position of column in title string */
440 int width, height, user_minwidth; 543 int width, height, user_minwidth;
441 int i = 0; 544 int i = 0;
442 int j = 0; 545 size_t j = 0;
443 int ch = '$'; /* first column $ is optional */
444
445 rb->memset(&printcell, 0, sizeof(struct printcell_info_t)); 546 rb->memset(&printcell, 0, sizeof(struct printcell_info_t));
446 547
548 printcell.gui_list = gui_list;
549 printcell.separator = pcs->cell_separator;
550 printcell.titlesep = pcs->title_delimeter;
551 printcell.colsep = pcs->text_delimeter;
552 printcell.hidecol_flags = pcs->hidecol_flags;
553
554 int ch = printcell.titlesep; /* first column $ is optional */
555
447 FOR_NB_SCREENS(n) 556 FOR_NB_SCREENS(n)
448 { 557 {
449 rb->screens[n]->getstringsize("W", &width, &height); 558 rb->screens[n]->getstringsize("W", &width, &height);
450 printcell.offw[n] = width; /* set column text offset */ 559 printcell.offw[n] = width; /* set column text offset */
451 } 560 }
452 561
453 if (*title == '$') 562 if (*title == printcell.titlesep)
454 title++; 563 title++;
455 do 564 do
456 { 565 {
457 if (ch == '$') 566 if (ch == printcell.titlesep)
458 { 567 {
459 printcell.title[j++] = ch; 568 printcell.title[j++] = ch;
460 user_minwidth = 0; 569 user_minwidth = 0;
@@ -466,7 +575,7 @@ int printcell_set_columns(struct gui_synclist *gui_list,
466 user_minwidth = 10*user_minwidth + *title - '0'; 575 user_minwidth = 10*user_minwidth + *title - '0';
467 title++; 576 title++;
468 } 577 }
469 if (*title != '$') /* user forgot $ or wants to display '*' */ 578 if (*title != printcell.titlesep) /* user forgot titlesep or wants to display '*' */
470 { 579 {
471 title = dspst; 580 title = dspst;
472 user_minwidth = 0; 581 user_minwidth = 0;
@@ -476,17 +585,25 @@ int printcell_set_columns(struct gui_synclist *gui_list,
476 } 585 }
477 586
478 sidx[i] = j; 587 sidx[i] = j;
479 if (*title == '$') /* $$ escaped user must want to display $*/
480 printcell.title[j++] = *title++;
481 588
482 while (*title != '\0' && *title != '$' && j < PRINTCELL_MAXLINELEN - 1) 589 while (*title != '\0'
590 && *title != printcell.titlesep
591 && j < PRINTCELL_MAXLINELEN - 1)
592 {
483 printcell.title[j++] = *title++; 593 printcell.title[j++] = *title++;
594 }
484 595
485 FOR_NB_SCREENS(n) 596 FOR_NB_SCREENS(n)
486 { 597 {
487 rb->screens[n]->getstringsize(&printcell.title[sidx[i]], &width, &height); 598 rb->screens[n]->getstringsize(&printcell.title[sidx[i]],
599 &width, &height);
600
488 if (width < user_minwidth) 601 if (width < user_minwidth)
489 width = user_minwidth; 602 width = user_minwidth;
603
604 if (width > LCD_WIDTH)
605 width = LCD_WIDTH;
606
490 printcell.colw[n][i] = width; 607 printcell.colw[n][i] = width;
491 printcell.totalcolw[n] += width; 608 printcell.totalcolw[n] += width;
492 } 609 }
@@ -498,37 +615,67 @@ int printcell_set_columns(struct gui_synclist *gui_list,
498 printcell.ncols = i; 615 printcell.ncols = i;
499 printcell.title[j] = '\0'; 616 printcell.title[j] = '\0';
500 printcell.selcol = -1; 617 printcell.selcol = -1;
501 printcell.selcol_index = 0;
502 618
503 rb->gui_synclist_set_title(gui_list, printcell.title, icon); 619 rb->gui_synclist_set_title(gui_list, printcell.title, icon);
504 return printcell.ncols; 620 return printcell.ncols;
505} 621}
506 622
507char *printcell_get_selected_column_text(struct gui_synclist *gui_list, char *buf, size_t bufsz) 623char *printcell_get_title_text(int selcol, char *buf, size_t bufsz)
508{ 624{
509 int selected = gui_list->selected_item; 625 /* note offsets are calculated everytime this function is called
510 int index = printcell.selcol_index - 1; 626 * shouldn't be used in hot code paths */
627 int index = 0;
628 buf[0] = '\0';
629 if (selcol < 0) /* return entire string incld col formatting '$'*/
630 return printcell.title;
631
632 if (selcol < printcell.ncols)
633 {
634 uint16_t sidx[PRINTCELL_MAX_COLUMNS]; /*indexes zero terminated strings in buffer*/
635 parse_dsptext(printcell.titlesep, selcol + 1, printcell.title, buf, bufsz, sidx);
636 index = sidx[selcol];
637 }
638 return &buf[index];
639}
511 640
512 if (index < 0) 641char *printcell_get_column_text(int selcol, char *buf, size_t bufsz)
513 index = 0; 642{
643 int index = 0;
514 char *bpos; 644 char *bpos;
645 struct gui_synclist *gui_list = printcell.gui_list;
515 646
516 if (gui_list->callback_get_item_name(selected, gui_list->data, buf, bufsz) == buf) 647 if (gui_list && gui_list->callback_draw_item == printcell_listdraw_fn)
517 { 648 {
518 bpos = &buf[index]; 649 int col = selcol;
519 if (printcell.selcol < 0) /* return entire string incld col formatting '$'*/ 650 int item = gui_list->selected_item;
520 return bpos; 651 void *data = gui_list->data;
521 while(bpos < &buf[bufsz - 1]) 652
653 if (col < printcell.ncols
654 && gui_list->callback_get_item_name(item, data, buf, bufsz) == buf)
522 { 655 {
523 if (*bpos == '$' || *bpos == '\0') 656 bpos = buf;
524 goto success; 657 if (col < 0) /* return entire string incld col formatting '$'*/
525 bpos++; 658 {
659 return bpos;
660 }
661 bpos++; /* Skip sep/NULL */
662
663 while(bpos < &buf[bufsz - 1])
664 {
665 if (*bpos == printcell.colsep || *bpos == '\0')
666 {
667 if (col-- == 0)
668 goto success;
669 index = bpos - buf + 1; /* Skip sep/NULL */
670 }
671 bpos++;
672 }
526 } 673 }
527 } 674 }
528/*failure*/ 675/*failure*/
529 bpos = buf; 676 bpos = buf;
530 index = 0; 677 index = 0;
531success: 678success:
532 *bpos = '\0'; 679 *bpos = '\0';
533 return &buf[index]; 680 return &buf[index];
534} 681}