# repoman: Checks
# Copyright 2007-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

"""This module contains functions used in Repoman to ascertain the quality
and correctness of an ebuild."""

from __future__ import unicode_literals

import codecs
from itertools import chain
import re
import time
import repoman.errors as errors
import portage
from portage.eapi import eapi_supports_prefix, eapi_has_implicit_rdepend, \
	eapi_has_src_prepare_and_src_configure, eapi_has_dosed_dohard, \
	eapi_exports_AA

class LineCheck(object):
	"""Run a check on a line of an ebuild."""
	"""A regular expression to determine whether to ignore the line"""
	ignore_line = False
	"""True if lines containing nothing more than comments with optional
	leading whitespace should be ignored"""
	ignore_comment = True

	def new(self, pkg):
		pass

	def check_eapi(self, eapi):
		""" returns if the check should be run in the given EAPI (default is True) """
		return True

	def check(self, num, line):
		"""Run the check on line and return error if there is one"""
		if self.re.match(line):
			return self.error

	def end(self):
		pass

class PhaseCheck(LineCheck):
	""" basic class for function detection """

	func_end_re = re.compile(r'^\}$')
	phases_re = re.compile('(%s)' % '|'.join((
		'pkg_pretend', 'pkg_setup', 'src_unpack', 'src_prepare',
		'src_configure', 'src_compile', 'src_test', 'src_install',
		'pkg_preinst', 'pkg_postinst', 'pkg_prerm', 'pkg_postrm',
		'pkg_config')))
	in_phase = ''

	def check(self, num, line):
		m = self.phases_re.match(line)
		if m is not None:
			self.in_phase = m.group(1)
		if self.in_phase != '' and \
				self.func_end_re.match(line) is not None:
			self.in_phase = ''

		return self.phase_check(num, line)

	def phase_check(self, num, line):
		""" override this function for your checks """
		pass

class EbuildHeader(LineCheck):
	"""Ensure ebuilds have proper headers
		Copyright header errors
		CVS header errors
		License header errors

	Args:
		modification_year - Year the ebuild was last modified
	"""

	repoman_check_name = 'ebuild.badheader'

	gentoo_copyright = r'^# Copyright ((1999|2\d\d\d)-)?%s Gentoo Foundation$'
	# Why a regex here, use a string match
	# gentoo_license = re.compile(r'^# Distributed under the terms of the GNU General Public License v2$')
	gentoo_license = '# Distributed under the terms of the GNU General Public License v2'
	cvs_header = re.compile(r'^# \$Header: .*\$$')
	ignore_comment = False

	def new(self, pkg):
		if pkg.mtime is None:
			self.modification_year = r'2\d\d\d'
		else:
			self.modification_year = str(time.gmtime(pkg.mtime)[0])
		self.gentoo_copyright_re = re.compile(
			self.gentoo_copyright % self.modification_year)

	def check(self, num, line):
		if num > 2:
			return
		elif num == 0:
			if not self.gentoo_copyright_re.match(line):
				return errors.COPYRIGHT_ERROR
		elif num == 1 and line.rstrip('\n') != self.gentoo_license:
			return errors.LICENSE_ERROR
		elif num == 2:
			if not self.cvs_header.match(line):
				return errors.CVS_HEADER_ERROR


class EbuildWhitespace(LineCheck):
	"""Ensure ebuilds have proper whitespacing"""

	repoman_check_name = 'ebuild.minorsyn'

	ignore_line = re.compile(r'(^$)|(^(\t)*#)')
	ignore_comment = False
	leading_spaces = re.compile(r'^[\S\t]')
	trailing_whitespace = re.compile(r'.*([\S]$)')

	def check(self, num, line):
		if self.leading_spaces.match(line) is None:
			return errors.LEADING_SPACES_ERROR
		if self.trailing_whitespace.match(line) is None:
			return errors.TRAILING_WHITESPACE_ERROR

class EbuildBlankLine(LineCheck):
	repoman_check_name = 'ebuild.minorsyn'
	ignore_comment = False
	blank_line = re.compile(r'^$')

	def new(self, pkg):
		self.line_is_blank = False

	def check(self, num, line):
		if self.line_is_blank and self.blank_line.match(line):
			return 'Useless blank line on line: %d'
		if self.blank_line.match(line):
			self.line_is_blank = True
		else:
			self.line_is_blank = False

	def end(self):
		if self.line_is_blank:
			yield 'Useless blank line on last line'

