Commit 2af25ac0f9d5f298204422a2321895ce7c709f97

Werner Lemberg 2014-12-02T08:38:57

[docmaker] Ensure Python 3 compatibility. * src/tools/docmaker/content.py (ContentProcessor::set_section, ContentProcessor::finish): Replace `has_key' function with `in' keyword. * src/tools/docmaker/formatter.py (Formatter::__init__): Replace sorting function with a key generator. (Formatter::add_identifier): Replace `has_key' function with `in' keyword. * src/tools/docmaker/tohtml.py (HtmlFormatter::html_source_quote): Replace `has_key' function with `in' keyword. (HtmlFormatter::index_exit, HtmlFormatter::section_enter): Use integer division. s/<>/>/. * src/tools/docmaker/utils.py: Import `itertools'. (index_sort): Replaced by... (index_key): ... this new key generator (doing exactly the same).

diff --git a/ChangeLog b/ChangeLog
index 535f07a..7142efd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2014-12-02  Werner Lemberg  <wl@gnu.org>
+
+	[docmaker] Ensure Python 3 compatibility.
+
+	* src/tools/docmaker/content.py (ContentProcessor::set_section,
+	ContentProcessor::finish): Replace `has_key' function with `in'
+	keyword.
+
+	* src/tools/docmaker/formatter.py (Formatter::__init__): Replace
+	sorting function with a key generator.
+	(Formatter::add_identifier): Replace `has_key' function with `in'
+	keyword.
+
+	* src/tools/docmaker/tohtml.py (HtmlFormatter::html_source_quote):
+	Replace `has_key' function with `in' keyword.
+	(HtmlFormatter::index_exit, HtmlFormatter::section_enter): Use
+	integer division.
+	s/<>/>/.
+
+	* src/tools/docmaker/utils.py: Import `itertools'.
+	(index_sort): Replaced by...
+	(index_key): ... this new key generator (doing exactly the same).
+
 2014-11-29  Werner Lemberg  <wl@gnu.org>
 
 	[docmaker] Don't output a block multiple times.
diff --git a/src/tools/docmaker/content.py b/src/tools/docmaker/content.py
index ed3516c..76a06a7 100644
--- a/src/tools/docmaker/content.py
+++ b/src/tools/docmaker/content.py
@@ -395,7 +395,7 @@ class  ContentProcessor:
 
     def  set_section( self, section_name ):
         """Set current section during parsing."""
-        if not self.sections.has_key( section_name ):
+        if not section_name in self.sections:
             section = DocSection( section_name )
             self.sections[section_name] = section
             self.section                = section
@@ -488,7 +488,7 @@ class  ContentProcessor:
         # listed there
         for chap in self.chapters:
             for sec in chap.order:
-                if self.sections.has_key( sec ):
+                if sec in self.sections:
                     section = self.sections[sec]
                     section.chapter = chap
                     section.reorder()
diff --git a/src/tools/docmaker/formatter.py b/src/tools/docmaker/formatter.py
index 45b3384..e8fda83 100644
--- a/src/tools/docmaker/formatter.py
+++ b/src/tools/docmaker/formatter.py
@@ -54,10 +54,10 @@ class  Formatter:
                             self.add_identifier( field.name, block )
 
         self.block_index = self.identifiers.keys()
-        self.block_index.sort( index_sort )
+        self.block_index.sort( key = index_key )
 
     def  add_identifier( self, name, block ):
-        if self.identifiers.has_key( name ):
+        if name in self.identifiers:
             # duplicate name!
             sys.stderr.write( "WARNING: duplicate definition for"
                               + " '" + name + "' "
diff --git a/src/tools/docmaker/tohtml.py b/src/tools/docmaker/tohtml.py
index e570034..34379a1 100644
--- a/src/tools/docmaker/tohtml.py
+++ b/src/tools/docmaker/tohtml.py
@@ -411,7 +411,7 @@ class  HtmlFormatter( Formatter ):
                     # this is a C keyword
                     result = ( result + prefix
                                + keyword_prefix + name + keyword_suffix )
-                elif self.identifiers.has_key( name ):
+                elif name in self.identifiers:
                     # this is a known identifier
                     block = self.identifiers[name]
                     id = block.name
@@ -480,7 +480,7 @@ class  HtmlFormatter( Formatter ):
     def  index_exit( self ):
         # `block_index' already contains the sorted list of index names
         count = len( self.block_index )
-        rows  = ( count + self.columns - 1 ) / self.columns
+        rows  = ( count + self.columns - 1 ) // self.columns
 
         print '<table class="index">'
         for r in range( rows ):
@@ -572,17 +572,17 @@ class  HtmlFormatter( Formatter ):
                 maxwidth = len( b.name )
 
         width = 70  # XXX magic number
-        if maxwidth <> 0:
+        if maxwidth > 0:
             # print section synopsis
             print section_synopsis_header
             print '<table class="synopsis">'
 
-            columns = width / maxwidth
+            columns = width // maxwidth
             if columns < 1:
                 columns = 1
 
             count = len( section.block_names )
-            rows  = ( count + columns - 1 ) / columns
+            rows  = ( count + columns - 1 ) // columns
 
             for r in range( rows ):
                 line = "<tr>"
diff --git a/src/tools/docmaker/utils.py b/src/tools/docmaker/utils.py
index c75dd2d..b35823a 100644
--- a/src/tools/docmaker/utils.py
+++ b/src/tools/docmaker/utils.py
@@ -13,7 +13,7 @@
 #  understand and accept it fully.
 
 
-import string, sys, os, glob
+import string, sys, os, glob, itertools
 
 
 # current output directory
@@ -21,38 +21,19 @@ import string, sys, os, glob
 output_dir = None
 
 
-# A function to sort the index.  It is a simple lexicographical sort, except
-# that it places capital letters before lowercase ones.
+# A function that generates a sorting key.  We want lexicographical order
+# (primary key) except that capital letters are sorted before lowercase
+# ones (secondary key).
 #
-def  index_sort( s1, s2 ):
-    if not s1:
-        return -1
-
-    if not s2:
-        return 1
-
-    l1 = len( s1 )
-    l2 = len( s2 )
-    m1 = string.lower( s1 )
-    m2 = string.lower( s2 )
-
-    for i in range( l1 ):
-        if i >= l2 or m1[i] > m2[i]:
-            return 1
-
-        if m1[i] < m2[i]:
-            return -1
-
-        if s1[i] < s2[i]:
-            return -1
-
-        if s1[i] > s2[i]:
-            return 1
-
-    if l2 > l1:
-        return -1
-
-    return 0
+# The primary key is implemented by lowercasing the input.  The secondary
+# key is simply the original data appended, character by character.  For
+# example, the sort key for `FT_x' is `fFtT__xx', while the sort key for
+# `ft_X' is `fftt__xX'.  Since ASCII codes of uppercase letters are
+# numerically smaller than the codes of lowercase letters, `fFtT__xx' gets
+# sorted before `fftt__xX'.
+#
+def  index_key( s ):
+    return string.join( itertools.chain( *zip( s.lower(), s ) ) )
 
 
 # Sort `input_list', placing the elements of `order_list' in front.