Project

General

Profile

Bug #182 ยป strwidth.patch

Robin Hahling, 07/22/2016 08:44 PM

View differences:

src/dfc.c
39 39
#include <stdio.h>
40 40
#include <stdlib.h>
41 41
#include <string.h>
42
#include <locale.h>
42 43

  
43 44
#include "dfc.h"
44 45

  
45 46
#ifdef NLS_ENABLED
46
#include <locale.h>
47 47
#include <libintl.h>
48 48
#endif /* NLS_ENABLED */
49 49

  
......
154 154
		NULL
155 155
	};
156 156

  
157
#ifdef NLS_ENABLED
158
	/* translation support */
157
	// Use user locale rather than default C locale.
158
	// This allows handling unicode strings in path and so on.
159
	// (see also strwidth() in util.c)
159 160
	if (setlocale(LC_ALL, "") == NULL) {
160 161
		(void)fputs("Locale cannot be set\n", stderr);
161 162
		ret = EXIT_FAILURE;
162 163
	}
164

  
165
#ifdef NLS_ENABLED
166
	/* translation support */
163 167
	if (bindtextdomain(PACKAGE, LOCALEDIR) == NULL) {
164 168
		(void)fputs("Cannot bind locale\n", stderr);
165 169
		ret = EXIT_FAILURE;
src/export/text.c
106 106
	if (!bflag) {
107 107
		(void)printf("%s", _("(=) USED"));
108 108
		gap = max.bar -
109
		         (int)strlen(_("(=) USED")) - (int)strlen(_("FREE (-)"));
109
		         strwidth(_("(=) USED")) - strwidth(_("FREE (-)"));
110 110
		(void)printf("%*s", gap, "");
111 111
		(void)printf("%s", _("FREE (-)"));
112 112
	}
src/platform/services-bsd.c
126 126
				fmi->fsname = g_unknown_str;
127 127
			if ((fmi->mntdir = strdup(entbuf->f_mntonname)) == NULL)
128 128
				fmi->mntdir = g_unknown_str;
129
			if ((fmi->fstype = strdup(entbuf->f_fstypename)) == NULL)
130
				fmi->fstype = g_unknown_str;
129 131
		} else {
130
			if ((fmi->fsname = strdup(shortenstr(entbuf->f_mntfromname,
131
					       STRMAXLEN))) == NULL)
132
			if ((fmi->fsname = strdup(shortenstr(
133
				entbuf->f_mntfromname, STRMAXCOLS))) == NULL)
132 134
				fmi->fsname = g_unknown_str;
133
			if ((fmi->mntdir = strdup(shortenstr(entbuf->f_mntonname,
134
					    STRMAXLEN))) == NULL)
135
			if ((fmi->mntdir = strdup(shortenstr(
136
				entbuf->f_mntonname, STRMAXCOLS))) == NULL)
135 137
				fmi->mntdir = g_unknown_str;
136
		}
137
		if ((fmi->fstype = strdup(shortenstr(entbuf->f_fstypename,
138
				     STRMAXLEN))) == NULL)
138
			if ((fmi->fstype = strdup(shortenstr(
139
				entbuf->f_fstypename, STRMAXCOLS))) == NULL)
139 140
			fmi->fstype = g_unknown_str;
141
		}
140 142

  
141 143
		/* infos from statvfs */
142 144
		fmi->flags    = GET_FLAGS(vfsbuf);
src/platform/services-linux.c
113 113
		if (Wflag) { /* Wflag to avoid name truncation */
114 114
			if ((fmi->fsname = strdup(entbuf->mnt_fsname))
115 115
					== NULL) {
116
				/* g_unknown_str is def. in extern.h(.in) */
117 116
				fmi->fsname = g_unknown_str;
118 117
			}
119 118
			if ((fmi->mntdir = strdup(entbuf->mnt_dir))
120 119
					== NULL) {
121 120
				fmi->mntdir = g_unknown_str;
122 121
			}
122
			if ((fmi->fstype = strdup(entbuf->mnt_type)) == NULL) {
123
				fmi->fstype = g_unknown_str;
124
			}
123 125
		} else {
124 126
			if ((fmi->fsname = strdup(shortenstr(
125
				entbuf->mnt_fsname,
126
				STRMAXLEN))) == NULL) {
127
				entbuf->mnt_fsname, STRMAXCOLS))) == NULL) {
127 128
				fmi->fsname = g_unknown_str;
128 129
			}
