All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [Powertop] [po] Updated zh_CN translation
@ 2018-03-03  2:04 arthur2e5
  0 siblings, 0 replies; 3+ messages in thread
From: arthur2e5 @ 2018-03-03  2:04 UTC (permalink / raw)
  To: powertop

[-- Attachment #1: Type: text/plain, Size: 1039 bytes --]

On 2018-03-02 18:33, Mingcong Bai wrote:
> 
> We are currently attempting on a fix to this issue, and current
> progress may be followed here: https://github.com/AOSC-Dev/powertop/.

Hi folks,

I think I have figured out the fix, but I can't be sure about the 
patches
until Bai does a test compilation given how messy the strlen() calls 
are.
Help yourself with the attachments if you want to see them this early. I 
will
do a more "conventional" email patch-thread after Bai tests it.

Those are fairly mechanical tasks, so take it as whatever license you 
want.
For functions added/rewritten entirely on my own, consider them WTFPL.
Amend the changes as you like.

By the way, please remember to update your LINGUAS file so make knows to
compile and ship the translations. Bai did that in:

1. https://github.com/AOSC-Dev/powertop/commit/ca4b2d9
2. https://github.com/AOSC-Dev/powertop/commit/d9ccc30
3. https://github.com/AOSC-Dev/powertop/commit/9347162 (necessary evil…)

--
Best Regards,
Mingye Wang

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Stop-using-strlen-on-C-strings.patch --]
[-- Type: text/x-diff, Size: 2043 bytes --]

From a1a11bae5240ef9c78ad56d57f6681225c3d4cec Mon Sep 17 00:00:00 2001
From: Mingye Wang <arthur200126@gmail.com>
Date: Fri, 2 Mar 2018 18:40:40 -0500
Subject: [PATCH 1/2] Stop using strlen() on C++ strings

C++'s strings have a quicker length operation. There's no need to
convert those strings to null-terminated C strings and run strlen()
on it.
---
 src/devices/ahci.cpp | 2 +-
 src/display.cpp      | 7 +++----
 src/lib.cpp          | 2 +-
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/devices/ahci.cpp b/src/devices/ahci.cpp
index 2fa2f52..31a42d3 100644
--- a/src/devices/ahci.cpp
+++ b/src/devices/ahci.cpp
@@ -150,7 +150,7 @@ ahci::ahci(char *_name, char *path): device()
 
 	diskname = model_name(path, _name);
 
-	if (strlen(diskname.c_str()) == 0)
+	if (diskname.length() == 0)
 		snprintf(humanname, sizeof(humanname), _("SATA link: %s"), _name);
 	else
 		snprintf(humanname, sizeof(humanname), _("SATA disk: %s"), diskname.c_str());
diff --git a/src/display.cpp b/src/display.cpp
index 10ee48a..8484683 100644
--- a/src/display.cpp
+++ b/src/display.cpp
@@ -98,7 +98,7 @@ void show_tab(unsigned int tab)
 	class tab_window *win;
 	unsigned int i;
 	int tab_pos = 17;
-	const char *c;
+	string& s = bottom_lines[tab_names[tab]];
 
 	if (!display)
 		return;
@@ -123,9 +123,8 @@ void show_tab(unsigned int tab)
 	wattrset(bottom_line, A_REVERSE);
 	mvwprintw(bottom_line, 0,0, "%120s", "");
 
-	c = bottom_lines[tab_names[tab]].c_str();
-	if (c && strlen(c) > 0)
-		mvwprintw(bottom_line, 0,0, c);
+	if (s.length() > 0)
+		mvwprintw(bottom_line, 0,0, s.c_str());
 	else
 		mvwprintw(bottom_line, 0, 0,
 			"<ESC> %s | <TAB> / <Shift + TAB> %s | ", _("Exit"),
diff --git a/src/lib.cpp b/src/lib.cpp
index 5e48f37..b80ad36 100644
--- a/src/lib.cpp
+++ b/src/lib.cpp
@@ -424,7 +424,7 @@ char *pretty_print(const char *str, char *buf, int len)
 
 	p = pretty_prints[str].c_str();
 
-	if (strlen(p) == 0)
+	if (pretty_prints[str].length() == 0)
 		p = str;
 
 	snprintf(buf, len,  "%s", p);
-- 
2.16.1.windows.4


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Align-multi-column-characters-properly.patch --]
[-- Type: text/x-diff, Size: 9540 bytes --]

From 645e5893dea21c78f5ba546a54b9760dd8ebbbf5 Mon Sep 17 00:00:00 2001
From: Mingye Wang <arthur200126@gmail.com>
Date: Fri, 2 Mar 2018 20:39:46 -0500
Subject: [PATCH 2/2] Align multi-column characters properly

Individual characters used in localization may occupy multiple bytes per
character in memory and multiple columns per character on screen. This
commit introduces facilities to do those tasks properly, and corrects
such invocations on translatable strings.

Change breakdown by file:

* lib.{cpp,h}:
	Introduce a measure_string function as a wcswidth() wrapper.
		This function converts a char* to wint_t* and calls
		wcswidth.
	Modify align_string to count columns properly.
	Provide C++ string variants of both functions.
* display.cpp:
	Use measure_string for tab position.
	Measure the printed translation, not the original name.
* cpu:
	Replace expand_string with append_string_expanded_cpp:
		Append char* to the string given,
		calculate the padding needed by measuring the char*,
		and pad the char*.
	Replace calls accordingly.
* devices/device.cpp, tuning/tuning.cpp:
	Replace while loops with align_string.
---
 src/cpu/cpu.cpp        | 60 ++++++++++++++++++++++----------------
 src/devices/device.cpp |  2 +-
 src/display.cpp        |  2 +-
 src/lib.cpp            | 78 +++++++++++++++++++++++++++++++++++++++++++-------
 src/lib.h              |  6 ++++
 src/tuning/tuning.cpp  |  7 ++---
 6 files changed, 115 insertions(+), 40 deletions(-)

diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp
index f3711f5..7ef1abd 100644
--- a/src/cpu/cpu.cpp
+++ b/src/cpu/cpu.cpp
@@ -333,10 +333,17 @@ void end_cpu_measurement(void)
 	perf_events->stop();
 }
 
-static void expand_string(char *string, unsigned int newlen)
+static void append_string_expanded_cpp(string &s, const char* more, unsigned int add_width)
 {
-	while (strlen(string) < newlen)
-		strcat(string, " ");
+	s.append(more);
+
+	int width = measure_string(more);
+	if (width < 0)
+		return;
+
+	int spaces_to_pad = add_width - width;
+	if (spaces_to_pad > 0)
+		s.resize(s.length() + spaces_to_add, ' ');
 }
 
 static int has_state_level(class abstract_cpu *acpu, int state, int line)