class EbuildQuote(LineCheck):
	"""Ensure ebuilds have valid quoting around things like D,FILESDIR, etc..."""

	repoman_check_name = 'ebuild.minorsyn'
	_message_commands = ["die", "echo", "eerror",
		"einfo", "elog", "eqawarn", "ewarn"]
	_message_re = re.compile(r'\s(' + "|".join(_message_commands) + \
		r')\s+"[^"]*"\s*$')
	_ignored_commands = ["local", "export"] + _message_commands
	ignore_line = re.compile(r'(^$)|(^\s*#.*)|(^\s*\w+=.*)' + \
		r'|(^\s*(' + "|".join(_ignored_commands) + r')\s+)')
	ignore_comment = False
	var_names = ["D", "DISTDIR", "FILESDIR", "S", "T", "ROOT", "WORKDIR"]

	# EAPI=3/Prefix vars
	var_names += ["ED", "EPREFIX", "EROOT"]

	# variables for games.eclass
	var_names += ["Ddir", "GAMES_PREFIX_OPT", "GAMES_DATADIR",
		"GAMES_DATADIR_BASE", "GAMES_SYSCONFDIR", "GAMES_STATEDIR",
		"GAMES_LOGDIR", "GAMES_BINDIR"]

	# variables for multibuild.eclass
	var_names += ["BUILD_DIR"]

	var_names = "(%s)" % "|".join(var_names)
	var_reference = re.compile(r'\$(\{'+var_names+'\}|' + \
		var_names + '\W)')
	missing_quotes = re.compile(r'(\s|^)[^"\'\s]*\$\{?' + var_names + \
		r'\}?[^"\'\s]*(\s|$)')
	cond_begin =  re.compile(r'(^|\s+)\[\[($|\\$|\s+)')
	cond_end =  re.compile(r'(^|\s+)\]\]($|\\$|\s+)')

	def check(self, num, line):
		if self.var_reference.search(line) is None:
			return
		# There can be multiple matches / violations on a single line. We
		# have to make sure none of the matches are violators. Once we've
		# found one violator, any remaining matches on the same line can
		# be ignored.
		pos = 0
		while pos <= len(line) - 1:
			missing_quotes = self.missing_quotes.search(line, pos)
			if not missing_quotes:
				break
			# If the last character of the previous match is a whitespace
			# character, that character may be needed for the next
			# missing_quotes match, so search overlaps by 1 character.
			group = missing_quotes.group()
			pos = missing_quotes.end() - 1

			# Filter out some false positives that can
			# get through the missing_quotes regex.
			if self.var_reference.search(group) is None:
				continue

			# Filter matches that appear to be an
			# argument to a message command.
			# For example: false || ewarn "foo $WORKDIR/bar baz"
			message_match = self._message_re.search(line)
			if message_match is not None and \
				message_match.start() < pos and \
				message_match.end() > pos:
				break

			# This is an attempt to avoid false positives without getting
			# too complex, while possibly allowing some (hopefully
			# unlikely) violations to slip through. We just assume
			# everything is correct if the there is a ' [[ ' or a ' ]] '
			# anywhere in the whole line (possibly continued over one
			# line).
			if self.cond_begin.search(line) is not None:
				continue
			if self.cond_end.search(line) is not None:
				continue

			# Any remaining matches on the same line can be ignored.
			return errors.MISSING_QUOTES_ERROR


class EbuildAssignment(LineCheck):
	"""Ensure ebuilds don't assign to readonly variables."""

	repoman_check_name = 'variable.readonly'
	readonly_assignment = re.compile(r'^\s*(export\s+)?(A|CATEGORY|P|PV|PN|PR|PVR|PF|D|WORKDIR|FILESDIR|FEATURES|USE)=')

	def check(self, num, line):
		match = self.readonly_assignment.match(line)
		e = None
		if match is not None:
			e = errors.READONLY_ASSIGNMENT_ERROR
		return e

class Eapi3EbuildAssignment(EbuildAssignment):
	"""Ensure ebuilds don't assign to readonly EAPI 3-introduced variables."""

	readonly_assignment = re.compile(r'\s*(export\s+)?(ED|EPREFIX|EROOT)=')

	def check_eapi(self, eapi):
		return eapi_supports_prefix(eapi)

