This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Print verbose archive listing with localedef --list-archive -v


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  <jakub@redhat.com>

	* 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]