@@ -826,11 +833,11 @@ void impl_w_display_cpu_states(int state)
 {
 	WINDOW *win;
 	char buffer[128];
-	char linebuf[1024];
+	string linebuf;
 	unsigned int package, core, cpu;
 	int line, loop, cstates_num, pstates_num;
 	class abstract_cpu *_package, * _core, * _cpu;
-	int ctr = 0;
+	int ctr = 0; // column count
 	unsigned int i;
 
 	cstates_num = get_cstates_num();
@@ -872,32 +879,37 @@ void impl_w_display_cpu_states(int state)
 			for (line = LEVEL_HEADER; line <= loop; line++) {
 				int first = 1;
 				ctr = 0;
-				linebuf[0] = 0;
+				linebuf.resize(0);
 
 				if (!has_state_level(_package, state, line))
 					continue;
 
 				buffer[0] = 0;
 				if (first_pkg == 0) {
-					strcat(linebuf, fill_state_name(_package, state, line, buffer));
-					expand_string(linebuf, ctr + 10);
-					strcat(linebuf, fill_state_line(_package, state, line, buffer));
+					fill_state_name(_package, state, line, buffer);
+					append_string_expanded_cpp(linebuf, buffer, 10);
+
+					/* fortunately, fill_state_line always clears buffer. */
+					fill_state_line(_package, state, line, buffer);
+					append_string_expanded_cpp(linebuf, buffer, 10);
+				} else {
+					linebuf.resize(20, ' ');
 				}
-				ctr += 20;
-				expand_string(linebuf, ctr);
+				ctr = 20;
 
-				strcat(linebuf, "| ");
+				linebuf.append("| ");
 				ctr += strlen("| ");
 
 				if (!_core->can_collapse()) {
 					buffer[0] = 0;
-					strcat(linebuf, fill_state_name(_core, state, line, buffer));
-					expand_string(linebuf, ctr + 10);
-					strcat(linebuf, fill_state_line(_core, state, line, buffer));
-					ctr += 20;
-					expand_string(linebuf, ctr);
+					fill_state_name(_core, state, line, buffer);
+					append_string_expanded_cpp(linebuf, buffer, 10);
+
+					fill_state_line(_core, state, line, buffer);
+					append_string_expanded_cpp(linebuf, buffer, 10);
 
-					strcat(linebuf, "| ");
+					ctr += 12;
+					linebuf.append("| ");
 					ctr += strlen("| ");
 				}
 
@@ -907,19 +919,19 @@ void impl_w_display_cpu_states(int state)
 						continue;
 
 					if (first == 1) {
-						strcat(linebuf, fill_state_name(_cpu, state, line, buffer));
-						expand_string(linebuf, ctr + 10);
+						fill_state_name(_core, state, line, buffer);
+						append_string_expanded_cpp(linebuf, buffer, 12);
 						first = 0;
 						ctr += 12;
 					}
 					buffer[0] = 0;
-					strcat(linebuf, fill_state_line(_cpu, state, line, buffer));
+					fill_state_line(_core, state, line, buffer);
+					append_string_expanded_cpp(linebuf, buffer, 10);
 					ctr += 10;
-					expand_string(linebuf, ctr);
 
 				}
-				strcat(linebuf, "\n");
-				wprintw(win, "%s", linebuf);
+				linebuf.append("\n");
+				wprintw(win, "%s", linebuf.c_str());
 			}
 			wprintw(win, "\n");
 			first_pkg++;
diff --git a/src/devices/device.cpp b/src/devices/device.cpp
index 2245b65..c8f64ec 100644
--- a/src/devices/device.cpp
+++ b/src/devices/device.cpp
@@ -199,7 +199,7 @@ void report_devices(void)
 			else
 				sprintf(util, "%5i%s",  (int)all_devices[i]->utilization(),  all_devices[i]->util_units());
 		}
-		while (strlen(util) < 13) strcat(util, " ");
+		align_string(util, 13, 128);
 
 		P = all_devices[i]->power_usage(&all_results, &all_parameters);
 
diff --git a/src/display.cpp b/src/display.cpp
index 8484683..484f764 100644
--- a/src/display.cpp
+++ b/src/display.cpp
@@ -140,7 +140,7 @@ void show_tab(unsigned int tab)
 				wattrset(tab_bar, A_REVERSE);
 			mvwprintw(tab_bar, 0, tab_pos, " %s ", tab_translations[tab_names[i]].c_str());
 
-			tab_pos += 3 + tab_names[i].length();
+			tab_pos += 3 + measure_string_cpp(tab_translations[tab_names[i]]);
 	}
 
 	wrefresh(tab_bar);
diff --git a/src/lib.cpp b/src/lib.cpp
index b80ad36..d16b1ea 100644
--- a/src/lib.cpp
+++ b/src/lib.cpp
@@ -23,6 +23,7 @@
  *	Arjan van de Ven <arjan@linux.intel.com>
  *	Peter Anvin
  */
+#define _XOPEN_SOURCE
 #include <map>
 #include <string.h>
 #include <iostream>