class EbuildNestedDie(LineCheck):
	"""Check ebuild for nested die statements (die statements in subshells)"""

	repoman_check_name = 'ebuild.nesteddie'
	nesteddie_re = re.compile(r'^[^#]*\s\(\s[^)]*\bdie\b')

	def check(self, num, line):
		if self.nesteddie_re.match(line):
			return errors.NESTED_DIE_ERROR


class EbuildUselessDodoc(LineCheck):
	"""Check ebuild for useless files in dodoc arguments."""
	repoman_check_name = 'ebuild.minorsyn'
	uselessdodoc_re = re.compile(
		r'^\s*dodoc(\s+|\s+.*\s+)(ABOUT-NLS|COPYING|LICENCE|LICENSE)($|\s)')

	def check(self, num, line):
		match = self.uselessdodoc_re.match(line)
		if match:
			return "Useless dodoc '%s'" % (match.group(2), ) + " on line: %d"


class EbuildUselessCdS(LineCheck):
	"""Check for redundant cd ${S} statements"""
	repoman_check_name = 'ebuild.minorsyn'
	method_re = re.compile(r'^\s*src_(prepare|configure|compile|install|test)\s*\(\)')
	cds_re = re.compile(r'^\s*cd\s+("\$(\{S\}|S)"|\$(\{S\}|S))\s')

	def __init__(self):
		self.check_next_line = False

	def check(self, num, line):
		if self.check_next_line:
			self.check_next_line = False
			if self.cds_re.match(line):
				return errors.REDUNDANT_CD_S_ERROR
		elif self.method_re.match(line):
			self.check_next_line = True

class EapiDefinition(LineCheck):
	"""
	Check that EAPI assignment conforms to PMS section 7.3.1
	(first non-comment, non-blank line).
	"""
	repoman_check_name = 'EAPI.definition'
	ignore_comment = True
	_eapi_re = portage._pms_eapi_re

	def new(self, pkg):
		self._cached_eapi = pkg.eapi
		self._parsed_eapi = None
		self._eapi_line_num = None

	def check(self, num, line):
		if self._eapi_line_num is None and line.strip():
			self._eapi_line_num = num + 1
			m = self._eapi_re.match(line)
			if m is not None:
				self._parsed_eapi = m.group(2)

	def end(self):
		if self._parsed_eapi is None:
			if self._cached_eapi != "0":
				yield "valid EAPI assignment must occur on or before line: %s" % \
					self._eapi_line_num
		elif self._parsed_eapi != self._cached_eapi:
			yield ("bash returned EAPI '%s' which does not match "
				"assignment on line: %s") % \
				(self._cached_eapi, self._eapi_line_num)

class EbuildPatches(LineCheck):
	"""Ensure ebuilds use bash arrays for PATCHES to ensure white space safety"""
	repoman_check_name = 'ebuild.patches'
	re = re.compile(r'^\s*PATCHES=[^\(]')
	error = errors.PATCHES_ERROR

class EbuildQuotedA(LineCheck):
	"""Ensure ebuilds have no quoting around ${A}"""

	repoman_check_name = 'ebuild.minorsyn'
	a_quoted = re.compile(r'.*\"\$(\{A\}|A)\"')

	def check(self, num, line):
		match = self.a_quoted.match(line)
		if match:
			return "Quoted \"${A}\" on line: %d"

class NoOffsetWithHelpers(LineCheck):
	""" Check that the image location, the alternate root offset, and the
	offset prefix (D, ROOT, ED, EROOT and EPREFIX) are not used with
	helpers """

	repoman_check_name = 'variable.usedwithhelpers'
	# Ignore matches in quoted strings like this:
	# elog "installed into ${ROOT}usr/share/php5/apc/."
	re = re.compile(r'^[^#"\']*\b(docinto|docompress|dodir|dohard|exeinto|fowners|fperms|insinto|into)\s+"?\$\{?(D|ROOT|ED|EROOT|EPREFIX)\b.*')
	error = errors.NO_OFFSET_WITH_HELPERS