129
			if ((fmi->mntdir = strdup(shortenstr(entbuf->mnt_dir,
130
						STRMAXLEN))) == NULL) {
130
			if ((fmi->mntdir = strdup(shortenstr(
131
				entbuf->mnt_dir, STRMAXCOLS))) == NULL) {
131 132
				fmi->mntdir = g_unknown_str;
132 133
			}
134
			if ((fmi->fstype = strdup(shortenstr(
135
				entbuf->mnt_type, STRMAXCOLS))) == NULL) {
136
				fmi->fstype = g_unknown_str;
137
			}
133 138
		}
134
		if ((fmi->fstype = strdup(shortenstr(entbuf->mnt_type,
135
						12))) == NULL) {
136
			fmi->fstype = g_unknown_str;
137
		}
139

  
138 140
		if ((fmi->mntopts = strdup(entbuf->mnt_opts)) == NULL) {
139 141
			fmi->mntopts = g_none_str;
140 142
		}
src/platform/services-solaris.c
112 112
			continue;
113 113
		}
114 114
		if (Wflag) { /* Wflag to avoid name truncation */
115
			if ((fmi->fsname = strdup(mnttabbuf.mnt_special)) == NULL) {
115
			if ((fmi->fsname = strdup(mnttabbuf.mnt_special)) == NULL)
116 116
				fmi->fsname = g_unknown_str;
117
			}
118
			if ((fmi->mntdir = strdup(mnttabbuf.mnt_mountp))== NULL) {
117
			if ((fmi->mntdir = strdup(mnttabbuf.mnt_mountp))== NULL)
119 118
				fmi->mntdir = g_unknown_str;
120
			}
119
			if ((fmi->fstype = strdup(mnttabbuf.mnt_fstype)) == NULL)
120
				fmi->fstype = g_unknown_str;
121 121
		} else {
122 122
			if ((fmi->fsname = strdup(shortenstr(
123
				mnttabbuf.mnt_special,
124
				STRMAXLEN))) == NULL) {
123
				mnttabbuf.mnt_special, STRMAXCOLS))) == NULL) {
125 124
				fmi->fsname = g_unknown_str;
126 125
			}
127
			if ((fmi->mntdir = strdup(shortenstr(mnttabbuf.mnt_mountp,
128
						STRMAXLEN))) == NULL) {
126
			if ((fmi->mntdir = strdup(shortenstr(
127
				mnttabbuf.mnt_mountp, STRMAXCOLS))) == NULL) {
129 128
				fmi->mntdir = g_unknown_str;
130 129
			}
130
			if ((fmi->fstype = strdup(shortenstr(
131
				mnttabbuf.mnt_fstype, STRMAXCOLS))) == NULL) {
132
				fmi->fstype = g_unknown_str;
133
			}
131 134
		}
132
		if ((fmi->fstype = strdup(shortenstr(mnttabbuf.mnt_fstype,
133
						12))) == NULL) {
134
			fmi->fstype = g_unknown_str;
135
		}
135

  
136 136
		if ((fmi->mntopts = strdup(mnttabbuf.mnt_mntopts)) == NULL) {
137 137
			fmi->mntopts = g_none_str;
138 138
		}
src/platform/services.h
38 38
 */
39 39
#include "list.h"
40 40

  
41
#define STRMAXLEN 24
41
/*
42
 * Maximum number of columns to display a string untruncated
43
 */
44
#define STRMAXCOLS 24
42 45

  
43 46
/*
44 47
 * Return 1 if the current fs should usually be ignored, 0 otherwise.
src/util.c
44 44
#include <time.h>
45 45
#include <sys/ioctl.h>
46 46
#include <math.h>
47
#include <wchar.h>
47 48

  
48 49
#if defined(__sun)
49 50
#include <termios.h> /* on solaris, this is where struct winsize is declared */
......
120 121
char *
121 122
shortenstr(char *str, int len)
122 123
{
123
	int slen = (int)strlen(str);
124
	int slen = strwidth(str);
124 125

  
125 126
	if (slen < len + 1)
126 127
		return str;
......
175 176
}
176 177

  
177 178
/*
179
 * Given a string, return the number of columns needed to display it on a
180
 * terminal. If an error occurs, this function fallbacks to using strlen.
181
 */