@@ -262,23 +263,80 @@ string read_sysfs_string(const char *format, const char *param)
 
 void align_string(char *buffer, size_t min_sz, size_t max_sz)
 {
-	size_t sz;
+	int width = measure_string(buffer, max_sz);
+
+	/* This may be incorrect, but remains a reasonable fallback. */
+	if (width < 0) {
+		buffer[min_sz] = 0x00;
+		return;
+	}
+
+	if (width < min_sz) {
+		int chars_to_pad = min_sz - width;
+		int len = strlen(buffer);
+
+		/* Bad input... shrug it off. */
+		if (len > max_sz) {
+			buffer[max_sz] = 0x00;
+			return;
+		}
+
+		/* Compromise to avoid out-of-bound writes */
+		if (chars_to_pad + len > max_sz)
+			chars_to_pad = max_sz - len - 1;
+
+		memset(buffer + len, ' ', chars_to_pad);
+		buffer[len + chars_to_pad] = 0x00;
+	}
+}
+
+void align_string_cpp(string &s, size_t min_sz)
+{
+	int width = measure_string_cpp(buffer);
+	/* This may be incorrect, but remains a reasonable fallback. */
+	if (width < 0) {
+		s.resize(min_sz);
+	}
+
+	if (width < min_sz) {
+		int chars_to_pad = sz - width;
+		s.resize(s.length() + chars_to_pad, ' ');
+	}
+}
+
+int measure_string(const char* cs, size_t len) {
+	wint_t *buf;
+	size_t wlen = 0;
+	int ret = -2; /* wcswidth returns -1 on non-prints, use a different ret for error */
 
 	/** mbsrtowcs() allows NULL dst and zero sz,
 	 * comparing to mbstowcs(), which causes undefined
-	 * behaviour under given circumstances*/
+	 * behaviour under given circumstances
+	 * [citation needed] */
 
 	/* start with mbsrtowcs() local mbstate_t * and
 	 * NULL dst pointer*/
-	sz = mbsrtowcs(NULL, (const char **)&buffer, max_sz, NULL);
-	if (sz == (size_t)-1) {
-		buffer[min_sz] = 0x00;
-		return;
-	}
-	while (sz < min_sz) {
-		strcat(buffer, " ");
-		sz++;
+	mbstate_t state;
+	memset(&state, 0x00, sizeof(state));
+
+	if (!cs)
+		return ret;
+
+	if (len == (size_t)-1)
+		len = strlen(cs);
+
+	buf = malloc(len * sizeof(wint_t));
+	if (!buf)
+		return ret;
+
+	wlen = mbsrtowcs(buf, cs, len, &state);
+	if (wlen == (size_t)-1) {
+		free(buf);
+		return -3; /* align_string should know it */
 	}
+
+	ret = wcswidth(buf, wlen);
+	return ret;
 }
 
 void format_watts(double W, char *buffer, unsigned int len)
diff --git a/src/lib.h b/src/lib.h
index 6d85eb6..ff4833a 100644
--- a/src/lib.h
+++ b/src/lib.h
@@ -88,6 +88,12 @@ extern int read_msr(int cpu, uint64_t offset, uint64_t *value);
 extern int write_msr(int cpu, uint64_t offset, uint64_t value);
 
 extern void align_string(char *buffer, size_t min_sz, size_t max_sz);
+extern void align_string_cpp(string &s, size_t min_sz);
+extern int measure_string(const char* cs, size_t len = -1);
+
+inline int measure_string_cpp(const string& s) {
+	return measure_string(s.c_str(), s.length());
+}
 
 extern void ui_notify_user_ncurses(const char *frmt, ...);
 extern void ui_notify_user_console(const char *frmt, ...);
diff --git a/src/tuning/tuning.cpp b/src/tuning/tuning.cpp
index 005bb4b..bf344a2 100644
--- a/src/tuning/tuning.cpp
+++ b/src/tuning/tuning.cpp
@@ -115,11 +115,10 @@ static void __tuning_update_display(int cursor_pos)
 		char desc[4096];
 		pt_strcpy(res, all_tunables[i]->result_string());
 		pt_strcpy(desc, all_tunables[i]->description());
-		while (strlen(res) < 12)
-			strcat(res, " ");
 
-		while (strlen(desc) < 103)
-			strcat(desc, " ");
+		align_string(res, 12, 128);
+		align_string(desc, 103, 128);
+
 		if ((int)i != cursor_pos) {
 			wattrset(win, A_NORMAL);
 			wprintw(win, "   ");
-- 
2.16.1.windows.4


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [Powertop] [po] Updated zh_CN translation
@ 2018-03-03  8:14 Mingcong Bai
  0 siblings, 0 replies; 3+ messages in thread
From: Mingcong Bai @ 2018-03-03  8:14 UTC (permalink / raw)
  To: powertop

[-- Attachment #1: Type: text/plain, Size: 1316 bytes --]

Updated Mingye Wang's patches to fix build - PowerTOP has been built and 
tested and columns are now aligned correctly when using zh_CN.

Best Regards,
Mingcong Bai


在 2018年03月02日 20:04, arthur2e5(a)aosc.io 写道:
> On 2018-03-02 18:33, Mingcong Bai wrote:
>>
>> We are currently attempting on a fix to this issue, and current
>> progress may be followed here: https://github.com/AOSC-Dev/powertop/.
>
> Hi folks,
>
> I think I have figured out the fix, but I can't be sure about the patches
> until Bai does a test compilation given how messy the strlen() calls are.
> Help yourself with the attachments if you want to see them this early. 
> I will
> do a more "conventional" email patch-thread after Bai tests it.
>
> Those are fairly mechanical tasks, so take it as whatever license you 
> want.
> For functions added/rewritten entirely on my own, consider them WTFPL.
> Amend the changes as you like.
>
> By the way, please remember to update your LINGUAS file so make knows to
> compile and ship the translations. Bai did that in:
>
> 1. https://github.com/AOSC-Dev/powertop/commit/ca4b2d9
> 2. https://github.com/AOSC-Dev/powertop/commit/d9ccc30
> 3. https://github.com/AOSC-Dev/powertop/commit/9347162 (necessary evil…)
>
> -- 
> Best Regards,
> Mingye Wang


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Stop-using-strlen-on-C-strings.patch --]
[-- Type: text/x-patch, Size: 2034 bytes --]

>From a1a11bae5240ef9c78ad56d57f6681225c3d4cec Mon Sep 17 00:00:00 2001
From: Mingye Wang <arthur200126@gmail.com>
Date: Fri, 2 Mar 2018 18:40:40 -0500
Subject: [PATCH 1/2] Stop using strlen() on C++ strings

C++'s strings have a quicker length operation. There's no need to
convert those strings to null-terminated C strings and run strlen()
on it.
---
 src/devices/ahci.cpp | 2 +-
 src/display.cpp      | 7 +++----
 src/lib.cpp          | 2 +-
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/devices/ahci.cpp b/src/devices/ahci.cpp
index 2fa2f52..31a42d3 100644
--- a/src/devices/ahci.cpp
+++ b/src/devices/ahci.cpp
@@ -150,7 +150,7 @@ ahci::ahci(char *_name, char *path): device()
 
 	diskname = model_name(path, _name);
 
-	if (strlen(diskname.c_str()) == 0)
+	if (diskname.length() == 0)
 		snprintf(humanname, sizeof(humanname), _("SATA link: %s"), _name);
 	else
 		snprintf(humanname, sizeof(humanname), _("SATA disk: %s"), diskname.c_str());
diff --git a/src/display.cpp b/src/display.cpp
index 10ee48a..8484683 100644
--- a/src/display.cpp
+++ b/src/display.cpp
@@ -98,7 +98,7 @@ void show_tab(unsigned int tab)
 	class tab_window *win;
 	unsigned int i;
 	int tab_pos = 17;
-	const char *c;
+	string& s = bottom_lines[tab_names[tab]];
 
 	if (!display)
 		return;
@@ -123,9 +123,8 @@ void show_tab(unsigned int tab)
 	wattrset(bottom_line, A_REVERSE);
 	mvwprintw(bottom_line, 0,0, "%120s", "");
 
-	c = bottom_lines[tab_names[tab]].c_str();
-	if (c && strlen(c) > 0)
-		mvwprintw(bottom_line, 0,0, c);
+	if (s.length() > 0)
+		mvwprintw(bottom_line, 0,0, s.c_str());
 	else
 		mvwprintw(bottom_line, 0, 0,
 			"<ESC> %s | <TAB> / <Shift + TAB> %s | ", _("Exit"),
diff --git a/src/lib.cpp b/src/lib.cpp
index 5e48f37..b80ad36 100644
--- a/src/lib.cpp
+++ b/src/lib.cpp
@@ -424,7 +424,7 @@ char *pretty_print(const char *str, char *buf, int len)
 
 	p = pretty_prints[str].c_str();
 
-	if (strlen(p) == 0)
+	if (pretty_prints[str].length() == 0)
 		p = str;
 
 	snprintf(buf, len,  "%s", p);
-- 
2.15.1


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Align-multi-column-characters-properly.patch --]
[-- Type: text/x-patch, Size: 9549 bytes --]

>From c55334d2e7dfe53c86af4d2dca4fc67e667b0a0b Mon Sep 17 00:00:00 2001
From: Mingye Wang <arthur200126@gmail.com>
Date: Fri, 2 Mar 2018 20:39:46 -0500
Subject: [PATCH 2/2] Align multi-column characters properly

Individual characters used in localization may occupy multiple bytes per
character in memory and multiple columns per character on screen. This
commit introduces facilities to do those tasks properly, and corrects
such invocations on translatable strings.

Change breakdown by file:

* lib.{cpp,h}:
	Introduce a measure_string function as a wcswidth() wrapper.
		This function converts a char* to wint_t* and calls
		wcswidth.
	Modify align_string to count columns properly.
	Provide C++ string variants of both functions.
* display.cpp:
	Use measure_string for tab position.
	Measure the printed translation, not the original name.
* cpu:
	Replace expand_string with append_string_expanded_cpp:
		Append char* to the string given,
		calculate the padding needed by measuring the char*,
		and pad the char*.
	Replace calls accordingly.
* devices/device.cpp, tuning/tuning.cpp:
	Replace while loops with align_string.
---
 src/cpu/cpu.cpp        | 60 ++++++++++++++++++++++----------------
 src/devices/device.cpp |  2 +-
 src/display.cpp        |  2 +-
 src/lib.cpp            | 78 +++++++++++++++++++++++++++++++++++++++++++-------
 src/lib.h              |  6 ++++
 src/tuning/tuning.cpp  |  7 ++---
 6 files changed, 115 insertions(+), 40 deletions(-)

diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp
index f3711f5..760652b 100644
--- a/src/cpu/cpu.cpp
+++ b/src/cpu/cpu.cpp
@@ -333,10 +333,17 @@ void end_cpu_measurement(void)
 	perf_events->stop();
 }
 
-static void expand_string(char *string, unsigned int newlen)
+static void append_string_expanded_cpp(string &s, const char* more, unsigned int add_width)
 {
-	while (strlen(string) < newlen)
-		strcat(string, " ");
+	s.append(more);
+
+	int width = measure_string(more);
+	if (width < 0)
+		return;
+
+	int spaces_to_pad = add_width - width;
+	if (spaces_to_pad > 0)
+		s.resize(s.length() + spaces_to_pad, ' ');
 }
 
 static int has_state_level(class abstract_cpu *acpu, int state, int line)
@@ -826,11 +833,11 @@ void impl_w_display_cpu_states(int state)
 {
 	WINDOW *win;
 	char buffer[128];
-	char linebuf[1024];
+	string linebuf;
 	unsigned int package, core, cpu;
 	int line, loop, cstates_num, pstates_num;
 	class abstract_cpu *_package, * _core, * _cpu;
-	int ctr = 0;
+	int ctr = 0; // column count
 	unsigned int i;
 
 	cstates_num = get_cstates_num();
@@ -872,32 +879,37 @@ void impl_w_display_cpu_states(int state)
 			for (line = LEVEL_HEADER; line <= loop; line++) {
 				int first = 1;
 				ctr = 0;
-				linebuf[0] = 0;
+				linebuf.resize(0);
 
 				if (!has_state_level(_package, state, line))
 					continue;
 
 				buffer[0] = 0;
 				if (first_pkg == 0) {
-					strcat(linebuf, fill_state_name(_package, state, line, buffer));
-					expand_string(linebuf, ctr + 10);
-					strcat(linebuf, fill_state_line(_package, state, line, buffer));
+					fill_state_name(_package, state, line, buffer);
+					append_string_expanded_cpp(linebuf, buffer, 10);
+
+					/* fortunately, fill_state_line always clears buffer. */
+					fill_state_line(_package, state, line, buffer);
+					append_string_expanded_cpp(linebuf, buffer, 10);
+				} else {
+					linebuf.resize(20, ' ');
 				}
-				ctr += 20;
-				expand_string(linebuf, ctr);
+				ctr = 20;
 
-				strcat(linebuf, "| ");
+				linebuf.append("| ");
 				ctr += strlen("| ");
 
 				if (!_core->can_collapse()) {
 					buffer[0] = 0;
-					strcat(linebuf, fill_state_name(_core, state, line, buffer));
-					expand_string(linebuf, ctr + 10);
-					strcat(linebuf, fill_state_line(_core, state, line, buffer));
-					ctr += 20;
-					expand_string(linebuf, ctr);
+					fill_state_name(_core, state, line, buffer);
+					append_string_expanded_cpp(linebuf, buffer, 10);
+
+					fill_state_line(_core, state, line, buffer);
+					append_string_expanded_cpp(linebuf, buffer, 10);
 
-					strcat(linebuf, "| ");
+					ctr += 12;
+					linebuf.append("| ");
 					ctr += strlen("| ");
 				}
 
@@ -907,19 +919,19 @@ void impl_w_display_cpu_states(int state)
 						continue;
 
 					if (first == 1) {
-						strcat(linebuf, fill_state_name(_cpu, state, line, buffer));
-						expand_string(linebuf, ctr + 10);
+						fill_state_name(_core, state, line, buffer);
+						append_string_expanded_cpp(linebuf, buffer, 12);
 						first = 0;
 						ctr += 12;
 					}
 					buffer[0] = 0;
-					strcat(linebuf, fill_state_line(_cpu, state, line, buffer));
+					fill_state_line(_core, state, line, buffer);
+					append_string_expanded_cpp(linebuf, buffer, 10);
 					ctr += 10;
-					expand_string(linebuf, ctr);
 
 				}
-				strcat(linebuf, "\n");
-				wprintw(win, "%s", linebuf);
+				linebuf.append("\n");
+				wprintw(win, "%s", linebuf.c_str());
 			}
 			wprintw(win, "\n");
 			first_pkg++;
diff --git a/src/devices/device.cpp b/src/devices/device.cpp
index 2245b65..c8f64ec 100644
--- a/src/devices/device.cpp
+++ b/src/devices/device.cpp
@@ -199,7 +199,7 @@ void report_devices(void)
 			else
 				sprintf(util, "%5i%s",  (int)all_devices[i]->utilization(),  all_devices[i]->util_units());
 		}