class ImplicitRuntimeDeps(LineCheck):
	"""
	Detect the case where DEPEND is set and RDEPEND is unset in the ebuild,
	since this triggers implicit RDEPEND=$DEPEND assignment (prior to EAPI 4).
	"""

	repoman_check_name = 'RDEPEND.implicit'
	_assignment_re = re.compile(r'^\s*(R?DEPEND)\+?=')

	def new(self, pkg):
		self._rdepend = False
		self._depend = False

	def check_eapi(self, eapi):
		# Beginning with EAPI 4, there is no
		# implicit RDEPEND=$DEPEND assignment
		# to be concerned with.
		return eapi_has_implicit_rdepend(eapi)

	def check(self, num, line):
		if not self._rdepend:
			m = self._assignment_re.match(line)
			if m is None:
				pass
			elif m.group(1) == "RDEPEND":
				self._rdepend = True
			elif m.group(1) == "DEPEND":
				self._depend = True

	def end(self):
		if self._depend and not self._rdepend:
			yield 'RDEPEND is not explicitly assigned'

class InheritDeprecated(LineCheck):
	"""Check if ebuild directly or indirectly inherits a deprecated eclass."""

	repoman_check_name = 'inherit.deprecated'

	# deprecated eclass : new eclass (False if no new eclass)
	deprecated_classes = {
		"bash-completion": "bash-completion-r1",
		"boost-utils": False,
		"distutils": "distutils-r1",
		"gems": "ruby-fakegem",
		"git": "git-2",
		"mono": "mono-env",
		"mozconfig-2": "mozconfig-3",
		"mozcoreconf": "mozcoreconf-2",
		"php-ext-pecl-r1": "php-ext-pecl-r2",
		"php-ext-source-r1": "php-ext-source-r2",
		"php-pear": "php-pear-r1",
		"python": "python-r1 / python-single-r1 / python-any-r1",
		"python-distutils-ng": "python-r1 + distutils-r1",
		"qt3": False,
		"qt4": "qt4-r2",
		"ruby": "ruby-ng",
		"ruby-gnome2": "ruby-ng-gnome2",
		"x-modular": "xorg-2",
		}

	_inherit_re = re.compile(r'^\s*inherit\s(.*)$')

	def new(self, pkg):
		self._errors = []
		self._indirect_deprecated = set(eclass for eclass in \
			self.deprecated_classes if eclass in pkg.inherited)

	def check(self, num, line):

		direct_inherits = None
		m = self._inherit_re.match(line)
		if m is not None:
			direct_inherits = m.group(1)
			if direct_inherits:
				direct_inherits = direct_inherits.split()

		if not direct_inherits:
			return

		for eclass in direct_inherits:
			replacement = self.deprecated_classes.get(eclass)
			if replacement is None:
				pass
			elif replacement is False:
				self._indirect_deprecated.discard(eclass)
				self._errors.append("please migrate from " + \
					"'%s' (no replacement) on line: %d" % (eclass, num + 1))
			else:
				self._indirect_deprecated.discard(eclass)
				self._errors.append("please migrate from " + \
					"'%s' to '%s' on line: %d" % \
					(eclass, replacement, num + 1))

	def end(self):
		for error in self._errors:
			yield error
		del self._errors

		for eclass in self._indirect_deprecated:
			replacement = self.deprecated_classes[eclass]
			if replacement is False:
				yield "please migrate from indirect " + \
					"inherit of '%s' (no replacement)" % (eclass,)
			else:
				yield "please migrate from indirect " + \
					"inherit of '%s' to '%s'" % \
					(eclass, replacement)
		del self._indirect_deprecated

