66#include <unistd.h>
77
88const char * get_color (char * file , const struct stat * sb );
9- const char * get_suffix (char * file , const struct stat * sb );
109const char * colorize_from_mode (char * file , const struct stat * sb );
1110const char * colorize_from_name (char * file );
12- char * * fzf_tab_colorize (char * file );
1311int compile_patterns (char * nam , char * * list_colors );
1412char * ftb_strcat (char * dst , int n , ...);
1513
@@ -123,42 +121,29 @@ int compile_patterns(char* nam, char** list_colors)
123121 return 0 ;
124122}
125123
126- // TODO: use zsh mod_export function `file_type` ?
127- const char * get_suffix (char * file , const struct stat * sb )
124+ static char get_suffix (char * file , const struct stat * sb )
128125{
129126 struct stat sb2 ;
130127 mode_t filemode = sb -> st_mode ;
131128
132- if (S_ISBLK (filemode ))
133- return "#" ;
134- else if (S_ISCHR (filemode ))
135- return "%" ;
136- else if (S_ISDIR (filemode ))
137- return "/" ;
138- else if (S_ISFIFO (filemode ))
139- return "|" ;
140- else if (S_ISLNK (filemode ))
129+ if (S_ISLNK (filemode ))
141130 if (strpfx (mode_color [COL_LN ], "target" )) {
142131 if (stat (file , & sb2 ) == -1 ) {
143- return "@" ;
132+ return '@' ;
144133 }
145134 return get_suffix (file , & sb2 );
146135 } else {
147- return "@" ;
136+ return '@' ;
148137 }
149- else if (S_ISREG (filemode ))
150- return (filemode & S_IXUGO ) ? "*" : "" ;
151- else if (S_ISSOCK (filemode ))
152- return "=" ;
153138 else
154- return "?" ;
139+ return file_type ( filemode ) ;
155140}
156141
157142const char * get_color (char * file , const struct stat * sb )
158143{
159- // no list-colors, return empty color
144+ // no list-colors, return NULL
160145 if (pat_cnt == 0 ) {
161- return "" ;
146+ return NULL ;
162147 }
163148 const char * ret ;
164149 if ((ret = colorize_from_mode (file , sb )) || (ret = colorize_from_name (file ))) {
@@ -277,10 +262,8 @@ static int bin_fzf_tab_compcap_generate(char* nam, char** args, Options ops, UNU
277262
278263 for (i = 0 ; words [i ]; i ++ ) {
279264 // TODO: replace '\n'
280- char * buffer = zshcalloc (256 * sizeof (char ));
281265 char * dscr = i < dscrs_cnt ? dscrs [i ] : words [i ];
282-
283- buffer = ftb_strcat (buffer , 5 , dscr , bs , opts , nul , words [i ]);
266+ char * buffer = ftb_strcat (NULL , 5 , dscr , bs , opts , nul , words [i ]);
284267 ftb_compcap .array [ftb_compcap .len ++ ] = buffer ;
285268
286269 if (ftb_compcap .len == ftb_compcap .size ) {
@@ -298,21 +281,23 @@ static int bin_fzf_tab_compcap_generate(char* nam, char** args, Options ops, UNU
298281}
299282
300283// cat n string, return the pointer to the new string
301- // `size` is the size of dst
302284// dst will be reallocated if is not big enough
285+ // if dst is NULL, it will be allocated
303286char * ftb_strcat (char * dst , int n , ...)
304287{
305288 int i , idx ;
306289
307290 va_list valist ;
308291 va_start (valist , n );
309292
310- char * final = zrealloc (dst , 128 );
293+ char * final = dst ? zrealloc (dst , 128 ) : zalloc ( 128 );
311294 size_t size = 128 , max_len = 128 - 1 ;
312295 dst = final ;
313296
314297 for (i = 0 , idx = 0 ; i < n ; i ++ ) {
315298 char * src = va_arg (valist , char * );
299+ if (src == NULL )
300+ continue ;
316301 for (; * src != '\0' ; dst ++ , src ++ , idx ++ ) {
317302 if (idx == max_len ) {
318303 size += size / 2 ;
@@ -329,30 +314,36 @@ char* ftb_strcat(char* dst, int n, ...)
329314 return final ;
330315}
331316
317+ struct file_color {
318+ char * fc_begin ;
319+ char * fc_end ;
320+ char * sc ;
321+ char * suffix ;
322+ };
323+
332324// accept an
333- char * * fzf_tab_colorize (char * file )
325+ static struct file_color * fzf_tab_colorize (char * file )
334326{
335- int i ;
327+ struct file_color * fc = zalloc ( sizeof ( struct file_color )) ;
336328
337- // TODO: can avoid so many zalloc here?
338329 file = unmeta (file );
339330
340331 struct stat sb ;
341332 if (lstat (file , & sb ) == -1 ) {
342333 return NULL ;
343334 }
344335
345- const char * suffix = "" ;
336+ char suffix [ 2 ] = { 0 } ;
346337 if (isset (opt_list_type )) {
347- suffix = get_suffix (file , & sb );
338+ suffix [ 0 ] = get_suffix (file , & sb );
348339 }
349340 const char * color = get_color (file , & sb );
350341
351- char * symlink = "" ;
342+ char * symlink = NULL ;
352343 const char * symcolor = "" ;
353344 if ((sb .st_mode & S_IFMT ) == S_IFLNK ) {
354- symlink = zalloc (PATH_MAX );
355- int end = readlink (file , symlink , PATH_MAX );
345+ symlink = zshcalloc (PATH_MAX );
346+ size_t end = readlink (file , symlink , PATH_MAX );
356347 symlink [end ] = '\0' ;
357348 if (stat (file , & sb ) == -1 ) {
358349 symcolor = mode_color [COL_OR ];
@@ -363,33 +354,30 @@ char** fzf_tab_colorize(char* file)
363354 }
364355 }
365356
366- char * * reply = zshcalloc ((4 + 1 ) * sizeof (char * ));
367-
368- if (strlen (color ) != 0 ) {
369- reply [0 ] = zalloc (128 );
370- reply [1 ] = zalloc (128 );
371- sprintf (reply [0 ], "%s%s%s" , mode_color [COL_LC ], color , mode_color [COL_RC ]);
372- sprintf (reply [1 ], "%s%s%s" , mode_color [COL_LC ], "0" , mode_color [COL_RC ]);
357+ if (color != NULL ) {
358+ fc -> fc_begin = ftb_strcat (NULL , 3 , mode_color [COL_LC ], color , mode_color [COL_RC ]);
359+ fc -> fc_end = ftb_strcat (NULL , 3 , mode_color [COL_LC ], "0" , mode_color [COL_RC ]);
373360 } else {
374- reply [ 0 ] = ztrdup ("" );
375- reply [ 1 ] = ztrdup ("" );
361+ fc -> fc_begin = ztrdup ("" );
362+ fc -> fc_end = ztrdup ("" );
376363 }
377364
378- reply [ 2 ] = ztrdup (suffix );
365+ fc -> suffix = ztrdup (suffix );
379366
380- if (symlink [0 ] != '\0' ) {
381- reply [3 ] = zalloc (PATH_MAX );
382- sprintf (reply [3 ], "%s%s%s%s%s%s%s" , mode_color [COL_LC ], symcolor , mode_color [COL_RC ],
383- symlink , mode_color [COL_LC ], "0" , mode_color [COL_RC ]);
367+ if (symlink != NULL ) {
368+ fc -> sc = ftb_strcat (NULL , 7 , mode_color [COL_LC ], symcolor , mode_color [COL_RC ],
369+ symlink , mode_color [COL_LC ], "0" , mode_color [COL_RC ]);
384370 free (symlink );
385371 } else {
386- reply [3 ] = ztrdup ("" );
387- }
388- for (i = 0 ; i < 4 ; i ++ ) {
389- reply [i ] = metafy (reply [i ], -1 , META_REALLOC );
372+ fc -> sc = ztrdup ("" );
390373 }
391374
392- return reply ;
375+ fc -> fc_begin = metafy (fc -> fc_begin , -1 , META_REALLOC );
376+ fc -> fc_end = metafy (fc -> fc_end , -1 , META_REALLOC );
377+ fc -> sc = metafy (fc -> sc , -1 , META_REALLOC );
378+ fc -> suffix = metafy (fc -> suffix , -1 , META_REALLOC );
379+
380+ return fc ;
393381}
394382
395383static int bin_fzf_tab_candidates_generate (char * nam , char * * args , Options ops , UNUSED (int func ))
@@ -420,7 +408,7 @@ static int bin_fzf_tab_candidates_generate(char* nam, char** args, Options ops,
420408 * filepath = zshcalloc (PATH_MAX * sizeof (char )), * dpre = zshcalloc (128 ),
421409 * dsuf = zshcalloc (128 );
422410
423- char * first_word = zshcalloc ( 512 * sizeof ( char )) ;
411+ char * first_word = NULL ;
424412 int same_word = 1 ;
425413
426414 for (i = 0 ; i < ftb_compcap_len ; i ++ ) {
@@ -448,27 +436,27 @@ static int bin_fzf_tab_candidates_generate(char* nam, char** args, Options ops,
448436 }
449437
450438 // check if all the words are the same
451- if (i == 0 ) {
452- first_word = ftb_strcat ( first_word , 1 , word );
439+ if (first_word == NULL ) {
440+ first_word = ztrdup ( word );
453441 } else if (same_word && strcmp (word , first_word ) != 0 ) {
454442 same_word = 0 ;
455443 }
456444
457445 // add character and color to describe the type of the files
458446 if (realdir ) {
459447 filepath = ftb_strcat (filepath , 2 , realdir , word );
460- char * * reply = fzf_tab_colorize (filepath );
461- if (reply != NULL ) {
462- dpre = ftb_strcat (dpre , 2 , reply [ 1 ], reply [ 0 ] );
463- if (reply [ 3 ] [0 ] != '\0' ) {
464- dsuf = ftb_strcat (dsuf , 4 , reply [ 1 ], reply [ 2 ] , " -> " , reply [ 3 ] );
448+ struct file_color * fc = fzf_tab_colorize (filepath );
449+ if (fc != NULL ) {
450+ dpre = ftb_strcat (dpre , 2 , fc -> fc_end , fc -> fc_begin );
451+ if (fc -> sc [0 ] != '\0' ) {
452+ dsuf = ftb_strcat (dsuf , 4 , fc -> fc_end , fc -> suffix , " -> " , fc -> sc );
465453 } else {
466- dsuf = ftb_strcat (dsuf , 2 , reply [ 1 ], reply [ 2 ] );
454+ dsuf = ftb_strcat (dsuf , 2 , fc -> fc_end , fc -> suffix );
467455 }
468456 if (dpre [0 ] != '\0' ) {
469457 setiparam ("colorful" , 1 );
470458 }
471- freearray ( reply );
459+ free ( fc );
472460 }
473461 }
474462
0 commit comments