From 0c0c543466e95966851807b54a3830a695cc3032 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Sat, 16 Mar 2013 00:00:00 -0500 Subject: [PATCH] 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 d50884788df5a9706ecba6a0966f48ef8f213f41 improve translations commit 0022b6ec5dacd20d28e511389916cd6d8ff21091 add gettext support commit d59cf08c9dda421114af6d59ef4203d8bb10af3e Signed-off-by: Jim Warner --- pmap.c | 234 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 139 insertions(+), 95 deletions(-) diff --git a/pmap.c b/pmap.c index 0b06cd34..c8ba90fc 100644 --- a/pmap.c +++ b/pmap.c @@ -39,6 +39,53 @@ #include "proc/readproc.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) { @@ -220,7 +267,7 @@ struct 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, "KernelPageSize") == 0) return 1; @@ -234,7 +281,7 @@ static int is_unimportant (char *s) } /* 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); @@ -263,14 +310,6 @@ static void print_extended_maps (FILE *f) unsigned KLONG value; 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); firstmapping = 2; while (ret != NULL) { @@ -368,45 +407,45 @@ loop_end: /* Print header */ if (firstmapping && !q_option) { - printf("%*s", maxw1, "Address"); /* Address field always enabled */ + maxw1 = justify_print(nls_Address, maxw1, 1); - if (is_enabled("Flags")) - printf(" %*s", maxw2, "Flags"); + if (is_enabled(nls_Flags)) + maxw2 = justify_print(nls_Flags, maxw2, 1); - if (is_enabled("Offset")) - printf(" %*s", maxw3, "Offset"); + if (is_enabled(nls_Offset)) + maxw3 = justify_print(nls_Offset, maxw3, 1); - if (is_enabled("Device")) - printf(" %*s", maxw4, "Device"); + if (is_enabled(nls_Device)) + maxw4 = justify_print(nls_Device, maxw4, 1); - if (is_enabled("Inode")) - printf(" %*s", maxw5, "Inode"); + if (is_enabled(nls_Inode)) + maxw5 = justify_print(nls_Inode, maxw5, 1); 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")) printf(" %*s", maxwv, "VmFlags"); - if (is_enabled("Mapping")) - printf(" %s", "Mapping"); - - printf("\n"); + if (is_enabled(nls_Mapping)) + justify_print(nls_Mapping, 0, 0); + else + printf("\n"); } /* Print data */ printf("%*s", maxw1, start); /* Address field is always enabled */ - if (is_enabled("Flags")) + if (is_enabled(nls_Flags)) printf(" %*s", maxw2, flags); - if (is_enabled("Offset")) + if (is_enabled(nls_Offset)) printf(" %*s", maxw3, offset); - if (is_enabled("Device")) + if (is_enabled(nls_Device)) printf(" %*s", maxw4, dev); - if (is_enabled("Inode")) + if (is_enabled(nls_Inode)) printf(" %*s", maxw5, inode); for (listnode=listhead; listnode!=NULL; listnode=listnode->next) @@ -438,11 +477,11 @@ loop_end: /* === PRINT TOTALS === */ if (!q_option && listhead!=NULL) { /* footer enabled and non-empty */ - footer_gap = maxw1 + 1; /* Address field is always enabled */ - if (is_enabled("Flags" )) footer_gap += maxw2 + 1; - if (is_enabled("Offset")) footer_gap += maxw3 + 1; - if (is_enabled("Device")) footer_gap += maxw4 + 1; - if (is_enabled("Inode" )) footer_gap += maxw5 + 1; + footer_gap = maxw1 + 1; /* Address field is always enabled */ + if (is_enabled(nls_Flags )) footer_gap += maxw2 + 1; + if (is_enabled(nls_Offset)) footer_gap += maxw3 + 1; + if (is_enabled(nls_Device)) footer_gap += maxw4 + 1; + if (is_enabled(nls_Inode )) footer_gap += maxw5 + 1; for (i=0; i> 10), rss, - (private_dirty + shared_dirty), - flags, cp2); + printf("%0*" KLF "x %*lu %*llu %*llu %*s %s\n", + maxw1, start, + maxw2, (unsigned long)(diff >> 10), + maxw3, rss, + maxw4, (private_dirty + shared_dirty), + maxw5, flags, + cp2); /* reset some counters */ rss = shared_dirty = private_dirty = 0ull; diff = 0; @@ -623,20 +672,21 @@ static int one_proc(proc_t * p) const char *cp = mapping_name(p, start, diff, mapbuf, map_desc_showpath, dev_major, dev_minor, inode); - printf((sizeof(KLONG) == 8) - ? "%016" KLF "x %7lu %s %016llx %03x:%05x %s\n" - : "%08lx %7lu %s %016llx %03x:%05x %s\n", - start, - (unsigned long)(diff >> 10), - flags, file_offset, dev_major, dev_minor, cp); + printf("%0*" KLF "x %*lu %*s %0*llx %*.*s%03x:%05x %s\n", + maxw1, start, + maxw2, (unsigned long)(diff >> 10), + maxw3, flags, + maxw4, file_offset, + (maxw5-9), (maxw5-9), " ", dev_major, dev_minor, + cp); } if (!x_option && !d_option) { const char *cp = mapping_name(p, start, diff, mapbuf, map_desc_showpath, dev_major, dev_minor, inode); printf((sizeof(KLONG) == 8) - ? "%016" KLF "x %6luK %s %s\n" - : "%08lx %6luK %s %s\n", + ? "%016" KLF "x %6luK %s %s\n" + : "%08lx %6luK %s %s\n", start, (unsigned long)(diff >> 10), flags, cp); } @@ -644,27 +694,23 @@ static int one_proc(proc_t * p) fclose(fp); if (!q_option) { if (x_option) { - if (sizeof(KLONG) == 8) { - printf - ("---------------- ------ ------ ------\n"); - printf(_("total kB %15ld %7llu %7llu\n"), - (total_shared + total_private_writeable + + if (sizeof(KLONG) == 4) + justify_print("--------", maxw1, 0); + else + justify_print("----------------", maxw1, 0); + justify_print("-------", maxw2, 1); + justify_print("-------", maxw3, 1); + justify_print("-------", maxw4, 1); + printf("\n"); + + printf("%-*s ", maxw1, _("total kB")); + printf("%*ld %*llu %*llu\n", + maxw2, (total_shared + + total_private_writeable + total_private_readonly) >> 10, - total_rss, - (total_shared_dirty + - total_private_dirty) - - ); - } else { - printf - ("-------- ------- ------- ------- -------\n"); - printf - (_("total kB %7ld %7llu %7llu -\n"), - (total_shared + total_private_writeable + - 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) { printf @@ -874,10 +920,10 @@ static int config_create (char *rc_filename) fprintf(f,"\n"); fprintf(f,"# To enable a field uncomment its entry\n"); fprintf(f,"\n"); - fprintf(f,"#Flags\n"); - fprintf(f,"#Offset\n"); - fprintf(f,"#Device\n"); - fprintf(f,"#Inode\n"); + fprintf(f,"#%s\n", nls_Flags); + fprintf(f,"#%s\n", nls_Offset); + fprintf(f,"#%s\n", nls_Device); + fprintf(f,"#%s\n", nls_Inode); fprintf(f,"#Size\n"); fprintf(f,"#Rss\n"); fprintf(f,"#Pss\n"); @@ -893,7 +939,7 @@ static int config_create (char *rc_filename) fprintf(f,"#MMUPageSize\n"); fprintf(f,"#Locked\n"); fprintf(f,"#VmFlags\n"); - fprintf(f,"#Mapping\n"); + fprintf(f,"#%s\n", nls_Mapping); fprintf(f,"\n"); fprintf(f,"\n"); fprintf(f,"[Mapping]\n"); @@ -960,9 +1006,7 @@ int main(int argc, char **argv) }; program_invocation_name = program_invocation_short_name; - setlocale (LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); + nls_initialize(); atexit(close_stdout); if (argc < 2)