class InheritEclass(LineCheck):
	"""
	Base class for checking for missing inherits, as well as excess inherits.

	Args:
		eclass: Set to the name of your eclass.
		funcs: A tuple of functions that this eclass provides.
		comprehensive: Is the list of functions complete?
		exempt_eclasses: If these eclasses are inherited, disable the missing
		                  inherit check.
	"""

	def __init__(self, eclass, funcs=None, comprehensive=False,
		exempt_eclasses=None, ignore_missing=False, **kwargs):
		self._eclass = eclass
		self._comprehensive = comprehensive
		self._exempt_eclasses = exempt_eclasses
		self._ignore_missing = ignore_missing
		inherit_re = eclass
		self._inherit_re = re.compile(r'^(\s*|.*[|&]\s*)\binherit\s(.*\s)?%s(\s|$)' % inherit_re)
		# Match when the function is preceded only by leading whitespace, a
		# shell operator such as (, {, |, ||, or &&, or optional variable
		# setting(s). This prevents false positives in things like elog
		# messages, as reported in bug #413285.
		self._func_re = re.compile(r'(^|[|&{(])\s*(\w+=.*)?\b(' + '|'.join(funcs) + r')\b')

	def new(self, pkg):
		self.repoman_check_name = 'inherit.missing'
		# We can't use pkg.inherited because that tells us all the eclasses that
		# have been inherited and not just the ones we inherit directly.
		self._inherit = False
		self._func_call = False
		if self._exempt_eclasses is not None:
			inherited = pkg.inherited
			self._disabled = any(x in inherited for x in self._exempt_eclasses)
		else:
			self._disabled = False
		self._eapi = pkg.eapi

	def check(self, num, line):
		if not self._inherit:
			self._inherit = self._inherit_re.match(line)
		if not self._inherit:
			if self._disabled or self._ignore_missing:
				return
			s = self._func_re.search(line)
			if s is not None:
				func_name = s.group(3)
				eapi_func = _eclass_eapi_functions.get(func_name)
				if eapi_func is None or not eapi_func(self._eapi):
					self._func_call = True
					return ('%s.eclass is not inherited, '
						'but "%s" found at line: %s') % \
						(self._eclass, func_name, '%d')
		elif not self._func_call:
			self._func_call = self._func_re.search(line)

	def end(self):
		if not self._disabled and self._comprehensive and self._inherit and not self._func_call:
			self.repoman_check_name = 'inherit.unused'
			yield 'no function called from %s.eclass; please drop' % self._eclass

_eclass_eapi_functions = {
	"usex" : lambda eapi: eapi not in ("0", "1", "2", "3", "4", "4-python", "4-slot-abi")
}

# eclasses that export ${ECLASS}_src_(compile|configure|install)
_eclass_export_functions = (
	'ant-tasks', 'apache-2', 'apache-module', 'aspell-dict',
	'autotools-utils', 'base', 'bsdmk', 'cannadic',
	'clutter', 'cmake-utils', 'db', 'distutils', 'elisp',
	'embassy', 'emboss', 'emul-linux-x86', 'enlightenment',
	'font-ebdftopcf', 'font', 'fox', 'freebsd', 'freedict',
	'games', 'games-ggz', 'games-mods', 'gdesklets',
	'gems', 'gkrellm-plugin', 'gnatbuild', 'gnat', 'gnome2',
	'gnome-python-common', 'gnustep-base', 'go-mono', 'gpe',
	'gst-plugins-bad', 'gst-plugins-base', 'gst-plugins-good',
	'gst-plugins-ugly', 'gtk-sharp-module', 'haskell-cabal',
	'horde', 'java-ant-2', 'java-pkg-2', 'java-pkg-simple',
	'java-virtuals-2', 'kde4-base', 'kde4-meta', 'kernel-2',
	'latex-package', 'linux-mod', 'mozlinguas', 'myspell',
	'myspell-r2', 'mysql', 'mysql-v2', 'mythtv-plugins',
	'oasis', 'obs-service', 'office-ext', 'perl-app',
	'perl-module', 'php-ext-base-r1', 'php-ext-pecl-r2',
	'php-ext-source-r2', 'php-lib-r1', 'php-pear-lib-r1',
	'php-pear-r1', 'python-distutils-ng', 'python',
	'qt4-build', 'qt4-r2', 'rox-0install', 'rox', 'ruby',
	'ruby-ng', 'scsh', 'selinux-policy-2', 'sgml-catalog',
	'stardict', 'sword-module', 'tetex-3', 'tetex',
	'texlive-module', 'toolchain-binutils', 'toolchain',
	'twisted', 'vdr-plugin-2', 'vdr-plugin', 'vim',
	'vim-plugin', 'vim-spell', 'virtuoso', 'vmware',
	'vmware-mod', 'waf-utils', 'webapp', 'xemacs-elisp',
	'xemacs-packages', 'xfconf', 'x-modular', 'xorg-2',
	'zproduct'
)