-		while (strlen(util) < 13) strcat(util, " ");
+		align_string(util, 13, 128);
 
 		P = all_devices[i]->power_usage(&all_results, &all_parameters);
 
diff --git a/src/display.cpp b/src/display.cpp
index 8484683..484f764 100644
--- a/src/display.cpp
+++ b/src/display.cpp
@@ -140,7 +140,7 @@ void show_tab(unsigned int tab)
 				wattrset(tab_bar, A_REVERSE);
 			mvwprintw(tab_bar, 0, tab_pos, " %s ", tab_translations[tab_names[i]].c_str());
 
-			tab_pos += 3 + tab_names[i].length();
+			tab_pos += 3 + measure_string_cpp(tab_translations[tab_names[i]]);
 	}
 
 	wrefresh(tab_bar);
diff --git a/src/lib.cpp b/src/lib.cpp
index b80ad36..0ac5315 100644
--- a/src/lib.cpp
+++ b/src/lib.cpp
@@ -23,6 +23,7 @@
  *	Arjan van de Ven <arjan@linux.intel.com>
  *	Peter Anvin
  */
+#define _XOPEN_SOURCE
 #include <map>
 #include <string.h>
 #include <iostream>
@@ -262,23 +263,80 @@ string read_sysfs_string(const char *format, const char *param)
 
 void align_string(char *buffer, size_t min_sz, size_t max_sz)
 {
-	size_t sz;
+	int width = measure_string(buffer, max_sz);
+
+	/* This may be incorrect, but remains a reasonable fallback. */
+	if (width < 0) {
+		buffer[min_sz] = 0x00;
+		return;
+	}
+
+	if (width < min_sz) {
+		int chars_to_pad = min_sz - width;
+		int len = strlen(buffer);
+
+		/* Bad input... shrug it off. */
+		if (len > max_sz) {
+			buffer[max_sz] = 0x00;
+			return;
+		}
+
+		/* Compromise to avoid out-of-bound writes */
+		if (chars_to_pad + len + 1 > max_sz)
+			chars_to_pad = max_sz - len - 1;
+
+		memset(buffer + len, ' ', chars_to_pad);
+		buffer[len + chars_to_pad] = 0x00;
+	}
+}
+
+void align_string_cpp(string &s, size_t min_sz)
+{
+	int width = measure_string_cpp(s);
+	/* This may be incorrect, but remains a reasonable fallback. */
+	if (width < 0) {
+		s.resize(min_sz);
+	}
+
+	if (width < min_sz) {
+		int chars_to_pad = min_sz - width;
+		s.resize(s.length() + chars_to_pad, ' ');
+	}
+}
+
+int measure_string(const char* cs, size_t len) {
+	wchar_t *buf;
+	size_t wlen = 0;
+	int ret = -2; /* wcswidth returns -1 on non-prints, use a different ret for error */
 
 	/** mbsrtowcs() allows NULL dst and zero sz,
 	 * comparing to mbstowcs(), which causes undefined
-	 * behaviour under given circumstances*/
+	 * behaviour under given circumstances
+	 * [citation needed] */
 
 	/* start with mbsrtowcs() local mbstate_t * and
 	 * NULL dst pointer*/
-	sz = mbsrtowcs(NULL, (const char **)&buffer, max_sz, NULL);
-	if (sz == (size_t)-1) {
-		buffer[min_sz] = 0x00;
-		return;
-	}
-	while (sz < min_sz) {
-		strcat(buffer, " ");
-		sz++;
+	mbstate_t state;
+	memset(&state, 0x00, sizeof(state));
+
+	if (!cs)
+		return ret;
+
+	if (len == (size_t)-1)
+		len = strlen(cs);
+
+	buf = (wchar_t*) malloc(len * sizeof(wchar_t));
+	if (!buf)
+		return ret;
+
+	wlen = mbsrtowcs(buf, &cs, len, &state);
+	if (wlen == (size_t)-1) {
+		free(buf);
+		return -3; /* align_string should know it */
 	}
+
+	ret = wcswidth(buf, wlen);
+	return ret;
 }
 
 void format_watts(double W, char *buffer, unsigned int len)
diff --git a/src/lib.h b/src/lib.h
index 6d85eb6..ff4833a 100644
--- a/src/lib.h
+++ b/src/lib.h
@@ -88,6 +88,12 @@ extern int read_msr(int cpu, uint64_t offset, uint64_t *value);
 extern int write_msr(int cpu, uint64_t offset, uint64_t value);
 
 extern void align_string(char *buffer, size_t min_sz, size_t max_sz);
+extern void align_string_cpp(string &s, size_t min_sz);
+extern int measure_string(const char* cs, size_t len = -1);
+
+inline int measure_string_cpp(const string& s) {
+	return measure_string(s.c_str(), s.length());
+}
 
 extern void ui_notify_user_ncurses(const char *frmt, ...);
 extern void ui_notify_user_console(const char *frmt, ...);
diff --git a/src/tuning/tuning.cpp b/src/tuning/tuning.cpp
index 005bb4b..c3afa30 100644
--- a/src/tuning/tuning.cpp
+++ b/src/tuning/tuning.cpp
@@ -115,11 +115,10 @@ static void __tuning_update_display(int cursor_pos)
 		char desc[4096];
 		pt_strcpy(res, all_tunables[i]->result_string());
 		pt_strcpy(desc, all_tunables[i]->description());
-		while (strlen(res) < 12)
-			strcat(res, " ");
 
-		while (strlen(desc) < 103)
-			strcat(desc, " ");
+		align_string(res, 12, 128);
+		align_string(desc, 103, 4096);
+
 		if ((int)i != cursor_pos) {
 			wattrset(win, A_NORMAL);
 			wprintw(win, "   ");
-- 
2.15.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [Powertop] [po] Updated zh_CN translation
@ 2018-03-02 23:33 Mingcong Bai
  0 siblings, 0 replies; 3+ messages in thread
From: Mingcong Bai @ 2018-03-02 23:33 UTC (permalink / raw)
  To: powertop

[-- Attachment #1: Type: text/plain, Size: 1025 bytes --]

Hi,

Attached below is a copy of updated zh_CN translation for PowerTOP 
(master).

This transltion, like every other translation, will mess up the layout 
of tabs because PowerTOP does not count the displayed width of strings 
correctly.

In 
https://github.com/fenrus75/powertop/blob/ea5c678/src/display.cpp#L137-L145, 
PowerTOP renders a tab and decides the position of the next from the 
"width" or the string, but it's neither using the correct string nor 
using the correct calculation for width. Instead of taking the length of 
the rendered translation, PowerTOP uses the length of the original 
English string. Instead of taking a width from 
`wcswidth(tab_translations[tab_names[i]].c_str())`, PowerTOP uses 
`strlen()`, breaking on characters that take multiple (typically two) 
columns on screen like all of CJK and emoji.

We are currently attempting on a fix to this issue, and current progress 
may be followed here: https://github.com/AOSC-Dev/powertop/.

Best Regards
Mingcong Bai


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: zh_CN.po --]
[-- Type: text/x-gettext-translation, Size: 22056 bytes --]

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Intel Corporation
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Tommy He <lovenemesis@gmail.com>, 2012
msgid ""
msgstr ""
"Project-Id-Version: PowerTOP\n"
"Report-Msgid-Bugs-To: \"powertop@lists.01.org\"\n"
"POT-Creation-Date: 2018-03-01 15:10-0600\n"
"PO-Revision-Date: 2018-03-01 21:23-0600\n"
"Last-Translator: Mingcong Bai <jeffbai@aosc.xyz>\n"
"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/PowerTOP/"
"language/zh_CN/)\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 2.0.5\n"

#: src/calibrate/calibrate.cpp:238
#, c-format
msgid "Cannot create temp file\n"
msgstr "无法创建临时文件\n"

#: src/calibrate/calibrate.cpp:258
#, c-format
msgid "Calibrating: CPU usage on %i threads\n"
msgstr "正在校准 %i 线程中的 处理器使用\n"

#: src/calibrate/calibrate.cpp:273
#, c-format
msgid "Calibrating: CPU wakeup power consumption\n"
msgstr "正在校准 处理器唤醒能耗\n"

#: src/calibrate/calibrate.cpp:290
#, c-format
msgid "Calibrating USB devices\n"
msgstr "正在校准 USB 设备\n"

#: src/calibrate/calibrate.cpp:292 src/calibrate/calibrate.cpp:309
#: src/calibrate/calibrate.cpp:317 src/calibrate/calibrate.cpp:334
#, c-format
msgid ".... device %s \n"
msgstr "… 设备 %s \n"

#: src/calibrate/calibrate.cpp:307
#, c-format
msgid "Calibrating radio devices\n"
msgstr "正在校准无线电设备\n"

#: src/calibrate/calibrate.cpp:331
#, c-format
msgid "Calibrating backlight\n"
msgstr "正在校准背光\n"

#: src/calibrate/calibrate.cpp:355 src/calibrate/calibrate.cpp:365
#, c-format
msgid "Calibrating idle\n"
msgstr "正在校准空闲状态\n"

#: src/calibrate/calibrate.cpp:378
#, c-format
msgid "Calibrating: disk usage \n"
msgstr "正在校准磁盘使用\n"

#: src/calibrate/calibrate.cpp:403
msgid "Starting PowerTOP power estimate calibration \n"
msgstr "正在启动 PowerTOP 电量预计校准 \n"

#: src/calibrate/calibrate.cpp:426
msgid "Finishing PowerTOP power estimate calibration \n"
msgstr "正在完成 PowerTOP 电量预计校准 \n"

#: src/calibrate/calibrate.cpp:430
#, c-format
msgid "Parameters after calibration:\n"
msgstr "校准后参数:\n"

#: src/cpu/abstract_cpu.cpp:74
msgid "Idle"
msgstr "空闲"

#: src/cpu/abstract_cpu.cpp:76
msgid "Turbo Mode"
msgstr "睿频模式"

#: src/cpu/cpu_core.cpp:37 src/cpu/cpu_core.cpp:93 src/cpu/intel_cpus.cpp:322
#, c-format
msgid "  Core"
msgstr "  核心"

#: src/cpu/cpu.cpp:81
#, c-format
msgid "cpu package %i"
msgstr "处理器封装 %i"

#: src/cpu/cpu.cpp:82
msgid "cpu package"
msgstr "处理器封装"

#: src/cpu/cpu.cpp:85 src/cpu/cpu.cpp:92
#, c-format
msgid "package-%i"
msgstr "封装 %i"

#: src/cpu/cpu.cpp:86
msgid "cpu rapl package"
msgstr "处理器RAPL 封装"

#: src/cpu/cpu.cpp:93
msgid "dram rapl package"
msgstr "DRAM RAPL 封装"

#: src/cpu/cpu.cpp:458
msgid "Processor Idle State Report"
msgstr "处理器空闲事件报告"

#: src/cpu/cpu.cpp:522 src/cpu/cpu.cpp:740 src/cpu/cpu_package.cpp:47
#, c-format
msgid "Package"
msgstr "封装"

#: src/cpu/cpu.cpp:553 src/cpu/cpu.cpp:762
#, c-format
msgid "Core %d"
msgstr "核心 %d"

#: src/cpu/cpu.cpp:560
#, c-format
msgid "GPU %d"
msgstr "GPU %d"

#: src/cpu/cpu.cpp:581
msgid "CPU"
msgstr "CPU"

#: src/cpu/cpu.cpp:663
msgid "Processor Frequency Report"
msgstr "处理器频率报告"

#: src/cpu/cpu.cpp:783
#, c-format
msgid "CPU %d"
msgstr "CPU %d"

#: src/cpu/cpu.cpp:984
#, c-format
msgid "cpu_idle event returned no state?\n"
msgstr "cpu_idle(空闲)事件没有返回状态?\n"

#: src/cpu/cpu.cpp:999
#, c-format
msgid "power or cpu_frequency event returned no state?\n"
msgstr "power(电源)或 cpu_frequency(频率)事件没有返回状态?\n"

#: src/cpu/cpu_linux.cpp:79
msgid "C0 polling"
msgstr "C0 轮巡"

#: src/cpu/cpu_linux.cpp:242 src/cpu/cpu_linux.cpp:341
#: src/cpu/intel_cpus.cpp:649
#, c-format
msgid " CPU %i"
msgstr " CPU %i"

#: src/cpu/cpu_package.cpp:105 src/cpu/intel_cpus.cpp:410
#, c-format
msgid "  Package"
msgstr "  封装"

#: src/cpu/intel_cpus.cpp:127
#, c-format
msgid "read_msr cpu%d 0x%llx : "
msgstr "read_msr cpu%d 0x%llx:"

#: src/cpu/intel_cpus.cpp:572
msgid "C0 active"
msgstr "C0 已激活 "

#: src/cpu/intel_cpus.cpp:630
#, c-format
msgid "Average"
msgstr "平均值"

#: src/cpu/intel_gpu.cpp:64
#, c-format
msgid "  GPU "
msgstr "  GPU "

#: src/devices/ahci.cpp:154
#, c-format
msgid "SATA link: %s"
msgstr "SATA 链路:%s"

#: src/devices/ahci.cpp:156
#, c-format
msgid "SATA disk: %s"
msgstr "SATA 磁盘:%s"

#: src/devices/ahci.cpp:374
msgid "AHCI ALPM Residency Statistics - Not supported on this macine"
msgstr "AHCI ALPM(高级链路电源管理)常时统计 — 该设备不支持"

#: src/devices/ahci.cpp:389
msgid "Link"
msgstr "链路"

#: src/devices/ahci.cpp:390
msgid "Active"
msgstr "已激活"

#: src/devices/ahci.cpp:391
msgid "Partial"
msgstr "部分"

#: src/devices/ahci.cpp:392
msgid "Slumber"
msgstr "睡眠"

#: src/devices/ahci.cpp:393
msgid "Devslp"
msgstr "Devslp"

#: src/devices/ahci.cpp:399
msgid "AHCI ALPM Residency Statistics"
msgstr "AHCI ALPM(高级链路电源管理)常时统计"

#: src/devices/alsa.cpp:77
#, c-format
msgid "Audio codec %s: %s (%s)"
msgstr "音频设备 %s:%s (%s)"

#: src/devices/alsa.cpp:79 src/devices/alsa.cpp:81
#, c-format
msgid "Audio codec %s: %s"
msgstr "音频设备 %s:%s"

#: src/devices/devfreq.cpp:261
msgid "Device Freq stats"
msgstr "设备频率统计"

#: src/devices/devfreq.cpp:279
msgid " Devfreq is not enabled"
msgstr " 未启用 Devfreq"

#: src/devices/devfreq.cpp:284
msgid " No devfreq devices available"
msgstr " 无可用的 devfreq 设备"

#: src/devices/device.cpp:172 src/process/do_process.cpp:831
#, c-format
msgid "The battery reports a discharge rate of %sW\n"
msgstr "电池报告放电速率为 %sW\n"

#: src/devices/device.cpp:174 src/process/do_process.cpp:833
#, c-format
msgid "The power consumed was %sJ\n"
msgstr "能量使用总量为 %sJ\n"

#: src/devices/device.cpp:180
#, c-format
msgid "System baseline power is estimated at %sW\n"
msgstr "系统基线耗电量为 %sW\n"

#: src/devices/device.cpp:187
msgid "Power est.    Usage     Device name\n"
msgstr "预计电量    用量     设备名\n"

#: src/devices/device.cpp:189
msgid "              Usage     Device name\n"
msgstr "              用量     设备名\n"

#: src/devices/device.cpp:256
msgid "The battery reports a discharge rate of: "
msgstr "电池报告放电速率为:"

#: src/devices/device.cpp:261
msgid "The power consumed was : "
msgstr "已用能量:"

#: src/devices/device.cpp:268
msgid "The system baseline power is estimated at: "
msgstr "估算系统基线耗电量为:"

#: src/devices/device.cpp:277 src/process/do_process.cpp:850
#: src/process/do_process.cpp:852 src/process/do_process.cpp:926
#: src/process/do_process.cpp:1077
msgid "Usage"
msgstr "用量"

#: src/devices/device.cpp:278
msgid "Device Name"
msgstr "设备名称"

#: src/devices/device.cpp:280 src/process/do_process.cpp:935
#: src/process/do_process.cpp:1082
msgid "PW Estimate"
msgstr "电源估算"

#: src/devices/device.cpp:317
msgid "Device Power Report"
msgstr "设备能源报告"

#: src/devices/network.cpp:177
#, c-format
msgid "Network interface: %s (%s)"
msgstr "网络接口:%s (%s)"

#: src/devices/rfkill.cpp:65 src/devices/rfkill.cpp:69
#, c-format
msgid "Radio device: %s"
msgstr "无线设备:%s"

#: src/devices/runtime_pm.cpp:216
#, c-format
msgid "I2C %s (%s): %s"
msgstr "I2C %s (%s):%s"

#: src/devices/runtime_pm.cpp:216 src/tuning/tuningi2c.cpp:57
#: src/tuning/tuningi2c.cpp:59
msgid "Adapter"
msgstr "适配器"

#: src/devices/runtime_pm.cpp:216 src/devlist.cpp:331
#: src/tuning/tuningi2c.cpp:57 src/tuning/tuningi2c.cpp:59
msgid "Device"
msgstr "设备"

#: src/devices/runtime_pm.cpp:241
#, c-format
msgid "PCI Device: %s"
msgstr "PCI 设备:%s"

#: src/devices/usb.cpp:51 src/devices/usb.cpp:96 src/devices/usb.cpp:98
#, c-format
msgid "USB device: %s"
msgstr "USB 设备:%s"

#: src/devices/usb.cpp:94
#, c-format
msgid "USB device: %s (%s)"
msgstr "USB 设备:%s (%s)"

#: src/devlist.cpp:330
msgid "Process"
msgstr "进程"

#: src/devlist.cpp:347
msgid "Process Device Activity"
msgstr "进程设备活动"

#: src/display.cpp:70
msgid "Overview"
msgstr "概览"

#: src/display.cpp:71
msgid "Idle stats"
msgstr "空闲统计"

#: src/display.cpp:72
msgid "Frequency stats"
msgstr "频率统计"

#: src/display.cpp:73
msgid "Device stats"
msgstr "设备统计"

#: src/display.cpp:131
msgid "Exit"
msgstr "退出"

#: src/display.cpp:132
msgid "Navigate"
msgstr "导航"

#: src/lib.cpp:288
#, c-format
msgid "%7sW"
msgstr "%7sW"

#: src/lib.cpp:291
#, c-format
msgid "    0 mW"
msgstr "    0 mW"

#: src/lib.cpp:410
msgid "PS/2 Touchpad / Keyboard / Mouse"
msgstr "PS/2 触摸板 / 键盘 / 鼠标"

#: src/lib.cpp:411
msgid "SATA controller"
msgstr "SATA 控制器"

#: src/lib.cpp:412
msgid "Intel built in USB hub"
msgstr "Intel 内建 USB 集线器"

#: src/lib.cpp:467
#, c-format
msgid "glob returned GLOB_NOSPACE\n"
msgstr "glob 返回 GLOB_NOSPACE\n"

#: src/lib.cpp:471
#, c-format
msgid "glob returned GLOB_ABORTED\n"
msgstr "glob 返回 GLOB_ABORTED\n"

#: src/lib.cpp:475
#, c-format
msgid "glob returned GLOB_NOMATCH\n"
msgstr "glob 返回 GLOB_NOMATCH\n"

#: src/lib.cpp:513 src/lib.cpp:549
#, c-format
msgid ""
"Model-specific registers (MSR)\t\t\t not found (try enabling "
"CONFIG_X86_MSR).\n"
msgstr "特殊模块寄存器 (MSR)\t\t\t未找到(尝试启用 CONFIG_X86_MSR)。\n"

#: src/main.cpp:102
#, c-format
msgid "PowerTOP version "
msgstr "PowerTOP 版本 "

#: src/main.cpp:108
msgid "Set refresh time out"
msgstr "设定刷新延时"

#: src/main.cpp:121
msgid "Usage: powertop [OPTIONS]"
msgstr "用法:powertop [选项]"

#: src/main.cpp:122
msgid "sets all tunable options to their GOOD setting"
msgstr "将所有可调项设置为理想值"

#: src/main.cpp:123
msgid "runs powertop in calibration mode"
msgstr "以校准模式运行 PowerTOP"

#: src/main.cpp:124 src/main.cpp:127
msgid "[=filename]"
msgstr "[=filename]"

#: src/main.cpp:124
msgid "generate a csv report"
msgstr "生成 CSV 报告"

#: src/main.cpp:125
msgid "run in \"debug\" mode"
msgstr "以“除错”模式运行"

#: src/main.cpp:126
msgid "[=devnode]"
msgstr "[=devnode]"

#: src/main.cpp:126
msgid "uses an Extech Power Analyzer for measurements"
msgstr "使用 Extech 电源分析仪进行测量"

#: src/main.cpp:127
msgid "generate a html report"
msgstr "生成 HTML 报告"

#: src/main.cpp:128
msgid "[=iterations] number of times to run each test"
msgstr "[=iterations] 运行每项测试的次数"

#: src/main.cpp:129
msgid "suppress stderr output"
msgstr "阻止 stderr(标准错误)输出"

#: src/main.cpp:130 src/main.cpp:131
msgid "[=seconds]"
msgstr "[=seconds]"

#: src/main.cpp:130
msgid "interval for power consumption measurement"
msgstr "功耗测量时长"

#: src/main.cpp:131
msgid "generate a report for 'x' seconds"
msgstr "生成指定秒数内的报告"

#: src/main.cpp:132
msgid "[=workload]"
msgstr "[=workload]"

#: src/main.cpp:132
msgid "file to execute for workload"
msgstr "要执行的任务文件"

#: src/main.cpp:133
msgid "print version information"
msgstr "显示版本信息"

#: src/main.cpp:134
msgid "print this help menu"
msgstr "显示此帮助菜单"

#: src/main.cpp:136
msgid "For more help please refer to the 'man 8 powertop'"
msgstr "请查阅“man 8 powertop”以获取更多帮助"

#: src/main.cpp:231
#, c-format
msgid "Unknown issue running workload!\n"
msgstr "运行任务时遇到未知问题!\n"

#: src/main.cpp:288
msgid "PowerTOP is out of memory. PowerTOP is Aborting"
msgstr "PowerTOP 内存耗尽。 PowerTOP 正在中止"

#: src/main.cpp:296
#, c-format
msgid "Preparing to take measurements\n"
msgstr "正在准备测量\n"

#: src/main.cpp:301
#, c-format
msgid "Taking %d measurement(s) for a duration of %d second(s) each.\n"
msgstr "正在执行 %d 次测量,每次持续 %d 秒。\n"

#: src/main.cpp:303
#, c-format
msgid "Measuring workload %s.\n"
msgstr "正在测量任务 %s。\n"

#: src/main.cpp:326
#, c-format
msgid "PowerTOP "
msgstr "PowerTOP "

#: src/main.cpp:327 src/main.cpp:377
#, c-format
msgid "exiting...\n"
msgstr "正在退出…\n"

#: src/main.cpp:361
#, c-format
msgid "modprobe cpufreq_stats failed"
msgstr "运行 modprobe cpufreq_stats 命令失败"

#: src/main.cpp:364
#, c-format
msgid "modprobe msr failed"
msgstr "运行 modprobe msr 命令失败"

#: src/main.cpp:376 src/main.cpp:380
#, c-format
msgid "Failed to mount debugfs!\n"
msgstr "挂载 debugfs 失败!\n"

#: src/main.cpp:381
#, c-format
msgid "Should still be able to auto tune...\n"
msgstr "自动调整应当依然可用…\n"

#: src/main.cpp:463
#, c-format
msgid "Invalid CSV filename\n"
msgstr "CSV 文件名无效\n"

#: src/main.cpp:479
#, c-format
msgid "Invalid HTML filename\n"
msgstr "HTML 文件名无效\n"

#: src/main.cpp:488
#, c-format
msgid "Quiet mode failed!\n"
msgstr "静默模式出错!\n"

#: src/main.cpp:555
msgid "Leaving PowerTOP"
msgstr "正在离开 PowerTOP"

#: src/parameters/persistent.cpp:46 src/parameters/persistent.cpp:155
msgid "Cannot save to file"
msgstr "无法保存到文件"

#: src/parameters/persistent.cpp:89 src/parameters/persistent.cpp:180
msgid "Cannot load from file"
msgstr "无法载入文件"

#: src/parameters/persistent.cpp:138
#, c-format
msgid "Loaded %i prior measurements\n"
msgstr "已载入之前 %i 个测量\n"

#: src/parameters/persistent.cpp:181
msgid ""
"File will be loaded after taking minimum number of measurement(s) with "
"battery only \n"
msgstr "仅会在使用电池运行时测量最小次数后载入文件 \n"

#: src/perf/perf.cpp:115
#, c-format
msgid ""
"Too many open files, please increase the limit of open file descriptors.\n"
msgstr "打开了过多文件,请尝试提高打开文件标记的限制。\n"

#: src/perf/perf.cpp:117
#, c-format
msgid "PowerTOP %s needs the kernel to support the 'perf' subsystem\n"
msgstr "PowerTOP %s 需要内核“perf”子系统支持\n"

#: src/perf/perf.cpp:118
#, c-format
msgid "as well as support for trace points in the kernel:\n"
msgstr "以及内核中追溯点支持:\n"

#: src/process/do_process.cpp:819
#, c-format
msgid ""
"Estimated power: %5.1f    Measured power: %5.1f    Sum: %5.1f\n"
"\n"
msgstr ""
"预计耗电量: %5.1f    实测耗电量: %5.1f    总计: %5.1f\n"
"\n"

#: src/process/do_process.cpp:838
#, c-format
msgid "The estimated remaining time is %i hours, %i minutes\n"
msgstr "估计剩余时间 %i 小时 %i 分钟\n"

#: src/process/do_process.cpp:846
msgid "Summary"
msgstr "摘要"

#: src/process/do_process.cpp:846
msgid "wakeups/second"
msgstr "每秒唤醒数"

#: src/process/do_process.cpp:846
msgid "GPU ops/seconds"
msgstr "每秒 GPU 操作数"

#: src/process/do_process.cpp:846
msgid "VFS ops/sec and"
msgstr "每秒 VFS 操作数及"

#: src/process/do_process.cpp:846
msgid "CPU use"
msgstr "处理器占用"

#: src/process/do_process.cpp:850
msgid "Power est."
msgstr "估计电量"

#: src/process/do_process.cpp:850 src/process/do_process.cpp:852
#: src/process/do_process.cpp:1078
msgid "Events/s"
msgstr "每秒事件数"

#: src/process/do_process.cpp:850 src/process/do_process.cpp:852
#: src/process/do_process.cpp:931 src/process/do_process.cpp:1079
msgid "Category"
msgstr "分类"

#: src/process/do_process.cpp:850 src/process/do_process.cpp:852
#: src/process/do_process.cpp:932 src/process/do_process.cpp:1080
#: src/tuning/tuning.cpp:243 src/tuning/tuning.cpp:271
#: src/tuning/tuning.cpp:289
msgid "Description"
msgstr "描述"

#: src/process/do_process.cpp:927
msgid "Wakeups/s"
msgstr "每秒唤醒数"

#: src/process/do_process.cpp:928
msgid "GPU ops/s"
msgstr "每秒 GPU 操作数"

#: src/process/do_process.cpp:929
msgid "Disk IO/s"
msgstr "每秒磁盘 IO 用量"

#: src/process/do_process.cpp:930
msgid "GFX Wakeups/s"
msgstr "每秒 GFX 唤醒数"

#: src/process/do_process.cpp:1017
msgid "Overview of Software Power Consumers"
msgstr "每软件能耗概览"

#: src/process/do_process.cpp:1057
msgid "Target:"
msgstr "目标:"

#: src/process/do_process.cpp:1058
msgid "1 units/s"
msgstr "1 单位/秒"

#: src/process/do_process.cpp:1059
msgid "System: "
msgstr "系统:"

#: src/process/do_process.cpp:1061
msgid " wakeup/s"
msgstr " 唤醒/秒"

#: src/process/do_process.cpp:1062
msgid "CPU: "
msgstr "处理器:"

#: src/process/do_process.cpp:1064
#, c-format
msgid "% usage"
msgstr "%u 用量百分比"

#: src/process/do_process.cpp:1065
msgid "GPU:"
msgstr "GPU:"

#: src/process/do_process.cpp:1067 src/process/do_process.cpp:1073
msgid " ops/s"
msgstr " 操作/秒"

#: src/process/do_process.cpp:1068
msgid "GFX:"
msgstr "GFX:"

#: src/process/do_process.cpp:1070
msgid " wakeups/s"
msgstr " 唤醒/秒"

#: src/process/do_process.cpp:1071
msgid "VFS:"
msgstr "VFS:"

#: src/process/do_process.cpp:1139
msgid "Top 10 Power Consumers"
msgstr "十大耗能项目"

#: src/report/report.cpp:122
msgid "PowerTOP Version"
msgstr "PowerTOP 版本"

#: src/report/report.cpp:131
msgid "Kernel Version"
msgstr "内核版本"

#: src/report/report.cpp:135
msgid "System Name"
msgstr "系统名称"

#: src/report/report.cpp:142
msgid "CPU Information"
msgstr "处理器信息"

#: src/report/report.cpp:154
msgid "OS Information"
msgstr "操作系统信息"

#: src/report/report.cpp:161
msgid "System Information"
msgstr "系统信息"

#: src/report/report.cpp:195
#, c-format
msgid "Cannot open output file %s (%s)\n"
msgstr "无法打开输出文件 %s (%s)\n"

#: src/report/report.cpp:211
#, c-format
msgid "PowerTOP outputting using base filename %s\n"
msgstr "PowerTOP 正在输出到默认文件名 %s\n"

#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50
#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:49
#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45
#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45
msgid "Good"
msgstr "良好"

#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50
#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:50
#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45
#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45
msgid "Bad"
msgstr "欠佳"

#: src/tuning/bluetooth.cpp:46 src/tuning/ethernet.cpp:50
#: src/tuning/runtime.cpp:42 src/tuning/tunable.cpp:51
#: src/tuning/tuningi2c.cpp:35 src/tuning/tuningsysfs.cpp:45
#: src/tuning/tuningusb.cpp:39 src/tuning/wifi.cpp:45
msgid "Unknown"
msgstr "未知"

#: src/tuning/bluetooth.cpp:48
#, c-format
msgid "Bluetooth device interface status"
msgstr "蓝牙设备接口状态"

#: src/tuning/ethernet.cpp:54
#, c-format
msgid "Wake-on-lan status for device %s"
msgstr "设备 %s 的局域网唤醒状态"

#: src/tuning/runtime.cpp:48
#, c-format
msgid "Runtime PM for %s device %s"
msgstr "%s 设备 %s 的运行时电源管理"

#: src/tuning/runtime.cpp:50
#, c-format
msgid "%s device %s has no runtime power management"
msgstr "%s 设备 %s 没有运行时电源管理"

#: src/tuning/runtime.cpp:74
#, c-format
msgid "PCI Device %s has no runtime power management"
msgstr "PCI 设备 %s 没有运行时电源管理"

#: src/tuning/runtime.cpp:76
#, c-format
msgid "Runtime PM for PCI Device %s"
msgstr "PCI 设备 %s 的运行时电源管理"

#: src/tuning/tuning.cpp:62
msgid "Enable Audio codec power management"
msgstr "启用音频设备电源管理"

#: src/tuning/tuning.cpp:63
msgid "NMI watchdog should be turned off"
msgstr "关闭 NMI 监控"

#: src/tuning/tuning.cpp:64
msgid "Power Aware CPU scheduler"
msgstr "支持能源调整的 处理器调度器"

#: src/tuning/tuning.cpp:65
msgid "VM writeback timeout"
msgstr "虚拟内存回写延时"

#: src/tuning/tuning.cpp:82
msgid "Tunables"
msgstr "可调项"

#: src/tuning/tuning.cpp:82
msgid " <ESC> Exit | <Enter> Toggle tunable | <r> Window refresh"
msgstr " <ESC> 退出 | <Enter> 切换可调整项 | <r> 窗口刷新"

#: src/tuning/tuning.cpp:244
msgid "Script"
msgstr "脚本"

#: src/tuning/tuning.cpp:258
msgid "Software Settings in Need of Tuning"
msgstr "软件设置需要调整"

#: src/tuning/tuning.cpp:277
msgid "Untunable Software Issues"
msgstr "无法调整的软件问题"

#: src/tuning/tuning.cpp:301
msgid "Optimal Tuned Software Settings"
msgstr "软件设置已调整为最佳状态"

#: src/tuning/tuningi2c.cpp:57
#, c-format
msgid "Runtime PM for I2C %s %s (%s)"
msgstr "I2C 运行时电源管理 %s %s (%s)"

#: src/tuning/tuningi2c.cpp:59
#, c-format
msgid "I2C %s %s has no runtime power management"
msgstr "I2C %s %s 没有运行时电源管理"

#: src/tuning/tuningsysfs.cpp:123
#, c-format
msgid "Enable SATA link power management for %s"
msgstr "启用 %s 上的 SATA 链路电源管理"

#: src/tuning/tuningusb.cpp:54
#, c-format
msgid "Autosuspend for unknown USB device %s (%s:%s)"
msgstr "自动挂起未知 USB 设备 %s (%s:%s)"

#: src/tuning/tuningusb.cpp:71 src/tuning/tuningusb.cpp:73
#: src/tuning/tuningusb.cpp:75
#, c-format
msgid "Autosuspend for USB device %s [%s]"
msgstr "自动挂起 USB 设备 %s [%s]"

#: src/tuning/wifi.cpp:48
#, c-format
msgid "Wireless Power Saving for interface %s"
msgstr "接口 %s 的无线节电设置"

#~ msgid "cpu rapl package %i"
#~ msgstr "CPU RAPL 封装 %i"

#~ msgid "dram rapl package %i"
#~ msgstr "DRAM RAPL 封装 %i"

#~ msgid "Actual"
#~ msgstr "实际"

#~ msgid "Power Consumption Summary"
#~ msgstr "电量消耗概览"

#~ msgid "GPU ops/second"
#~ msgstr "每秒 GPU 操作数"

#~ msgid "VFS ops/sec"
#~ msgstr "每秒 VFS 操作数"

#~ msgid "GFX wakes/sec and"
#~ msgstr "每秒 GFX 唤醒数和"

#~ msgid "Using 'ondemand' cpufreq governor"
#~ msgstr "使用 'ondemand'(按需调整)CPU 频率控制器"

#~ msgid "[=FILENAME]"
#~ msgstr "[=文件名]"

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-03-03  8:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-03  2:04 [Powertop] [po] Updated zh_CN translation arthur2e5
  -- strict thread matches above, loose matches on Subject: below --
2018-03-03  8:14 Mingcong Bai
2018-03-02 23:33 Mingcong Bai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.