182
int
183
strwidth(const char *str)
184
{
185
	int ncols;
186
	size_t nwchars;
187
	wchar_t *wcs;
188

  
189
	if ((nwchars = mbstowcs(NULL, str, 0)) == (size_t)-1)
190
		return (int)strlen(str);
191
	nwchars++; // terminating null wide character
192

  
193
	if ((wcs = calloc(nwchars, sizeof(wchar_t))) == NULL)
194
		return (int)strlen(str);
195

  
196
	if (mbstowcs(wcs, str, nwchars) == (size_t)-1) {
197
		free(wcs);
198
		return (int)strlen(str);
199
	}
200

  
201
	ncols = wcswidth(wcs, nwchars);
202

  
203
	free(wcs);
204

  
205
	return ncols;
206
}
207

  
208
/*
178 209
 * convert to human readable format and return the information i to format
179 210
 * correctly the output.
180 211
 * @n: address of the number to convert
......
506 537
	 * init min width to header names and width of the graph bar + 1 to have
507 538
	 * a space between each column.
508 539
	 */
509
	max.fsname	= (int)strlen(_("FILESYSTEM")) + 1;
510
	max.fstype	= Tflag ? (int)strlen(_("TYPE")) + 1 : 0;
540
	max.fsname	= strwidth(_("FILESYSTEM")) + 1;
541
	max.fstype	= Tflag ? strwidth(_("TYPE")) + 1 : 0;
511 542
	max.bar		= bflag ? 0 : wflag ? GRAPHBAR_WIDE : GRAPHBAR_SHORT;
512
	max.perctused	= (int)strlen(_("%USED")) + 1;
513
	max.used	= dflag ? (int)strlen(_("USED")) + 1 : 0;
514
	max.avail	= (int)strlen(_("AVAILABLE")) + 1;
515
	max.total	= (int)strlen(_("TOTAL")) + 1;
516
	max.nbinodes	= iflag ? (int)strlen(_("#INODES")) + 1 : 0;
517
	max.avinodes	= iflag ? (int)strlen(_("AV.INODES")) + 1 : 0;
518
	max.mntdir	= Mflag ? 0 : (int)strlen(_("MOUNTED ON")) + 1;
519
	max.mntopts	= oflag ? (int)strlen(_("MOUNT OPTIONS")) + 1: 0;
543
	max.perctused	= strwidth(_("%USED")) + 1;
544
	max.used	= dflag ? strwidth(_("USED")) + 1 : 0;
545
	max.avail	= strwidth(_("AVAILABLE")) + 1;
546
	max.total	= strwidth(_("TOTAL")) + 1;
547
	max.nbinodes	= iflag ? strwidth(_("#INODES")) + 1 : 0;
548
	max.avinodes	= iflag ? strwidth(_("AV.INODES")) + 1 : 0;
549
	max.mntdir	= Mflag ? 0 : strwidth(_("MOUNTED ON")) + 1;
550
	max.mntopts	= oflag ? strwidth(_("MOUNT OPTIONS")) + 1: 0;
520 551
}
521 552

  
522 553
/*
......
580 611
		return;
581 612

  
582 613
	/* + 1 for a space between each column */
583
	max.fsname = imax((int)strlen(fmi->fsname) + 1, max.fsname);
584
	max.fstype = imax((int)strlen(fmi->fstype) + 1, max.fstype);
614
	max.fsname = imax(strwidth(fmi->fsname) + 1, max.fsname);
615
	max.fstype = imax(strwidth(fmi->fstype) + 1, max.fstype);
585 616

  
586 617
	if (!Mflag)
587
		max.mntdir = imax((int)strlen(fmi->mntdir) + 1, max.mntdir);
618
		max.mntdir = imax(strwidth(fmi->mntdir) + 1, max.mntdir);
588 619

  
589 620
	if (oflag)
590
		max.mntopts = imax((int)strlen(fmi->mntopts) + 1, max.mntopts);
621
		max.mntopts = imax(strwidth(fmi->mntopts) + 1, max.mntopts);
591 622

  
592 623
	if (dflag)
593 624
		max.used = imax(get_req_width(fmi->used), max.used);
src/util.h
47 47
char * strtrim(char *str);
48 48
char * shortenstr(char *str, int len);
49 49
char * sanitizestr(const char *str);
50
int strwidth(const char *str);
50 51
int humanize(double *n);
51 52
int humanize_i(uint64_t *n);
52 53
void print_unit(int i, int mode);
    (1-1/1)