_eclass_info = {
	'autotools': {
		'funcs': (
			'eaclocal', 'eautoconf', 'eautoheader',
			'eautomake', 'eautoreconf', '_elibtoolize',
			'eautopoint'
		),
		'comprehensive': True,

		# Exempt eclasses:
		# git - An EGIT_BOOTSTRAP variable may be used to call one of
		#       the autotools functions.
		# subversion - An ESVN_BOOTSTRAP variable may be used to call one of
		#       the autotools functions.
		'exempt_eclasses': ('git', 'git-2', 'subversion', 'autotools-utils')
	},

	'eutils': {
		'funcs': (
			'estack_push', 'estack_pop', 'eshopts_push', 'eshopts_pop',
			'eumask_push', 'eumask_pop', 'epatch', 'epatch_user',
			'emktemp', 'edos2unix', 'in_iuse', 'use_if_iuse', 'usex'
		),
		'comprehensive': False,

		# These are "eclasses are the whole ebuild" type thing.
		'exempt_eclasses': _eclass_export_functions,
	},

	'flag-o-matic': {
		'funcs': (
			'filter-(ld)?flags', 'strip-flags', 'strip-unsupported-flags',
			'append-((ld|c(pp|xx)?))?flags', 'append-libs',
		),
		'comprehensive': False
	},

	'libtool': {
		'funcs': (
			'elibtoolize',
		),
		'comprehensive': True,
		'exempt_eclasses': ('autotools',)
	},

	'multilib': {
		'funcs': (
			'get_libdir',
		),

		# These are "eclasses are the whole ebuild" type thing.
		'exempt_eclasses': _eclass_export_functions + ('autotools', 'libtool',
			'multilib-minimal'),

		'comprehensive': False
	},

	'multiprocessing': {
		'funcs': (
			'makeopts_jobs',
		),
		'comprehensive': False
	},

	'prefix': {
		'funcs': (
			'eprefixify',
		),
		'comprehensive': True
	},

	'toolchain-funcs': {
		'funcs': (
			'gen_usr_ldscript',
		),
		'comprehensive': False
	},

	'user': {
		'funcs': (
			'enewuser', 'enewgroup',
			'egetent', 'egethome', 'egetshell', 'esethome'
		),
		'comprehensive': True
	}
}

class EMakeParallelDisabled(PhaseCheck):
	"""Check for emake -j1 calls which disable parallelization."""
	repoman_check_name = 'upstream.workaround'
	re = re.compile(r'^\s*emake\s+.*-j\s*1\b')
	error = errors.EMAKE_PARALLEL_DISABLED

	def phase_check(self, num, line):
		if self.in_phase == 'src_compile' or self.in_phase == 'src_install':
			if self.re.match(line):
				return self.error

class EMakeParallelDisabledViaMAKEOPTS(LineCheck):
	"""Check for MAKEOPTS=-j1 that disables parallelization."""
	repoman_check_name = 'upstream.workaround'
	re = re.compile(r'^\s*MAKEOPTS=(\'|")?.*-j\s*1\b')
	error = errors.EMAKE_PARALLEL_DISABLED_VIA_MAKEOPTS

class NoAsNeeded(LineCheck):
	"""Check for calls to the no-as-needed function."""
	repoman_check_name = 'upstream.workaround'
	re = re.compile(r'.*\$\(no-as-needed\)')
	error = errors.NO_AS_NEEDED

class PreserveOldLib(LineCheck):
	"""Check for calls to the deprecated preserve_old_lib function."""
	repoman_check_name = 'ebuild.minorsyn'
	re = re.compile(r'.*preserve_old_lib')
	error = errors.PRESERVE_OLD_LIB

class SandboxAddpredict(LineCheck):
	"""Check for calls to the addpredict function."""
	repoman_check_name = 'upstream.workaround'
	re = re.compile(r'(^|\s)addpredict\b')
	error = errors.SANDBOX_ADDPREDICT

class DeprecatedBindnowFlags(LineCheck):
	"""Check for calls to the deprecated bindnow-flags function."""
	repoman_check_name = 'ebuild.minorsyn'
	re = re.compile(r'.*\$\(bindnow-flags\)')
	error = errors.DEPRECATED_BINDNOW_FLAGS

