egencache: Migrate _special_filename class to portage.utils.changelog for api use

Requested move by Robin <robbat2@gentoo.org> for the new split changelog repo scripts.
Rename the class more appropriately.
Make the file_type_lt() private.
diff --git a/bin/egencache b/bin/egencache
index 80738cf..e994b4a 100755
--- a/bin/egencache
+++ b/bin/egencache
@@ -52,16 +52,16 @@
 from portage.cache.cache_errors import CacheError, StatCollision
 from portage.cache.index.pkg_desc_index import pkg_desc_index_line_format
 from portage.const import TIMESTAMP_FORMAT
-from portage.manifest import guessManifestFileType
 from portage.package.ebuild._parallel_manifest.ManifestScheduler import ManifestScheduler
 from portage.util import cmp_sort_key, writemsg_level
 from portage.util._async.AsyncFunction import AsyncFunction
 from portage.util._async.run_main_scheduler import run_main_scheduler
 from portage.util._async.TaskScheduler import TaskScheduler
 from portage.util._eventloop.global_event_loop import global_event_loop
+from portage.util.changelog import ChangeLogTypeSort
 from portage import cpv_getkey
 from portage.dep import Atom, isjustname
-from portage.versions import pkgsplit, vercmp, _pkg_str
+from portage.versions import vercmp
 
 try:
 	from xml.etree import ElementTree
@@ -668,72 +668,6 @@
 		os.utime(desc_path, (mtime, mtime))
 
 
-if sys.hexversion < 0x3000000:
-	_filename_base = unicode
-else:
-	_filename_base = str
-
-class _special_filename(_filename_base):
-	"""
-	Helps to sort file names by file type and other criteria.
-	"""
-	def __new__(cls, status_change, file_name):
-		return _filename_base.__new__(cls, status_change + file_name)
-
-	def __init__(self, status_change, file_name):
-		_filename_base.__init__(status_change + file_name)
-		self.status_change = status_change
-		self.file_name = file_name
-		self.file_type = guessManifestFileType(file_name)
-
-	@staticmethod
-	def file_type_lt(a, b):
-		"""
-		Defines an ordering between file types.
-		"""
-		first = a.file_type
-		second = b.file_type
-		if first == second:
-			return False
-
-		if first == "EBUILD":
-			return True
-		elif first == "MISC":
-			return second in ("EBUILD",)
-		elif first == "AUX":
-			return second in ("EBUILD", "MISC")
-		elif first == "DIST":
-			return second in ("EBUILD", "MISC", "AUX")
-		elif first is None:
-			return False
-		else:
-			raise ValueError("Unknown file type '%s'" % first)
-
-	def __lt__(self, other):
-		"""
-		Compare different file names, first by file type and then
-		for ebuilds by version and lexicographically for others.
-		EBUILD < MISC < AUX < DIST < None
-		"""
-		if self.__class__ != other.__class__:
-			raise NotImplementedError
-
-		# Sort by file type as defined by file_type_lt().
-		if self.file_type_lt(self, other):
-			return True
-		elif self.file_type_lt(other, self):
-			return False
-
-		# Files have the same type.
-		if self.file_type == "EBUILD":
-			# Sort by version. Lowest first.
-			ver = "-".join(pkgsplit(self.file_name[:-7])[1:3])
-			other_ver = "-".join(pkgsplit(other.file_name[:-7])[1:3])
-			return vercmp(ver, other_ver) < 0
-		else:
-			# Sort lexicographically.
-			return self.file_name < other.file_name
-
 class GenChangeLogs(object):
 	def __init__(self, portdb, changelog_output, changelog_reversed,
 		max_jobs=None, max_load=None):
@@ -853,11 +787,11 @@
 					elif f[1].startswith('ChangeLog'):
 						pass
 					elif f[0].startswith('A'):
-						changed.append(_special_filename("+", f[1]))
+						changed.append(ChangeLogTypeSort("+", f[1]))
 					elif f[0].startswith('D'):
-						changed.append(_special_filename("-", f[1]))
+						changed.append(ChangeLogTypeSort("-", f[1]))
 					elif f[0].startswith('M'):
-						changed.append(_special_filename("", f[1]))
+						changed.append(ChangeLogTypeSort("", f[1]))
 					else:
 						writemsg_level(
 							"ERROR: unexpected git file status for %s: %s\n" % (cp,f,),
diff --git a/pym/portage/util/changelog.py b/pym/portage/util/changelog.py
new file mode 100644
index 0000000..9fc5ab6
--- /dev/null
+++ b/pym/portage/util/changelog.py
@@ -0,0 +1,69 @@
+#!/usr/bin/python -b
+# Copyright 2009-2015 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+
+from portage.manifest import guessManifestFileType
+from portage.versions import _unicode, pkgsplit, vercmp
+
+
+class ChangeLogTypeSort(_unicode):
+	"""
+	Helps to sort file names by file type and other criteria.
+	"""
+	def __new__(cls, status_change, file_name):
+		return _unicode.__new__(cls, status_change + file_name)
+
+	def __init__(self, status_change, file_name):
+		_unicode.__init__(status_change + file_name)
+		self.status_change = status_change
+		self.file_name = file_name
+		self.file_type = guessManifestFileType(file_name)
+
+	@staticmethod
+	def _file_type_lt(a, b):
+		"""
+		Defines an ordering between file types.
+		"""
+		first = a.file_type
+		second = b.file_type
+		if first == second:
+			return False
+
+		if first == "EBUILD":
+			return True
+		elif first == "MISC":
+			return second in ("EBUILD",)
+		elif first == "AUX":
+			return second in ("EBUILD", "MISC")
+		elif first == "DIST":
+			return second in ("EBUILD", "MISC", "AUX")
+		elif first is None:
+			return False
+		else:
+			raise ValueError("Unknown file type '%s'" % first)
+
+	def __lt__(self, other):
+		"""
+		Compare different file names, first by file type and then
+		for ebuilds by version and lexicographically for others.
+		EBUILD < MISC < AUX < DIST < None
+		"""
+		if self.__class__ != other.__class__:
+			raise NotImplementedError
+
+		# Sort by file type as defined by _file_type_lt().
+		if self._file_type_lt(self, other):
+			return True
+		elif self._file_type_lt(other, self):
+			return False
+
+		# Files have the same type.
+		if self.file_type == "EBUILD":
+			# Sort by version. Lowest first.
+			ver = "-".join(pkgsplit(self.file_name[:-7])[1:3])
+			other_ver = "-".join(pkgsplit(other.file_name[:-7])[1:3])
+			return vercmp(ver, other_ver) < 0
+		else:
+			# Sort lexicographically.
+			return self.file_name < other.file_name