pmap: wield my machete, achieve width-wise nls support

The existing gettext nls support in pmap exposed users
to some potentially ugly misalignments should the text
that's used in headers someday actually be translated.

The length issue had been addressed already for -X/-XX
modes, but the column headers weren't nls translatable
as yet. This commit makes any header (not literally in
/proc/#/smaps) nls aware. It provides translated width
protection to all modes except one that's header-less!

As part of this effort, the occasional two spaces that
preceeded the Mapping column have been reduced to one.

Reference(s):
       new usage & fix coding style
commit d50884788d
       improve translations
commit 0022b6ec5d
       add gettext support
commit d59cf08c9d

Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
Jim Warner 2013-03-16 00:00:00 -05:00 committed by Jaromir Capik
parent 3262143a29
commit 0c0c543466

220
pmap.c
View File

@ -39,6 +39,53 @@
#include "proc/readproc.h" #include "proc/readproc.h"
#include "proc/version.h" #include "proc/version.h"
const char *nls_Address,
*nls_Offset,
*nls_Device,
*nls_Mapping,
*nls_Flags,
*nls_Inode,
*nls_Kbytes,
*nls_Mode,
*nls_RSS,
*nls_Dirty;
static void nls_initialize(void)
{
setlocale (LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
/* these are the headings shared across all options,
though their widths when output might differ */
nls_Address = _("Address");
nls_Offset = _("Offset");
nls_Device = _("Device");
nls_Mapping = _("Mapping");
/* these headings are used only by the -X/-XX options,
and are not derived literally from /proc/#/smaps */
nls_Flags = _("Flags");
nls_Inode = _("Inode");
/* these are potentially used for options other than -X/-XX, */
nls_Kbytes = _("Kbytes");
nls_Mode = _("Mode");
nls_RSS = _("RSS");
nls_Dirty = _("Dirty");
}
static int justify_print(const char *str, int width, int right)
{
if (width < 1)
puts(str);
else {
int len = strlen(str);
if (width < len) width = len;
printf(right ? "%*.*s " : "%-*.*s ", width, width, str);
}
return width;
}
static int integer_width(unsigned KLONG number) static int integer_width(unsigned KLONG number)
{ {
@ -220,7 +267,7 @@ struct cnf_listnode {
static struct cnf_listnode *cnf_listhead=NULL, *cnf_listnode; static struct cnf_listnode *cnf_listhead=NULL, *cnf_listnode;
static int is_unimportant (char *s) static int is_unimportant (const char *s)
{ {
if (strcmp(s, "AnonHugePages") == 0) return 1; if (strcmp(s, "AnonHugePages") == 0) return 1;
if (strcmp(s, "KernelPageSize") == 0) return 1; if (strcmp(s, "KernelPageSize") == 0) return 1;
@ -234,7 +281,7 @@ static int is_unimportant (char *s)
} }
/* check, whether we want to display the field or not */ /* check, whether we want to display the field or not */
static int is_enabled (char *s) static int is_enabled (const char *s)
{ {
if (X_option == 1) return !is_unimportant(s); if (X_option == 1) return !is_unimportant(s);
@ -263,14 +310,6 @@ static void print_extended_maps (FILE *f)
unsigned KLONG value; unsigned KLONG value;
char *ret, *map_basename, c, has_vmflags = 0; char *ret, *map_basename, c, has_vmflags = 0;
/* initial widths */
maxw1 = strlen("Address");
maxw2 = strlen("Flags" );
maxw3 = strlen("Offset" );
maxw4 = strlen("Device" );
maxw5 = strlen("Inode" );
maxwv = strlen("VmFlags");
ret = fgets(mapbuf, sizeof mapbuf, f); ret = fgets(mapbuf, sizeof mapbuf, f);
firstmapping = 2; firstmapping = 2;
while (ret != NULL) { while (ret != NULL) {
@ -368,45 +407,45 @@ loop_end:
/* Print header */ /* Print header */
if (firstmapping && !q_option) { if (firstmapping && !q_option) {
printf("%*s", maxw1, "Address"); /* Address field always enabled */ maxw1 = justify_print(nls_Address, maxw1, 1);
if (is_enabled("Flags")) if (is_enabled(nls_Flags))
printf(" %*s", maxw2, "Flags"); maxw2 = justify_print(nls_Flags, maxw2, 1);
if (is_enabled("Offset")) if (is_enabled(nls_Offset))
printf(" %*s", maxw3, "Offset"); maxw3 = justify_print(nls_Offset, maxw3, 1);
if (is_enabled("Device")) if (is_enabled(nls_Device))
printf(" %*s", maxw4, "Device"); maxw4 = justify_print(nls_Device, maxw4, 1);
if (is_enabled("Inode")) if (is_enabled(nls_Inode))
printf(" %*s", maxw5, "Inode"); maxw5 = justify_print(nls_Inode, maxw5, 1);
for (listnode=listhead; listnode!=NULL; listnode=listnode->next) for (listnode=listhead; listnode!=NULL; listnode=listnode->next)
printf(" %*s", listnode->max_width, listnode->description); justify_print(listnode->description, listnode->max_width, 1);
if (has_vmflags && is_enabled("VmFlags")) if (has_vmflags && is_enabled("VmFlags"))
printf(" %*s", maxwv, "VmFlags"); printf(" %*s", maxwv, "VmFlags");
if (is_enabled("Mapping")) if (is_enabled(nls_Mapping))
printf(" %s", "Mapping"); justify_print(nls_Mapping, 0, 0);
else
printf("\n"); printf("\n");
} }
/* Print data */ /* Print data */
printf("%*s", maxw1, start); /* Address field is always enabled */ printf("%*s", maxw1, start); /* Address field is always enabled */
if (is_enabled("Flags")) if (is_enabled(nls_Flags))
printf(" %*s", maxw2, flags); printf(" %*s", maxw2, flags);
if (is_enabled("Offset")) if (is_enabled(nls_Offset))
printf(" %*s", maxw3, offset); printf(" %*s", maxw3, offset);
if (is_enabled("Device")) if (is_enabled(nls_Device))
printf(" %*s", maxw4, dev); printf(" %*s", maxw4, dev);
if (is_enabled("Inode")) if (is_enabled(nls_Inode))
printf(" %*s", maxw5, inode); printf(" %*s", maxw5, inode);
for (listnode=listhead; listnode!=NULL; listnode=listnode->next) for (listnode=listhead; listnode!=NULL; listnode=listnode->next)
@ -439,10 +478,10 @@ loop_end:
if (!q_option && listhead!=NULL) { /* footer enabled and non-empty */ if (!q_option && listhead!=NULL) { /* footer enabled and non-empty */
footer_gap = maxw1 + 1; /* Address field is always enabled */ footer_gap = maxw1 + 1; /* Address field is always enabled */
if (is_enabled("Flags" )) footer_gap += maxw2 + 1; if (is_enabled(nls_Flags )) footer_gap += maxw2 + 1;
if (is_enabled("Offset")) footer_gap += maxw3 + 1; if (is_enabled(nls_Offset)) footer_gap += maxw3 + 1;
if (is_enabled("Device")) footer_gap += maxw4 + 1; if (is_enabled(nls_Device)) footer_gap += maxw4 + 1;
if (is_enabled("Inode" )) footer_gap += maxw5 + 1; if (is_enabled(nls_Inode )) footer_gap += maxw5 + 1;
for (i=0; i<footer_gap; i++) putc(' ', stdout); for (i=0; i<footer_gap; i++) putc(' ', stdout);
@ -479,6 +518,7 @@ static int one_proc(proc_t * p)
unsigned long long total_rss = 0ull; unsigned long long total_rss = 0ull;
unsigned long long total_private_dirty = 0ull; unsigned long long total_private_dirty = 0ull;
unsigned long long total_shared_dirty = 0ull; unsigned long long total_shared_dirty = 0ull;
int maxw1, maxw2, maxw3, maxw4, maxw5;
/* Overkill, but who knows what is proper? The "w" prog uses /* Overkill, but who knows what is proper? The "w" prog uses
* the tty width to determine this. * the tty width to determine this.
@ -504,25 +544,35 @@ static int one_proc(proc_t * p)
return 0; return 0;
} }
if (!q_option && (x_option | d_option)) {
if (x_option) { if (x_option) {
if (sizeof(KLONG) == 4) maxw1 = 16;
/* Translation Hint: Please keep if (sizeof(KLONG) == 4) maxw1 = 8;
* alignment of the following four maxw2 = maxw3 = maxw4 = 7;
* headers intact. */ maxw5 = 5;
printf if (!q_option) {
(_("Address Kbytes RSS Dirty Mode Mapping\n")); maxw1 = justify_print(nls_Address, maxw1, 0);
else maxw2 = justify_print(nls_Kbytes, maxw2, 1);
printf maxw3 = justify_print(nls_RSS, maxw3, 1);
(_("Address Kbytes RSS Dirty Mode Mapping\n")); maxw4 = justify_print(nls_Dirty, maxw4, 1);
maxw5 = justify_print(nls_Mode, maxw5, 0);
justify_print(nls_Mapping, 0, 0);
} }
}
if (d_option) { if (d_option) {
if (sizeof(KLONG) == 4) maxw1 = 16;
printf if (sizeof(KLONG) == 4) maxw1 = 8;
(_("Address Kbytes Mode Offset Device Mapping\n")); maxw2 = 7;
else maxw3 = 5;
printf maxw4 = 16;
(_("Address Kbytes Mode Offset Device Mapping\n")); maxw5 = 9;
if (!q_option) {
maxw1 = justify_print(nls_Address, maxw1, 0);
maxw2 = justify_print(nls_Kbytes, maxw2, 1);
maxw3 = justify_print(nls_Mode, maxw3, 0);
maxw4 = justify_print(nls_Offset, maxw4, 0);
maxw5 = justify_print(nls_Device, maxw5, 0);
justify_print(nls_Mapping, 0, 0);
} }
} }
@ -559,14 +609,13 @@ static int one_proc(proc_t * p)
} }
if (strncmp("Swap", smap_key, 4) == 0) { if (strncmp("Swap", smap_key, 4) == 0) {
/*doesnt matter as long as last */ /*doesnt matter as long as last */
printf((sizeof(KLONG) == 8) printf("%0*" KLF "x %*lu %*llu %*llu %*s %s\n",
? "%016" KLF maxw1, start,
"x %7lu %7llu %7llu %s %s\n" : maxw2, (unsigned long)(diff >> 10),
"%08lx %7lu %7llu %7llu %s %s\n", maxw3, rss,
start, maxw4, (private_dirty + shared_dirty),
(unsigned long)(diff >> 10), rss, maxw5, flags,
(private_dirty + shared_dirty), cp2);
flags, cp2);
/* reset some counters */ /* reset some counters */
rss = shared_dirty = private_dirty = 0ull; rss = shared_dirty = private_dirty = 0ull;
diff = 0; diff = 0;
@ -623,12 +672,13 @@ static int one_proc(proc_t * p)
const char *cp = const char *cp =
mapping_name(p, start, diff, mapbuf, map_desc_showpath, dev_major, mapping_name(p, start, diff, mapbuf, map_desc_showpath, dev_major,
dev_minor, inode); dev_minor, inode);
printf((sizeof(KLONG) == 8) printf("%0*" KLF "x %*lu %*s %0*llx %*.*s%03x:%05x %s\n",
? "%016" KLF "x %7lu %s %016llx %03x:%05x %s\n" maxw1, start,
: "%08lx %7lu %s %016llx %03x:%05x %s\n", maxw2, (unsigned long)(diff >> 10),
start, maxw3, flags,
(unsigned long)(diff >> 10), maxw4, file_offset,
flags, file_offset, dev_major, dev_minor, cp); (maxw5-9), (maxw5-9), " ", dev_major, dev_minor,
cp);
} }
if (!x_option && !d_option) { if (!x_option && !d_option) {
const char *cp = const char *cp =
@ -644,27 +694,23 @@ static int one_proc(proc_t * p)
fclose(fp); fclose(fp);
if (!q_option) { if (!q_option) {
if (x_option) { if (x_option) {
if (sizeof(KLONG) == 8) { if (sizeof(KLONG) == 4)
printf justify_print("--------", maxw1, 0);
("---------------- ------ ------ ------\n"); else
printf(_("total kB %15ld %7llu %7llu\n"), justify_print("----------------", maxw1, 0);
(total_shared + total_private_writeable + justify_print("-------", maxw2, 1);
total_private_readonly) >> 10, justify_print("-------", maxw3, 1);
total_rss, justify_print("-------", maxw4, 1);
(total_shared_dirty + printf("\n");
total_private_dirty)
); printf("%-*s ", maxw1, _("total kB"));
} else { printf("%*ld %*llu %*llu\n",
printf maxw2, (total_shared +
("-------- ------- ------- ------- -------\n"); total_private_writeable +
printf
(_("total kB %7ld %7llu %7llu -\n"),
(total_shared + total_private_writeable +
total_private_readonly) >> 10, total_private_readonly) >> 10,
total_rss, (total_shared_dirty+total_private_dirty)); maxw3, total_rss,
maxw4, (total_shared_dirty +
} total_private_dirty));
} }
if (d_option) { if (d_option) {
printf printf
@ -874,10 +920,10 @@ static int config_create (char *rc_filename)
fprintf(f,"\n"); fprintf(f,"\n");
fprintf(f,"# To enable a field uncomment its entry\n"); fprintf(f,"# To enable a field uncomment its entry\n");
fprintf(f,"\n"); fprintf(f,"\n");
fprintf(f,"#Flags\n"); fprintf(f,"#%s\n", nls_Flags);
fprintf(f,"#Offset\n"); fprintf(f,"#%s\n", nls_Offset);
fprintf(f,"#Device\n"); fprintf(f,"#%s\n", nls_Device);
fprintf(f,"#Inode\n"); fprintf(f,"#%s\n", nls_Inode);
fprintf(f,"#Size\n"); fprintf(f,"#Size\n");
fprintf(f,"#Rss\n"); fprintf(f,"#Rss\n");
fprintf(f,"#Pss\n"); fprintf(f,"#Pss\n");
@ -893,7 +939,7 @@ static int config_create (char *rc_filename)
fprintf(f,"#MMUPageSize\n"); fprintf(f,"#MMUPageSize\n");
fprintf(f,"#Locked\n"); fprintf(f,"#Locked\n");
fprintf(f,"#VmFlags\n"); fprintf(f,"#VmFlags\n");
fprintf(f,"#Mapping\n"); fprintf(f,"#%s\n", nls_Mapping);
fprintf(f,"\n"); fprintf(f,"\n");
fprintf(f,"\n"); fprintf(f,"\n");
fprintf(f,"[Mapping]\n"); fprintf(f,"[Mapping]\n");
@ -960,9 +1006,7 @@ int main(int argc, char **argv)
}; };
program_invocation_name = program_invocation_short_name; program_invocation_name = program_invocation_short_name;
setlocale (LC_ALL, ""); nls_initialize();
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
atexit(close_stdout); atexit(close_stdout);
if (argc < 2) if (argc < 2)