From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27799 invoked by alias); 10 May 2002 11:58:33 -0000 Mailing-List: contact libc-hacker-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sources.redhat.com Received: (qmail 27759 invoked from network); 10 May 2002 11:58:29 -0000 Received: from unknown (HELO sunsite.mff.cuni.cz) (195.113.19.66) by sources.redhat.com with SMTP; 10 May 2002 11:58:29 -0000 Received: (from jakub@localhost) by sunsite.mff.cuni.cz (8.11.6/8.11.6) id g4ABwE401105; Fri, 10 May 2002 13:58:14 +0200 Date: Fri, 10 May 2002 04:58:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers Subject: [PATCH] Print verbose archive listing with localedef --list-archive -v Message-ID: <20020510135813.F1551@sunsite.ms.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i X-SW-Source: 2002-05/txt/msg00013.txt.bz2 Hi! The following patch makes --list-archive -v more verbose than plain --list-archive. For each locale category, a single line with file size, offset within locale-archive, nlink count, md5sum and locale/category is printed, like: 173416 383f80 7 18df5be8ef37eb1da09aeb52dee73e6a cs_CZ/LC_CTYPE 59 406a00 2 8a2acabaa518d4ea111c67182d6eb3c4 cs_CZ/LC_NUMERIC 2396 406a40 1 440312353035fab2de24bc48c0e7cea3 cs_CZ/LC_TIME 24143 4073a0 2 a215f933754c6cf95ada59413ae72e7d cs_CZ/LC_COLLATE 295 40d1f0 1 e25a29301d5d5b19373d194174c6b8d0 cs_CZ/LC_MONETARY 64 40d320 1 8d499d1b4530cc027c04bc8102fd473b cs_CZ/LC_MESSAGES/SYS_LC_MESSAGES 39 3b4c00 9 9f0433753d11fa45ef41781a733b397d cs_CZ/LC_PAPER 84 40d360 1 732b4482c88e6357baa0bf3e46c968d5 cs_CZ/LC_NAME 167 40d3c0 1 740654dbe00218beec59563af68c6410 cs_CZ/LC_ADDRESS 65 40d470 1 eac0d816714d5a048914ec8b80914f0e cs_CZ/LC_TELEPHONE 28 3b4d50 9 345396e85397d99eb778c78c9e230127 cs_CZ/LC_MEASUREMENT 388 40d4c0 1 721d5a48af98210b4a31e0e536f06784 cs_CZ/LC_IDENTIFICATION so that one can check what really in the locale-archive is, what locale categories are shared between what locales, in how many mmap calls that locale can be mapped, etc. I think localedef will need --extract-from-archive option too, plus maybe some option (maybe default) to optimize for number of mmap syscalls instead of size (ie. something like if file size is < 4K or so, don't attempt to link them together unless all the < 4K category files are reachable by one mmap call). 2002-05-10 Jakub Jelinek * locale/programs/localedef.h (show_archive_content): Add verbose argument. * locale/programs/localedef.c (main): Adjust caller. * locale/programs/locarchive (struct nameent, struct dataent): New. (nameentcmp, dataentcmp): New functions. (xstrcmp): Remove. (show_archive_content): Print verbose listing with --list-archive -v. --- libc/locale/programs/localedef.h.jj Tue Apr 30 12:52:50 2002 +++ libc/locale/programs/localedef.h Fri May 10 11:45:46 2002 @@ -175,6 +175,6 @@ extern int add_locales_to_archive (size_ extern int delete_locales_from_archive (size_t nlist, char *list[]); /* List content of locale archive. */ -extern void show_archive_content (void); +extern void show_archive_content (int verbose); #endif /* localedef.h */ --- libc/locale/programs/localedef.c.jj Tue Apr 30 12:52:50 2002 +++ libc/locale/programs/localedef.c Fri May 10 11:46:38 2002 @@ -202,7 +202,7 @@ main (int argc, char *argv[]) /* Handle a few special cases. */ if (list_archive) - show_archive_content (); + show_archive_content (verbose); if (add_to_archive) return add_locales_to_archive (argc - remaining, &argv[remaining], replace_archive); --- libc/locale/programs/locarchive.c.jj Tue Apr 30 19:49:04 2002 +++ libc/locale/programs/locarchive.c Fri May 10 13:44:03 2002 @@ -897,21 +897,52 @@ delete_locales_from_archive (nlist, list } +struct nameent +{ + char *name; + uint32_t locrec_offset; +}; + + +struct dataent +{ + const unsigned char *sum; + uint32_t file_offset; + uint32_t nlink; +}; + + static int -xstrcmp (const void *a, const void *b) +nameentcmp (const void *a, const void *b) { - return strcmp (*(const char **) a, *(const char **) b); + return strcmp (((const struct nameent *) a)->name, + ((const struct nameent *) b)->name); +} + + +static int +dataentcmp (const void *a, const void *b) +{ + if (((const struct dataent *) a)->file_offset + < ((const struct dataent *) b)->file_offset) + return -1; + + if (((const struct dataent *) a)->file_offset + > ((const struct dataent *) b)->file_offset) + return 1; + + return 0; } void -show_archive_content (void) +show_archive_content (int verbose) { struct locarhandle ah; struct locarhead *head; struct namehashent *namehashtab; + struct nameent *names; int cnt; - char **names; int used; /* Open the archive. This call never returns if we cannot @@ -920,7 +951,8 @@ show_archive_content (void) head = ah.addr; - names = (char **) xmalloc (head->namehash_used * sizeof (char *)); + names = (struct nameent *) xmalloc (head->namehash_used + * sizeof (struct nameent)); namehashtab = (struct namehashent *) ((char *) ah.addr + head->namehash_offset); @@ -928,14 +960,91 @@ show_archive_content (void) if (namehashtab[cnt].locrec_offset != 0) { assert (used < head->namehash_used); - names[used++] = ah.addr + namehashtab[cnt].name_offset; + names[used].name = ah.addr + namehashtab[cnt].name_offset; + names[used++].locrec_offset = namehashtab[cnt].locrec_offset; } /* Sort the names. */ - qsort (names, used, sizeof (char *), xstrcmp); + qsort (names, used, sizeof (struct nameent), nameentcmp); - for (cnt = 0; cnt < used; ++cnt) - puts (names[cnt]); + if (verbose) + { + struct dataent *files; + struct sumhashent *sumhashtab; + int sumused; + + files = (struct dataent *) xmalloc (head->sumhash_used + * sizeof (struct sumhashent)); + + sumhashtab = (struct sumhashent *) ((char *) ah.addr + + head->sumhash_offset); + for (cnt = sumused = 0; cnt < head->sumhash_size; ++cnt) + if (sumhashtab[cnt].file_offset != 0) + { + assert (sumused < head->sumhash_used); + files[sumused].sum = (const unsigned char *) sumhashtab[cnt].sum; + files[sumused].file_offset = sumhashtab[cnt].file_offset; + files[sumused++].nlink = 0; + } + + /* Sort by file locations. */ + qsort (files, sumused, sizeof (struct dataent), dataentcmp); + + /* Compute nlink fields. */ + for (cnt = 0; cnt < used; ++cnt) + { + struct locrecent *locrec; + int idx; + + locrec = (struct locrecent *) ((char *) ah.addr + + names[cnt].locrec_offset); + for (idx = 0; idx < __LC_LAST; ++idx) + if (idx != LC_ALL) + { + struct dataent *data, dataent; + + dataent.file_offset = locrec->record[idx].offset; + data = (struct dataent *) bsearch (&dataent, files, sumused, + sizeof (struct dataent), + dataentcmp); + assert (data != NULL); + ++data->nlink; + } + } + + /* Print it. */ + for (cnt = 0; cnt < used; ++cnt) + { + struct locrecent *locrec; + int idx, i; + + locrec = (struct locrecent *) ((char *) ah.addr + + names[cnt].locrec_offset); + for (idx = 0; idx < __LC_LAST; ++idx) + if (idx != LC_ALL) + { + struct dataent *data, dataent; + + dataent.file_offset = locrec->record[idx].offset; + data = (struct dataent *) bsearch (&dataent, files, sumused, + sizeof (struct dataent), + dataentcmp); + printf ("%6d %7x %3d ", + locrec->record[idx].len, locrec->record[idx].offset, + data->nlink); + for (i = 0; i < 16; i += 4) + printf ("%02x%02x%02x%02x", + data->sum[i], data->sum[i + 1], + data->sum[i + 2], data->sum[i + 3]); + printf (" %s/%s\n", names[cnt].name, + idx == LC_MESSAGES ? "LC_MESSAGES/SYS_LC_MESSAGES" + : locnames[idx]); + } + } + } + else + for (cnt = 0; cnt < used; ++cnt) + puts (names[cnt].name); close_archive (&ah); Jakub