2011/2/9 Jonathan Nieder <jrnieder@xxxxxxxxx>: > Nguyán ThÃi Ngác Duy wrote: > >> +++ b/column.c >> @@ -0,0 +1,177 @@ > [...] >> +static int item_length(const struct column_layout *c, const char *s) >> +{ >> +   int a_len = 0; >> + >> +   if (!(c->mode & COL_ANSI)) >> +       return strlen(s); >> + >> +   while ((s = strstr(s, "\033[")) != NULL) { >> +       int len = strspn(s+2, "0123456789;"); >> +       s += len+3; /* \033[<len><func char> */ >> +       a_len += len+3; >> +   } >> +   return a_len; >> +} > > I think you mean "return strlen(orig_s) - a_len". > > Something like the following could be more obvious, though > it is unfortunately verbose. > >    Âint len = 0; >    Âwhile (*s) { >        Âconst char *next; > >        Â/* \033[<len><func char> */ >        Âif (!prefixcmp(s, "\033[")) { >            Âs += strlen("\033["); >            Âs += strspn(s, "0123456789;"); >            Âif (!*s) >                Â... handle somehow ... >            Âs++; >        Â} > >        Ânext = strchrnul(s, '\033'); >        Âlen += next - s; >        Âs = next; >    Â} > > Both miscompute the width of "DÃpÃt". ÂSomething like this can do ok > if the string is modifiable and we know it is UTF-8: > >        Âchar save; >        Â... >        Ânext = strchrnul(s, '\033'); > >        Â/* >         * NEEDSWORK: a utf8_strwidth variant that >         * accepts a memory area not terminated by \0 >         * would avoid this ugliness. >         */ >        Âsave = *next; >        Â*next = '\0'; >        Âlen += utf8_strwidth(s); >        Â*next = save; > > POSIX does not provide a strwidth function, so if we want to handle > encodings like SHIFT-JIS then something uglier[1] might come to life. I think UTF-8 is enough. Git does not produce complex ansi escape codes. Perhaps checking them at the beginning and reset code at the end is enough. > [...] >> +static void relayout(const struct column_layout *c, >> +         Âint padding, int spare, >> +         Âint *initial_width, int **width, >> +         Âint *rows, int *cols) >> +{ >> +   int new_rows, new_cols, new_initial_width; >> +   int i, *new_width, new_spare, total_width; >> + >> +   /* >> +   Â* Assume all columns have same width, we would need >> +   Â* initial_width*cols. But then after squeezing, we have >> +   Â* "spare" more chars. Assume a new total_width with >> +   Â* additional chars, then re-squeeze to see if it fits >> +   Â* c->width. >> +   Â*/ > > Might be easier to debug if this part were deferred to a separate > patch. :) > >> +   total_width = (*initial_width)*(*cols) + spare; > > An odd heuristic. ÂDoes it work well in practice? It seems so. If it does not, I guess I would need to look into how GNU ls does it. -- Duy ÿô.nÇ·®+%˱é¥wÿº{.nÇ· ßØnr¡öë¨è&£ûz¹Þúzf£¢·h§~Ûÿÿïÿê_èæ+v¨þ)ßø