class WantAutoDefaultValue(LineCheck):
	"""Check setting WANT_AUTO* to latest (default value)."""
	repoman_check_name = 'ebuild.minorsyn'
	_re = re.compile(r'^WANT_AUTO(CONF|MAKE)=(\'|")?latest')

	def check(self, num, line):
		m = self._re.match(line)
		if m is not None:
			return 'WANT_AUTO' + m.group(1) + \
				' redundantly set to default value "latest" on line: %d'

class SrcCompileEconf(PhaseCheck):
	repoman_check_name = 'ebuild.minorsyn'
	configure_re = re.compile(r'\s(econf|./configure)')

	def check_eapi(self, eapi):
		return eapi_has_src_prepare_and_src_configure(eapi)

	def phase_check(self, num, line):
		if self.in_phase == 'src_compile':
			m = self.configure_re.match(line)
			if m is not None:
				return ("'%s'" % m.group(1)) + \
					" call should be moved to src_configure from line: %d"

class SrcUnpackPatches(PhaseCheck):
	repoman_check_name = 'ebuild.minorsyn'
	src_prepare_tools_re = re.compile(r'\s(e?patch|sed)\s')

	def check_eapi(self, eapi):
		return eapi_has_src_prepare_and_src_configure(eapi)

	def phase_check(self, num, line):
		if self.in_phase == 'src_unpack':
			m = self.src_prepare_tools_re.search(line)
			if m is not None:
				return ("'%s'" % m.group(1)) + \
					" call should be moved to src_prepare from line: %d"

class BuiltWithUse(LineCheck):
	repoman_check_name = 'ebuild.minorsyn'
	re = re.compile(r'(^|.*\b)built_with_use\b')
	error = errors.BUILT_WITH_USE

class DeprecatedUseq(LineCheck):
	"""Checks for use of the deprecated useq function"""
	repoman_check_name = 'ebuild.minorsyn'
	re = re.compile(r'(^|.*\b)useq\b')
	error = errors.USEQ_ERROR

class DeprecatedHasq(LineCheck):
	"""Checks for use of the deprecated hasq function"""
	repoman_check_name = 'ebuild.minorsyn'
	re = re.compile(r'(^|.*\b)hasq\b')
	error = errors.HASQ_ERROR

# EAPI-3 checks
class Eapi3DeprecatedFuncs(LineCheck):
	repoman_check_name = 'EAPI.deprecated'
	deprecated_commands_re = re.compile(r'^\s*(check_license)\b')

	def check_eapi(self, eapi):
		return eapi not in ('0', '1', '2')

	def check(self, num, line):
		m = self.deprecated_commands_re.match(line)
		if m is not None:
			return ("'%s'" % m.group(1)) + \
				" has been deprecated in EAPI=3 on line: %d"

# EAPI-4 checks
class Eapi4IncompatibleFuncs(LineCheck):
	repoman_check_name = 'EAPI.incompatible'
	banned_commands_re = re.compile(r'^\s*(dosed|dohard)')

	def check_eapi(self, eapi):
		return not eapi_has_dosed_dohard(eapi)

	def check(self, num, line):
		m = self.banned_commands_re.match(line)
		if m is not None:
			return ("'%s'" % m.group(1)) + \
				" has been banned in EAPI=4 on line: %d"

class Eapi4GoneVars(LineCheck):
	repoman_check_name = 'EAPI.incompatible'
	undefined_vars_re = re.compile(r'.*\$(\{(AA|KV|EMERGE_FROM)\}|(AA|KV|EMERGE_FROM))')

	def check_eapi(self, eapi):
		# AA, KV, and EMERGE_FROM should not be referenced in EAPI 4 or later.
		return not eapi_exports_AA(eapi)

	def check(self, num, line):
		m = self.undefined_vars_re.match(line)
		if m is not None:
			return ("variable '$%s'" % m.group(1)) + \
				" is gone in EAPI=4 on line: %d"

class PortageInternal(LineCheck):
	repoman_check_name = 'portage.internal'
	ignore_comment = True
	# Match when the command is preceded only by leading whitespace or a shell
	# operator such as (, {, |, ||, or &&. This prevents false positives in
	# things like elog messages, as reported in bug #413285.
	re = re.compile(r'^(\s*|.*[|&{(]+\s*)\b(ecompress|ecompressdir|env-update|prepall|prepalldocs|preplib)\b')

	def check(self, num, line):
		"""Run the check on line and return error if there is one"""
		m = self.re.match(line)
		if m is not None:
			return ("'%s'" % m.group(2)) + " called on line: %d"

class PortageInternalVariableAssignment(LineCheck):
	repoman_check_name = 'portage.internal'
	internal_assignment = re.compile(r'\s*(export\s+)?(EXTRA_ECONF|EXTRA_EMAKE)\+?=')

	def check(self, num, line):
		match = self.internal_assignment.match(line)
		e = None
		if match is not None:
			e = 'Assignment to variable %s' % match.group(2)
			e += ' on line: %d'
		return e

_base_check_classes = (InheritEclass, LineCheck, PhaseCheck)
_constant_checks = None

def _init(experimental_inherit=False):

	global _constant_checks, _eclass_info

	if not experimental_inherit:
		# Emulate the old eprefixify.defined and inherit.autotools checks.
		_eclass_info = {
			'autotools': {
				'funcs': (
					'eaclocal', 'eautoconf', 'eautoheader',
					'eautomake', 'eautoreconf', '_elibtoolize',
					'eautopoint'
				),
				'comprehensive': True,
				'ignore_missing': True,
				'exempt_eclasses': ('git', 'git-2', 'subversion', 'autotools-utils')
			},

			'prefix': {
				'funcs': (
					'eprefixify',
				),
				'comprehensive': False
			}
		}

	_constant_checks = tuple(chain((v() for k, v in globals().items()
		if isinstance(v, type) and issubclass(v, LineCheck) and
		v not in _base_check_classes),
		(InheritEclass(k, **portage._native_kwargs(kwargs))
		for k, kwargs in _eclass_info.items())))

_here_doc_re = re.compile(r'.*\s<<[-]?(\w+)$')
_ignore_comment_re = re.compile(r'^\s*#')

def run_checks(contents, pkg):
	unicode_escape_codec = codecs.lookup('unicode_escape')
	unicode_escape = lambda x: unicode_escape_codec.decode(x)[0]
	if _constant_checks is None:
		_init()
	checks = _constant_checks
	here_doc_delim = None
	multiline = None

	for lc in checks:
		lc.new(pkg)
	for num, line in enumerate(contents):

		# Check if we're inside a here-document.
		if here_doc_delim is not None:
			if here_doc_delim.match(line):
				here_doc_delim = None
		if here_doc_delim is None:
			here_doc = _here_doc_re.match(line)
			if here_doc is not None:
				here_doc_delim = re.compile(r'^\s*%s$' % here_doc.group(1))
		if here_doc_delim is not None:
			continue

		# Unroll multiline escaped strings so that we can check things:
		#		inherit foo bar \
		#			moo \
		#			cow
		# This will merge these lines like so:
		#		inherit foo bar 	moo 	cow
		try:
			# A normal line will end in the two bytes: <\> <\n>.  So decoding
			# that will result in python thinking the <\n> is being escaped
			# and eat the single <\> which makes it hard for us to detect.
			# Instead, strip the newline (which we know all lines have), and
			# append a <0>.  Then when python escapes it, if the line ended
			# in a <\>, we'll end up with a <\0> marker to key off of.  This
			# shouldn't be a problem with any valid ebuild ...
			line_escaped = unicode_escape(line.rstrip('\n') + '0')
		except SystemExit:
			raise
		except:
			# Who knows what kind of crazy crap an ebuild will have
			# in it -- don't allow it to kill us.
			line_escaped = line
		if multiline:
			# Chop off the \ and \n bytes from the previous line.
			multiline = multiline[:-2] + line
			if not line_escaped.endswith('\0'):
				line = multiline
				num = multinum
				multiline = None
			else:
				continue
		else:
			if line_escaped.endswith('\0'):
				multinum = num
				multiline = line
				continue

		if not line.endswith("#nowarn\n"):
			# Finally we have a full line to parse.
			is_comment = _ignore_comment_re.match(line) is not None
			for lc in checks:
				if is_comment and lc.ignore_comment:
					continue
				if lc.check_eapi(pkg.eapi):
					ignore = lc.ignore_line
					if not ignore or not ignore.match(line):
						e = lc.check(num, line)
						if e:
							yield lc.repoman_check_name, e % (num + 1)

	for lc in checks:
		i = lc.end()
		if i is not None:
			for e in i:
				yield lc.repoman_check_name, e
