<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
  <!ENTITY tex "TeX">
  <!ENTITY latex "LaTeX">
]>
<book id="book-root" lang="en">
  <bookinfo>
    <title>Lintian User's Manual</title>
    <abstract>
      <para>
        This manual describes Lintian, the Debian package checker.
      </para>
    </abstract>
    <copyright>
      <year>1998</year>
      <holder>Christian Schwarz</holder>
      <holder>Richard Braakman</holder>
    </copyright>
    <copyright>
      <year>2000</year>
      <holder>Sean 'Shaleh' Perry</holder>
    </copyright>
    <copyright>
      <year>2004</year>
      <year>2008</year>
      <holder>Frank Lichtenheld</holder>
    </copyright>
    <legalnotice>
      <para>
        This manual is free software; you may redistribute it and/or
        modify it under the terms of the GNU General Public License as
        published by the Free Software Foundation; either version 2,
        or (at your option) any later version.
      </para>
      <para>
        This is distributed in the hope that it will be useful, but
        without any warranty; without even the implied warranty of
        merchantability or fitness for a particular purpose. See the
        GNU General Public License for more details.
      </para>
      <para>
        A copy of the GNU General Public License is available as
        <filename>/usr/share/common-licenses/GPL</filename> in the
        Debian GNU/Linux distribution or on the World Wide Web at
        <ulink url="http://www.gnu.org/copyleft/gpl.html">the GNU web site</ulink>.
        You can also obtain it by writing to the Free Software Foundation,
        Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
      </para>
    </legalnotice>
  </bookinfo>
  <chapter label="1" id="chapter-1">
    <title>Introduction</title>
    <sect1 label="1.1" id="section-1.1">
      <title>About Lintian</title>
      <para>
        Lintian is a Debian package checker. It can be used to check
        binary and source packages for compliance with the Debian
        policy and for other common packaging errors.
      </para>
      <para>
        Lintian uses an archive directory, called laboratory, in which
        it stores information about the packages it examines.  It can
        keep this information between multiple invocations in order to
        avoid repeating expensive data-collection operations. It's
        also possible to check the complete Debian archive for bugs
        &mdash; in a timely manner.
      </para>
    </sect1>

    <sect1 label="1.2" id="section-1.2">
      <title>The intention of Lintian</title>
      <para>
        Packaging has become complicated&mdash;not because dpkg is
        complicated (indeed, dpkg-deb is very simple to use) but
        because of the high requirements of our policy. If a developer
        releases a new package, she has to consider hundreds of
        guidelines to make the package `policy compliant.'
      </para>
      <para>
        All parts of our policy have been introduced by the same procedure:
        Some developer has a good idea how to make packages more `unique' with
        respect to a certain aspect&mdash;then the idea is discussed and a policy
        proposal is prepared. If we have a consensus about the policy change,
        it's introduced in our manuals.
      </para>
      <para>
        Therefore, our policy is <emphasis>not</emphasis> designed to
        make life harder for the maintainers! The intention is to make
        Debian the best Linux distribution out there. With this in
        mind, lots of policy changes are discussed on the mailing
        lists each week.
      </para>
      <para>
        But changing the policy is only a small part of the story:
        Just having some statement included in the manual does not
        make Debian any better. What's needed is for that policy to
        become `real life,' i.e.,
        it's <emphasis>implemented</emphasis> in our packages. And
        this is where Lintian comes in: Lintian checks packages and
        reports possible policy violations. (Of course, not everything
        can be checked mechanically &mdash; but a lot of things can
        and this is what Lintian is for.)
      </para>
      <para>Thus, Lintian has the following goals:</para>
      <itemizedlist mark="bullet">
        <listitem>
          <para>
            <emphasis>To give us some impression of the `gap'
              between theory (written policy) and praxis (current state of
              implementation).</emphasis>
          </para>
          <para>
            From the results of the first two Lintian checks I
            implemented, I see that there is a big need to make this
            gap smaller. Introducing more policy aspects is worthless
            unless they are implemented. We first should fix packages
            to comply with current policy before searching for new
            ways to make policy more detailed. (Of course, there are
            also important policy changes that need to be introduced
            &mdash; but this is not what's meant here.)
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>
              To make us re-think about certain aspects of our policy.
            </emphasis>
          </para>
          <para>
            For example, it could turn out that some ideas that once
            sounded great in theory are hard to implement in all our
            packages &mdash; in which case we should rework this
            aspect of policy.
          </para>
        </listitem>
        <listitem>
          <para>
            <emphasis>
              To show us where to concentrate our efforts in order to
              make Debian a higher quality distribution.
            </emphasis>
          </para>
          <para>
            Most release requirements will be implemented through
            policy.  Lintian reports provide an easy way to
            compare <emphasis>all</emphasis> our packages against
            policy and keep track of the fixing process by watching
            bug reports.  Note, that all this can be
            done <emphasis>automatically</emphasis>.
          </para>
        </listitem>
        <listitem>
          <para><emphasis>To make us avoid making the same mistakes all over again.</emphasis>
          </para>
          <para>
            Being humans, it's natural for us to make errors. Since we
            all have the ability to learn from our mistakes, this is
            actually no big problem.  Once an important bug is
            discovered, a Lintian check could be written to check for
            exactly this bug. This will prevent the bug from appearing
            in any future revisions of any of our packages.
          </para>
        </listitem>
      </itemizedlist>
    </sect1>

    <sect1 label="1.3" id="section-1.3">
      <title>Design issues</title>
      <para>There are three fields of application for Lintian:</para>
      <itemizedlist mark="bullet">
        <listitem>
          <para>
            one person could use Lintian to check the whole Debian
            archive and reports bugs,
          </para>
        </listitem>
        <listitem>
          <para>
            each maintainer runs Lintian over her packages before
            uploading them,
          </para>
        </listitem>
        <listitem>
          <para>
            dinstall checks packages which are uploaded to master
            before they are installed in the archive.
          </para>
        </listitem>
      </itemizedlist>
      <para>
        The authors of Lintian decided to use a very modular design to
        achieve the following goals:
      </para>
      <itemizedlist mark="bullet">
        <listitem>
          <para>
            flexibility: Lintian can be used to check single packages
            or the whole archive and to report and keep track of bug
            reports, etc.
          </para>
        </listitem>
        <listitem>
          <para>
            completeness: Lintian will eventually include checks for
            (nearly) everything that can be checked mechanically.
          </para>
        </listitem>
        <listitem>
          <para>
            uptodateness: Lintian will be updated whenever policy is
            changed.
          </para>
        </listitem>
        <listitem>
          <para>
            performance: Lintian should make it possible to check
            single packages within seconds or check the full archive
            within 5 days.
          </para>
        </listitem>
      </itemizedlist>
      <para>
        The design also has a number of constrains that limits the
        things Lintian can check for and what tools it can use:
      </para>
      <itemizedlist mark="bullet">
        <listitem>
          <para>
            static analysis: The code in a package may be analyzed,
            but it should <emphasis>never</emphasis> be executed.
            However, Lintian can (and does) use external tools to
            analyze files in the package.
          </para>
        </listitem>
        <listitem>
          <para>
            deterministic replay-ability: Checks should not rely on
            the state of system caches or even the system time.  These
            things makes it harder for others to reproduce (the
            absence of) tags.
          </para>
        </listitem>
        <listitem>
          <para>
            same source analysis: Lintian checks packages in small
            isolated groups based on the source package.  Requiring
            the presence of all the dependencies to provide the full
            results make it harder to run lintian (not to mention, it
            makes "deterministic replay-ability" a lot harder as
            well).
          </para>
        </listitem>
      </itemizedlist>
    </sect1>

    <sect1 label="1.4" id="section-1.4">
      <title>Disclaimer</title>
      <para>Here is a list of important notes on how to use Lintian:</para>
      <orderedlist numeration="arabic">
        <listitem>
          <para>
            Lintian is not finished yet and will probably never
            be. Please don't use Lintian as a reference for Debian
            policy. Lintian might miss a lot of policy violations
            while it might also report some violations by mistake. If
            in doubt, please check out the policy manuals.
          </para>
        </listitem>
        <listitem>
          <para>
            The Debian policy gives the maintainers a lot of
            freedom. In most cases, the guidelines included in the
            manuals allow exceptions. Thus, if Lintian reports a
            policy violation on a package and you think this is such
            an exception (or if you think Lintian has a bug) you can
            do two things: If your package is a bit non-standard and
            weird in this regard, you can install an override. If you
            think however that the check is too easily or outright
            wrongly triggered, please file a bug on the lintian
            package.
          </para>
        </listitem>
        <listitem>
          <para>
            Please DO NOT use Lintian to file bug reports (neither
            single ones nor mass bug reports). This is done by the
            authors of Lintian already and duplication of efforts and
            bug reports should be avoided! If you think a certain bug
            is `critical' and should be reported/fixed immediately,
            please contact the maintainer of the corresponding package
            and/or the Lintian maintainers.
          </para>
        </listitem>
        <listitem>
          <para>
            Any feedback about Lintian is welcome! Please send your
            comments to the lintian
            maintainers <email>lintian-maint@debian.org</email>.</para>
        </listitem>
      </orderedlist>
    </sect1>
  </chapter>

  <chapter label="2" id="chapter-2">
    <title>Getting started</title>
    <sect1 label="2.1" id="section-2.1">
      <title>Installing Lintian</title>
      <para>
        Before you can start to check your packages with Lintian,
        you'll have to install
        the <systemitem role="package">lintian</systemitem> Debian
        package.
      </para>
      <para>
        Alternatively you can checkout Lintian from the source
        repository and use that directly.  By setting LINTIAN_ROOT (or
        using the --root option) lintian can be run from the source
        directory as if it had been installed on your system.
      </para>
      <para>
        The only known caveat of using Lintian from the source
        directory is that Lintian requires a C.UTF-8 (or en_US.UTF-8)
        locale to correctly process some files.  Lintian 2.5.5
        supports using the C.UTF-8 locale
        from the <systemitem role="package">libc-bin</systemitem>
        in Debian Wheezy.
      </para>
      <para>
        If either your version
        of <systemitem role="package">libc-bin</systemitem> or Lintian
        are too old, you can work around this issue by generating an
        en_US.UTF-8 locale.  Alternatively, installing a copy
        of <systemitem role="package">lintian</systemitem> should
        solve this, as older versions of Lintian generates a private
        locale at install time.  Note, older versions of Lintian can
        only use the en_US.UTF-8 locale.
      </para>
    </sect1>

    <sect1 label="2.2" id="section-2.2">
      <title>Running lintian</title>
      <para>
        After that, you can run Lintian on a changes file or any
        Debian binary, udeb or source packages like this:
      </para>
      <screen>
$ lintian libc5_5.4.38-1.deb
W: libc5: old-fsf-address-in-copyright-file
W: libc5: shlib-without-dependency-information usr/lib/libgnumalloc.so.5.4.38
W: libc5: shlib-without-dependency-information lib/libc.so.5.4.38
W: libc5: shlib-without-dependency-information lib/libm.so.5.0.9
E: libc5: shlib-with-executable-bit lib/libc.so.5.4.38 0755
E: libc5: shlib-with-executable-bit lib/libm.so.5.0.9 0755
E: libc5: shlib-missing-in-control-file libgnumalloc usr/lib/libgnumalloc.so.5.4.38
$
</screen>
      <para>
        Please note that some checks are cross-package checks and can
        only be (accurately) performed if the binary packages and the
        source are processed together.  If Lintian is passed a changes
        file, it will attempt to process all packages listed in the
        changes file.
      </para>
      <para>
        Lintian supports a number of command line options, which are
        documented in the manpage of lintian(1).  Some of the options
        may appear in the lintianrc file (without the leading dashes)
        in Lintian 2.5.1 (or newer).
      </para>
    </sect1>

    <sect1 label="2.3" id="section-2.3">
      <title>Lintian Tags</title>
      <para>
        Lintian uses a special format for all its error and warning
        messages. With that it is very easy to write other programs
        which run Lintian and interpret the displayed messages.
      </para>
      <para>
        The first character of each line indicates the type of
        message. Currently, the following types are supported:
      </para>
      <variablelist>
        <varlistentry>
          <term><emphasis>Errors (E)</emphasis></term>
          <listitem>
            <para>
              The displayed message indicates a policy violation or a
              packaging error. For policy violations, Lintian will
              cite the appropriate policy section when it is invoked
              with the <option>-i</option> option.
            </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><emphasis>Warnings (W)</emphasis></term>
          <listitem>
            <para>
              The displayed message might be a policy violation or packaging
              error. A warning is usually an indication that the test is
              known to sometimes produce false positive alarms, because either
              the corresponding rule in policy has many exceptions or the test
              uses some sort of heuristic to find errors.
            </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><emphasis>Info (I)</emphasis></term>
          <listitem>
            <para>
              The displayed message is meant to inform the maintainer
              about a certain packaging aspect. Such messages do not
              usually indicate errors, but might still be of interest
              to the curious.  They are not displayed unless
              the <option>-I</option> option is set.
            </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><emphasis>Notes (N)</emphasis></term>
          <listitem>
            <para>
              The displayed message is a debugging message which
              informs you about the current state of Lintian.
            </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><emphasis>Experimental (X)</emphasis></term>
          <listitem>
            <para>
              The displayed message is one of the types listed above,
              but has been flagged as `experimental' by the Lintian
              maintainers.  This means that the code that generates
              this message is not as well tested as the rest of
              Lintian, and might still give surprising results.  Feel
              free to ignore Experimental messages that do not seem to
              make sense, though of course bug reports are always
              welcome.  They are not displayed unless
              the <option>-E</option> option is set.
            </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><emphasis>Overridden (O)</emphasis></term>
          <listitem>
            <para>
              The displayed message indicates a previous
              <emphasis>Warning</emphasis>
              or <emphasis>Error</emphasis> message which has been
              <emphasis>overridden</emphasis> (see below). They are
              not displayed unless
              the <option>--show-overrides</option> option is set.
            </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><emphasis>Pedantic (P)</emphasis></term>
          <listitem>
            <para>
              The displayed message indicates a message of Lintian at
              its most pickiest and include checks for particular
              Debian packaging styles, checks that are very frequently
              wrong, and checks that many people disagree with.  They
              are not displayed unless the <option>--pedantic</option>
              option is set.
            </para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>
        The type indicator is followed by the name of the package and
        for non-binary packages the type of the package.  Then comes
        the <emphasis>problem</emphasis> that was discovered, also
        known as a <emphasis>tag</emphasis> (for example,
        <literal>old-fsf-address-in-copyright-file</literal>).
      </para>
      <para>
        Depending on which tag has been reported, the line may contain
        additional arguments which tell you, for example, which files
        are involved.
      </para>
      <para>
        If you do not understand what a certain tag is about, you can
        specify the <option>-i</option> option when calling Lintian to
        get a detailed description of the reported tags:
      </para>
      <screen>
$ lintian -i libc5_5.4.38-1.deb
W: libc5: old-fsf-address-in-copyright-file
N:
N:   The /usr/share/doc/&lt;pkg&gt;/copyright file refers to the old postal
N:   address of the Free Software Foundation (FSF). The new address is:
N:   
N:     Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
N:     MA 02110-1301, USA.
N:   
N:   Severity: normal, Certainty: certain
N:
[...]
$
</screen>
      <para>
        In some cases, the messages contain some additional text with a
        leading hash character (<literal>#</literal>). This text should be ignored by any other
        programs which interpret Lintian's output because it doesn't follow a
        unique format between different messages and it's only meant as
        additional information for the maintainer.
      </para>
    </sect1>

    <sect1 label="2.4" id="section-2.4">
      <title>Overrides</title>
      <para>
        In some cases, the checked package does not have a bug or does
        not violate policy, but Lintian still reports an error or
        warning. This can have the following reasons: Lintian has a
        bug itself, a specific Lintian check is not smart enough to
        know about a special case allowed by policy, or the policy
        does allow exceptions to some rule in general.
      </para>
      <para>
        In the first case (where Lintian has a bug) you should send a
        bug report to the Debian bug tracking system and describe
        which package you checked, which messages have been displayed,
        and why you think Lintian has a bug. Best would be, if you
        would run Lintian again over your packages using
        the <option>-d</option> (or <option>--debug</option>) option,
        which will cause Lintian to output much more information
        (debugging info), and include these messages in your bug
        report. This will simplify the debugging process for the
        authors of Lintian.
      </para>
      <para>
        In the other two cases (where the error is actually an exception to
        policy), you should probably add an override. If you're unsure though whether
        it's indeed a good case for an override, you should contact the Lintian
        maintainers too, including the Lintian error message and a short note, stating
        why you think this is an exception. This way, the Lintian maintainers can be
        sure the problem is not actually a bug in Lintian or an error in the author's
        reading of policy. Please do not override bugs in lintian, they should rather
        be fixed than overridden.
      </para>
      <para>
        Once it has been decided that an override is needed, you can easily add one by
        supplying an overrides file. If the override is for a binary or udeb
        package, you have to place it at
        <filename>/usr/share/lintian/overrides/<replaceable>&lt;package&gt;</replaceable></filename>
        inside the package.  The tool <command>dh_lintian</command>
        from the Debian
        package <systemitem role="package">debhelper</systemitem> may
        be useful for this purpose.
      </para>
      <para>
        If the override is for a source package, you have to place it
        at <filename>debian/source/lintian-overrides</filename>
        or <filename>debian/source.lintian-overrides</filename> (the
        former path is preferred). With that, Lintian will know about
        this exception and not report the problem again when checking
        your package. (Actually, Lintian will report the problem
        again, but with type <emphasis>overridden</emphasis>, see
        above.)
      </para>
      <para>
        Note that Lintian extracts the override file from the (u)deb
        and stores it in the laboratory. The files currently installed
        on the system are not used in current Lintian versions.
      </para>
      <sect2 label="2.4.1" id="section-2.4.1">
        <title>Format of override files</title>
        <para>
          The format of the overrides file is simple, it consists of one override per
          line (and may contain empty lines and comments, starting with a <literal>#</literal>, on others):
          <literal>[[<replaceable>&lt;package&gt;</replaceable>][ <replaceable>&lt;archlist&gt;</replaceable>][ <replaceable>&lt;type&gt;</replaceable>]: ]<replaceable>&lt;lintian-tag&gt;</replaceable>[
            [*]<replaceable>&lt;lintian-info&gt;</replaceable>[*]]</literal>.  <replaceable>&lt;package&gt;</replaceable> is the package name;
          <replaceable>&lt;archlist&gt;</replaceable> is an
          architecture list (see Architecture specific overrides for
          more info);
          <replaceable>&lt;type&gt;</replaceable> is one of <literal>binary</literal>, <literal>udeb</literal> and
          <literal>source</literal>,
          and <replaceable>&lt;lintian-info&gt;</replaceable> is all
          additional information provided by Lintian except for the
          tag. What's inside brackets is optional and may be omitted if
          you want to match it all.  An example file for a binary
          package would look like:
        </para>
        <screen>
/usr/share/lintian/overrides/foo, where foo is the name of your package

# We use a non-standard dir permission to only allow the webserver to look
# into this directory:
foo binary: non-standard-dir-perm
foo binary: FSSTND-dir-in-usr /usr/man/man1/foo.1.gz
</screen>
        <para>An example file for a source package would look like:</para>
        <screen>
debian/source/lintian-overrides in your base source directory
foo source: debian-files-list-in-source
# Upstream distributes it like this, repacking would be overkill though, so
# tell lintian to not complain:
foo source: configure-generated-file-in-source config.cache
</screen>
        <para>
          Many tags can occur more than once (e.g. if the same error is
          found in more than one file). You can override a tag either
          completely by specifying its name (first line in the examples)
          or only one occurrence of it by specifying the additional
          info, too (second line in the examples).  If you add an
          asterisk (<literal>*</literal>) in the additional info, this
          will match arbitrary strings similar to the shell wildcard.
          For example:
        </para>
        <screen>
# The "help text" must also be covered by the override
source-is-missing apidoc/html/api_data.js *
</screen>
        <para>
          The first wildcard support appeared in Lintian 2.0.0, which
          only allowed the wildcards in the very beginning or end.
          Version 2.5.0~rc4 extended this to allow wildcards any where
          in the additional info.
        </para>
      </sect2>
      <sect2 label="2.4.2" id="section-2.4.2">
        <title>Documenting overrides</title>
        <para>
          To assist reviewers, Lintian will extract the comments from
          the overrides file and display the related comments next to
          the overridden tags.
        </para>
        <para>
          Comments directly above an override will be shown next to all
          tags it overrides.  If an override for the same tags appears
          on the very next line, it will inherit the comment from the
          override above it.
        </para>
        <screen>
# This comment will be shown above all tags overridden by the following
# two overrides, (because they apply to the same tag and there is no
# empty line between them)
foo source: some-tag exact match
foo source: some-tag wildcard * match
# This override has its own comment, and it is not shared with the
# override below (because there is an empty line in between them).
foo source: some-tag another exact match

foo source: some-tag override without a comment
</screen>
        <para>
          Empty lines can be used to disassociate a comment from an
          override following it.  This can also be used to make a general
          comment about the overrides that will not be displayed.
        </para>
        <screen>
# This is a general comment not connected to any override, since there
# is one (or more) empty lines after it.

foo source: another-tag without any comments
</screen>
      </sect2>
      <sect2 label="2.4.3" id="section-2.4.3">
        <title>Architecture specific overrides</title>
        <para>
          In rare cases, Lintian tags may be architecture specific.
          It is possible to mark overrides architecture specific by
          using the optional architecture list.
        </para>
        <para>
          The architecture list has the same syntax as the
          architecture list in the "Build-Depends" field of a source
          package. This is described in detail in the <ulink url="https://www.debian.org/doc/debian-policy/#s-controlsyntax">
          Debian Policy Manual §7.1</ulink>.  Examples:
        </para>
        <screen>
# This is an example override that only applies to the i386
# architecture.
foo [i386] binary: some-tag optional-extra

# An architecture wildcard would look like:
foo [any-i386] binary: another-tag optional-extra

# Negation also works
foo [!amd64 !i386] binary: some-random-tag optional-extra

# Negation even works for wildcards
foo [!any-i386] binary: some-tag-not-for-i386 optional-extra

# The package name and the package type is optional, so this
# also works
[linux-any]: tag-only-for-linux optional-extra.
</screen>
        <para>
          Support for architecture specific overrides was added in
          Lintian 2.5.0.  Wildcard support was added in 2.5.5.  Basic
          sanity checking was also added in 2.5.5, where unknown
          architectures trigger
          a <literal>malformed-override</literal> tag.  As does an
          architecture specific override for architecture independent
          packages.
        </para>
      </sect2>
    </sect1>
    <sect1 label="2.5" id="section-2.5">
      <title>Vendor Profiles</title>
      <para>
        Vendor profiles allows vendors and users to customize Lintian
        without having to modify the underlying code.  If a profile
        is not explicitly given, Lintian will derive the best
        possible profile for the current vendor from dpkg-vendor.
      </para>
      <sect2 label="2.5.1" id="section-2.5.1">
        <title>Rules for profile names and location</title>
        <para>
          Profile names should only consist of the lower case
          characters ([a-z]), underscore (_), dash (-) and
          forward slashes (/).  Particularly note that dot (.) are
          specifically <emphasis>not</emphasis> allowed in a
          profile name.
        </para>
        <para>
          The default profile for a vendor is called
          <filename>$VENDOR/main</filename>.  If Lintian sees a
          profile name without a slash, it is taken as a short
          form of the default profile for a vendor with that
          name.
        </para>
        <para>
          The filename for the profile is derived from the name by
          simply concatenating it with <filename>.profile</filename>,
          Lintian will then look for a file with that name in the
          following directories:
        </para>
        <itemizedlist>
          <listitem>
            <para>
              <filename>$XDG_DATA_HOME/lintian/profiles</filename>
            </para>
          </listitem>
          <listitem>
            <para>
              <filename>$HOME/.lintian/profiles</filename>
            </para>
          </listitem>
          <listitem>
            <para>
              <filename>/etc/lintian/profiles</filename>
            </para>
          </listitem>
          <listitem>
            <para>
              <filename>$LINTIAN_ROOT/profiles</filename>
            </para>
          </listitem>
        </itemizedlist>
        <para>
          Note that an implication of the handling of default
          vendor profiles implies that profiles must be in
          subdirectories of the directories above for Lintian
          to recognise them.
        </para>
        <para>
          The directories are checked in the listed order and the
          first file matching the profile will be used.  This allows
          users to override a system profile by putting one with the
          same filename
          in <filename>$XDG_DATA_HOME/lintian/profiles</filename>
          or <filename>$HOME/.lintian/profiles</filename>.
        </para>
      </sect2>
      <sect2 label="2.5.2" id="section-2.5.2">
        <title>Profile syntax and semantics</title>
        <para>
          Profiles are written in the same syntax as Debian
          control files as described in the
          <ulink url="https://www.debian.org/doc/debian-policy/#s-controlsyntax">
          Debian Policy Manual §5.1</ulink>.  Profiles allow
          comments as described in the Policy Manual.
        </para>
        <sect3 label="2.5.2.1" id="section-2.5.2.1">
          <title>Main profile paragraph</title>
          <para>
            The fields in the first paragraph are:
          </para>
          <variablelist>
            <varlistentry>
              <term><emphasis>Profile</emphasis> (simple, mandatory)</term>
              <listitem>
                <para>
                  Name of the profile.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Extends</emphasis> (simple, optional)</term>
              <listitem>
                <para>
                  Name of the (parent) profile, which this profile
                  extends.  Lintian will recursively process the
                  extended profile before continuing with processing
                  this profile.  In the absence of this field, the
                  profile is not based on another profile.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Load-Checks</emphasis> (folded, optional)</term>
              <listitem>
                <para>
                  Comma-separated list of checks.  Lintian will ensure
                  all checks listed are loaded (allowing tags from
                  them to be enabled or disabled via Enable-Tags or
                  Disable-Tags).
                </para>
                <para>
                  If a given check was already loaded before this
                  field is processed, then it is silently ignored.
                  Otherwise, the check is loaded and all of its tags
                  are disabled (as if it had been listed in
                  Disable-Tags-From-Check).
                </para>
                <para>
                  This field is most likely only useful if the profile
                  needs to enable a list of tags from a check in
                  addition to any tags already enabled from that
                  check (if any).
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Enable-Tags-From-Check</emphasis> (folded, optional)</term>
              <listitem>
                <para>
                  Comma-separated list of checks.  All tags from each
                  check listed will be enabled in this profile.  The check will
                  be loaded if it wasn't already.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Disable-Tags-From-Check</emphasis> (folded, optional)</term>
              <listitem>
                <para>
                Comma-separated list of checks.  All tags from each
                check listed will be disabled in this profile.  The check will
                be loaded if it wasn't already.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Enable-Tags</emphasis> (folded, optional)</term>
              <listitem>
                <para>
                  Comma-separated list of tags that should be enabled.
                  It may only list tags from checks already loaded or
                  listed in one of the following fields "Load-Checks",
                  "Enable-Tags-From-Check" or
                  "Disable-Tags-From-Check" in the current profile.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Disable-Tags</emphasis> (folded, optional)</term>
              <listitem>
                <para>
                  Comma-separated list of tags that should be
                  disabled.  It may only list tags from checks already
                  loaded or listed in one of the following fields
                  "Load-Checks", "Enable-Tags-From-Check" or
                  "Disable-Tags-From-Check" in the current profile.
                </para>
              </listitem>
            </varlistentry>
          </variablelist>
          <para>
            The profile is invalid and is rejected, if Enable-Tags and
            Disable-Tags lists the same tag twice - even if it is in
            the same field.  This holds analogously for checks and the
            three fields Load-Checks, Enable-Tags-From-Check and
            Disable-Tags-From-Check.
          </para>
          <para>
            It is allowed to list a tag in Enable-Tags or
            Disable-Tags even if the check that provides this tag is
            listed in the Disable-Tags-From-Check or
            Enable-Tags-From-Check field. In case of conflict,
            Enable-Tags / Disable-Tags shall overrule
            Disable-Tags-From-Check / Enable-Tags-From-Check within
            the profile.
          </para>
          <para>
            Load-Checks, Enable-Tags-From-Check and
            Disable-Tags-From-Check can be used to load third-party or
            vendor specific checks.
          </para>
          <para>
            It is not an error to load, enable or disable a check or
            tag that is already loaded, enabled or disabled
            respectively (e.g. by a parent profile).
          </para>
          <para>
            A profile is invalid if it directly or indirectly extends
            itself or if it extends an invalid profile.
          </para>
          <para>
            By default the tags from the check "lintian" will be loaded
            as they assist people in writing and maintaining their
            overrides file (e.g. by emitting <literal>malformed-override</literal>).
            However, they can be disabled by explicitly adding the check
            <literal>lintian</literal> in the Disable-Tags-From-Check field.
          </para>
        </sect3>
        <sect3 label="2.5.2.2" id="section-2.5.2.2">
          <title>Tag alteration paragraphs</title>
          <para>
            The fields in the secondary paragraphs are:
          </para>
          <variablelist>
            <varlistentry>
              <term><emphasis>Tags</emphasis> (folded, mandatory)</term>
              <listitem>
                <para>
                  Comma separated list of tags affected by this
                  paragraph.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Overridable</emphasis> (simple, optional)</term>
              <listitem>
                <para>
                  Either "Yes" or "No", which decides whether these
                  tags can be overridden.  Lintian will print an
                  informal message if it sees an override for a tag
                  marked as non-overridable (except if --quiet is
                  passed).
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Severity</emphasis> (simple, optional)</term>
              <listitem>
                <para>
                  The value must be a valid tag severity other than "classification".
                  The severity of the affected tags is set to this value.  This
                  cannot be used on any tag that is defined as a "classification" tag.
                </para>
                <para>
                  Note that <emphasis>experimental</emphasis> is not a
                  severity.
                </para>
              </listitem>
            </varlistentry>
          </variablelist>
          <para>
            The paragraph must contain at least one other field than the
            Tag field.
          </para>
        </sect3>
        <sect3 label="2.5.2.3" id="section-2.5.2.3">
          <title>An example vendor profile</title>
          <para>
            Below is a small example vendor profile for a fictive
            vendor called "my-vendor".
          </para>
          <screen>
# The default profile for "my-vendor"
Profile: my-vendor/main
# It has all the checks and settings from the "debian" profile
Extends: debian/main
# Add checks specific to "my-vendor"
Enable-Tags-From-Check:
  my-vendor/some-check,
  my-vendor/another-check,
# Disable a tag
Disable-Tags: dir-or-file-in-opt

# Bump severity of no-md5sums-control-file
# and file-missing-in-md5sums and make them
# non-overridable
Tags: no-md5sums-control-file,
      file-missing-in-md5sums,
Severity: serious
Overridable: no
</screen>
        </sect3>
      </sect2>
    </sect1>
    <sect1 label="2.6" id="section-2.6">
      <title>Vendor specific data files</title>
      <para>
        Lintian uses a number of data files for various checks,
        ranging from common spelling mistakes to lists of
        architectures.  While some of these data files are generally
        applicable for all vendors (or Debian derivatives), others
        are not.
      </para>
      <para>
        Starting with version 2.5.7, Lintian supports vendor
        specific data files.  This allows vendors to deploy their
        own data files tailored for their kind of system.  Lintian
        supports both extending an existing data file and completely
        overriding it.
      </para>
      <sect2 label="2.6.1" id="section-2.6.1">
        <title id="section-2.6.1-title">Load paths and order</title>
        <para>
          Lintian will search the following directories in order for
          vendor specific data files:
        </para>
        <itemizedlist>
          <listitem>
            <para>
              <filename>$XDG_DATA_HOME/lintian/vendors/<replaceable>PROFILENAME</replaceable>/data</filename>
            </para>
          </listitem>
          <listitem>
            <para>
              <filename>$HOME/.lintian/vendors/<replaceable>PROFILENAME</replaceable>/data</filename>
            </para>
          </listitem>
          <listitem>
            <para>
              <filename>/etc/lintian/vendors/<replaceable>PROFILENAME</replaceable>/data</filename>
            </para>
          </listitem>
          <listitem>
            <para>
              <filename>$LINTIAN_ROOT/vendors/<replaceable>PROFILENAME</replaceable>/data</filename>
            </para>
          </listitem>
          </itemizedlist>
        <para>
          If none of the directories exists or none of them provide
          the data file in question, Lintian will (recursively)
          retry with the parent of the vendor (if any).  If the
          vendor and none of its parents provide the data file,
          Lintian will terminate with an error.
        </para>
      </sect2>
      <sect2 label="2.6.2" id="section-2.6.2">
        <title>Basic syntax of data files</title>
        <para>
          Generally, data files are read line by line.  Leading
          whitespace of every line is removed and (now) empty lines
          are ignored.  Lines starting with a <literal>#</literal>
          are comments and are also ignored by the parser.  Lines
          are processed in the order they are read.
        </para>
        <para>
          If the first character of the line is
          a <literal>@</literal>, the first word is parsed as a
          special processing instruction.  The rest of the line
          is a parameter to that processing instruction.  Please
          refer to <xref linkend="section-2.6.2.1" endterm="section-2.6.2.1-title" />.
        </para>
        <para>
          All other lines are read as actual data.  If the data file
          is a table (or map), the lines will parsed as key-value
          pairs.  If the data file is a list (or set), the full line
          will be considered a single value of the list.
        </para>
        <para>
          It is permissible to define the same key twice with a
          different value.  In this case, the value associated with
          the key is generally redefined.  There are very rare
          exceptions to this rule, where the data file is a table of
          tables (of values).  In this case, a recurring key is used to
          generate the inner table.
        </para>

        <sect3 label="2.6.2.1" id="section-2.6.2.1">
          <title id="section-2.6.2.1-title">List of processing instructions</title>
          <para>
            The following processing instructions are recognised:
          </para>
          <variablelist>
            <varlistentry>
              <term><emphasis>@delete <replaceable>ENTRY</replaceable></emphasis></term>
              <listitem>
                <para>
                  Removes a single entry denoted by <replaceable>ENTRY</replaceable> that
                  has already been parsed.
                </para>
                <para>
                  It is permissible to list a non-existent entry, in which case the
                  instruction has no effect. This instruction does
                  <emphasis>not</emphasis> prevent the entry from being (re-)defined later,
                  it only affects the current definition of the entry.
                </para>
                <para>
                  For key-pair based data files, <replaceable>ENTRY</replaceable> must
                  match the key.  For single value data files,
                  <replaceable>ENTRY</replaceable> must match the line to remove.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>@include-parent</emphasis></term>
              <listitem>
                <para>
                  Processes parent data file of the current data file.
                </para>
                <para>
                  The informal semantics of this instruction is that it reads the "next"
                  data file in the vendor "chain".  The parsing of the parent is comparable
                  to a C-style include or sourcing a shell script.
                </para>
                <para>
                  More formally, let <replaceable>CP</replaceable> be the name of the vendor
                  profile that defines the data file containing the instruction.  Let
                  the parent of <replaceable>CP</replaceable> be referred to as
                  <replaceable>PCP</replaceable>.
                </para>
                <para>
                  Lintian will search for the data file provided by
                  <replaceable>PCP</replaceable> using the rules as specified in
                  <xref linkend="section-2.6.1" endterm="section-2.6.1-title" />.  If no
                  data file is found, Lintian will terminate the parsing with an error.
                  Thus, this instruction can only be used by profiles that extends other
                  profiles.
                </para>
              </listitem>
            </varlistentry>
          </variablelist>
        </sect3>
      </sect2>
    </sect1>
  </chapter>

  <chapter label="3" id="chapter-3">
    <title>Advanced usage</title>
    <sect1 label="3.1" id="section-3.1">
      <title>How Lintian works</title>
      <para>Lintian is divided into the following layers:</para>
      <variablelist>
        <varlistentry>
          <term><emphasis>frontend</emphasis></term>
          <listitem>
            <para>
              the command line interface (currently, this layer
              consists of two scripts,
              namely <command>lintian</command>
              and <command>lintian-info</command>)
             </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><emphasis>checks</emphasis></term>
          <listitem>
            <para>
              a set of modules that check different aspects of packages.
            </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><emphasis>data collectors</emphasis></term>
          <listitem>
            <para>
              a set of scripts that prepares specific information
              about a package needed by the check modules
            </para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>
        When you check a package with Lintian, the following steps are
        performed (not exactly in this order&mdash;but the details aren't important
        now):
      </para>
      <orderedlist numeration="arabic">
        <listitem>
          <para>
            An entry is created for the package in
            the <emphasis>laboratory</emphasis> (or
            just <emphasis>lab</emphasis>).
          </para>
        </listitem>
        <listitem>
          <para>
            Some data is collected about the package. (That is done by
            the so-called <emphasis>data collector</emphasis>
            scripts.) For example, the <command>file</command> program
            is run on each file in the package and the output is
            stored in the lab.
          </para>
        </listitem>
        <listitem>
          <para>
            The <emphasis>checks</emphasis> are run over the package
            and report any discovered policy violations or other
            errors. These scripts don't access the package contents
            directly, but use the collected data as input.
          </para>
        </listitem>
        <listitem>
          <para>
            Depending on the <emphasis>lab mode</emphasis> Lintian
            uses (see below), the whole lab directory is removed
            again.  If the lab is not removed, parts of the data
            collected may be auto cleaned to reduce disk space.
          </para>
        </listitem>
      </orderedlist>
      <para>
        This separation of the <emphasis>check</emphasis>
        from the <emphasis>data collector scripts</emphasis> makes it
        possible to run Lintian several times over a package without
        having to recollect all the data each time. In addition, the
        checker scripts do not have to worry about packaging details
        since this is abstracted away by the collector scripts.
      </para>
    </sect1>

    <sect1 label="3.2" id="section-3.2">
      <title>The laboratory</title>
      <para>
        Lintian creates a temporary lab in
        <filename class="directory">/tmp</filename> which is removed
        again after Lintian has completed its checks, unless the
        <option>--keep-lab</option> is used.
      </para>
    </sect1>

    <sect1 label="3.3" id="section-3.3">
      <title>Writing your own Lintian checks</title>
      <para>
        This section describes how to write and deploy your own
        Lintian checks.  Lintian will load checks from the following
        directories (in order):
      </para>
      <itemizedlist>
        <!-- FIXME: re-add this when aptdaemon (etc.) is ready for it
             LP: #1162947
          -->
        <!--listitem>
          <para>
            <filename>$HOME/.lintian/checks</filename>
          </para>
        </listitem>
        <listitem>
          <para>
            <filename>/etc/lintian/checks</filename>
          </para>
        </listitem-->
        <listitem>
          <para>
            <filename>$LINTIAN_ROOT/checks</filename>
          </para>
        </listitem>
      </itemizedlist>
      <para>
        Existing checks can be shadowed by placing a check with the
        same name in a directory appearing earlier in the list.  This
        also holds for the checks provided by Lintian itself.
      </para>
      <para>
        Checks in Lintian consist of a description file (.desc) and a
        Perl module implementing the actual check (.pm).  The
        names of these checks must consist entirely of the lower case
        characters ([a-z]), digits ([0-9]), underscore (_), dash (-),
        period (.) and forward slashes (/).
      </para>
      <para>
        The check name must be a valid Perl unique module name after
        the following transformations.  All periods and dashes are
        replaced with underscores.  All forward slashes are replaced
        with two colons (::).
      </para>
      <para>
        Check names without a forward slash (e.g. "fields") and names
        starting with either "lintian/" or "coll/" are reserved for
        the Lintian core.  Vendors are recommended to use their vendor
        name before the first slash (e.g. "ubuntu/fields").
      </para>
      <sect2 label="3.3.1" id="section-3.3.1">
        <title>Check description file</title>
        <para>
          The check description file is written in the same syntax as
          Debian control files as described in the
          <ulink url="https://www.debian.org/doc/debian-policy/#s-controlsyntax">
          Debian Policy Manual §5.1</ulink>.  Check description files
          allow comments as described in the Policy Manual.
        </para>
        <para>
          The check description file has two paragraph types.  The
          first is the check description itself and must be the first
          paragraph.  The rest of the descriptions describe tags, one
          tag per paragraph.
        </para>
        <sect3 label="3.3.1.1" id="section-3.3.1.1">
          <title>Check description paragraph</title>
          <para>
            The fields in the check description paragraph are:
          </para>
          <variablelist>
            <varlistentry>
              <term><emphasis>Check-Script</emphasis> (simple, mandatory)</term>
              <listitem>
                <para>
                  Name of the check.  This is used to determine the
                  package name of the Perl module implementing the
                  check.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Type</emphasis> (simple, mandatory)</term>
              <listitem>
                <para>
                  Comma separated list of package types for which this
                  check should be run.  Allowed values in the list are
                  "binary" (.deb files), "changes" (.changes files),
                  "source" (.dsc files) and "udeb" (.udeb files).
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Needs-Info</emphasis> (simple, optional)</term>
              <listitem>
                <para>
                  Comma separated list of collections required for the
                  check to be run.  Common values here include "unpacked",
                  "index" and "file-info".
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Info</emphasis> (multiline, optional)</term>
              <listitem>
                <para>
                  A short description of what the check is for.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Author</emphasis> (simple, optional)</term>
              <listitem>
                <para>
                  Name and email of the person, who created (or
                  implemented etc.) the check.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Abbrev</emphasis> (simple, optional)</term>
              <listitem>
                <para>
                  Alternative or abbreviated name of the check.  These
                  can be used with certain command line options as an
                  alternative name for the check.
                </para>
              </listitem>
            </varlistentry>
          </variablelist>
        </sect3>
        <sect3 label="3.3.1.2" id="section-3.3.1.2">
          <title>Tag description paragraph</title>
          <para>
            The fields in the tag description paragraph are:
          </para>
          <variablelist>
            <varlistentry>
              <term><emphasis>Tag</emphasis> (simple, mandatory)</term>
              <listitem>
                <para>
                  Name of the tag.  It must consist entirely of the
                  lower or/and upper case characters ([a-zA-Z]),
                  digits ([0-9]), underscore (_), dash (-) and period (.).
                  The tag name should be at most 68 characters long.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Severity</emphasis> (simple, mandatory)</term>
              <listitem>
                <para>
                  Determines the default value for how "severe" the
                  tag is.  The value must be one of "serious",
                  "important", "normal", "minor", "wishlist" and
                  "pedantic".  The effective severity and the value of
                  the Certainty field of a tag determine the
                  "one-letter" code (of non-experimental tags).
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Certainty</emphasis> (simple, mandatory)</term>
              <listitem>
                <para>
                  How accurate the tag is (believed to be).  The value
                  must be one of "certain", "possible", "wild-guess".
                  The effective severity and the value of the
                  Certainty field of a tag determine the "one-letter"
                  code (of non-experimental tags).
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Info</emphasis> (multiline, mandatory)</term>
              <listitem>
                <para>
                  The description of the tag, which can be seen by
                  using lintian-info (etc.).  The HTML tags
                  "&lt;tt&gt;" and "&lt;i&gt;" may be used in the
                  description.
                </para>
                <para>
                  The symbols &amp;, &lt; and &gt; must be escaped as
                  &amp;amp;, &amp;lt; and &amp;gt; (respectively).
                </para>
                <para>
                  Indented lines are considered "pre-formatted" and
                  will not be line wrapped.  These lines are still
                  subject to the allowed HTML tags and above mentioned
                  escape sequences.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Ref</emphasis> (simple, optional)</term>
              <listitem>
                <para>
                  A comma separated list of references.  It can be used
                  to refer to extra documentation.  It is primarily
                  used for manual references, HTTP links or Debian bug
                  references.
                </para>
                <para>
                  If a reference contains a space, it is taken as a
                  manual reference (e.g. "policy 4.14").  These
                  references are recorded in the
                  "output/manual-references" data file.
                </para>
                <para>
                  Other references include manpages ("lintian(1)"),
                  ftp or http(s) links ("https://lintian.debian.org"),
                  file references ("/usr/share/doc/lintian/changelog.gz")
                  or Debian bug numbers prefixed with a hash ("#651816").
                </para>
                <para>
                  Unknown references are (silently) ignored.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term><emphasis>Experimental</emphasis> (simple, optional)</term>
              <listitem>
                <para>
                  Whether or not the tag is considered "experimental".
                  Recognised values are "no" (default) and "yes".
                  Experimental tags always use "X" as their
                  "one-letter" code.
                </para>
              </listitem>
            </varlistentry>
          </variablelist>
        </sect3>
      </sect2>
      <sect2 label="3.3.2" id="section-3.3.2">
        <title>Check Perl module file</title>
        <para>
          This section describes the requirements for the Perl module
          implementing a given check.
        </para>
        <para>
          The Perl package name of the check must be identical to
          the check name (as defined by the "Check-Script" field in
          the description file) with the following transformations:
        </para>
        <itemizedlist>
          <listitem>
            <para>All periods and dashes are replaced with underscores.</para>
          </listitem>
          <listitem>
            <para>All forward slashes are replaced by two colons (::).</para>
          </listitem>
          <listitem>
            <para>The resulting value is prefixed with "Lintian::".</para>
          </listitem>
        </itemizedlist>
        <para>
          As an example, the check name <literal>contrib/hallo-world</literal>
          will result in the Perl package name
          <literal>Lintian::contrib::hallo_world</literal>.
        </para>
        <sect3 label="3.3.2.1" id="section-3.3.2.1">
          <title>API of the "run" sub</title>
          <para>
            The Perl module must implement the sub called <literal>run</literal> in
            that Perl package.  This sub will be run once for each package to be
            checked with 5 arguments.  These are (in order):
          </para>
          <itemizedlist>
            <listitem>
              <para>The package name.</para>
            </listitem>
            <listitem>
              <para>
                The package type being checked in this run.  This string
                is one of "binary" (.deb), "changes" (.changes), "source"
                (.dsc) or "udeb" (.udeb).
              </para>
            </listitem>
            <listitem>
              <para>
                An instance of API Lintian::Collect.  Its exact type depends
                on the type being processed and is one of
                Lintian::Collect::Binary (.deb or .udeb),
                Lintian::Collect::Changes (.changes) or
                Lintian::Collect::Source (.dsc).
              </para>
            </listitem>
            <listitem>
              <para>
                An instance of Lintian::Processable that represents the
                package being processed.
              </para>
            </listitem>
            <listitem>
              <para>
                An instance of Lintian::ProcessableGroup that represents
                the other processables in the given group.  An instance
                of the Lintian::Collect::Group is available via its
                "info" method.
              </para>
            </listitem>
          </itemizedlist>
          <para>
            Further arguments may be added in the future after the above
            mentioned ones.  Implementations should therefore ignore
            extra arguments beyond the ones they know of.
          </para>
          <para>
            If the run sub returns "normally", the check was run
            successfully.  Implementations should ensure the return
            value is undefined.
          </para>
          <para>
            If the run sub invokes a trappable error (e.g. "die"), no
            further checks are done on the package and Lintian will
            (eventually) exit with 2 to its caller.  The check may
            still be run on other packages.
          </para>
          <para>
            The run sub may emit tags by invoking the sub "tag" from
            Lintian::Tags (it can be imported).  The first argument is
            the name of the tag to emit.  Any extra arguments will be
            used as the "tag extra" (or diagnostics).  Example:
          </para>
          <programlisting>
use Lintian::Tags qw(tag);
sub run {
    tag 'my-tag', 'hallo world';
    return;
}
</programlisting>
          <para>
            would emit the tag "my-tag" with the extra note "hallo
            world" like this:
          </para>
          <screen>
I: package: my-tag hallo world
</screen>
        </sect3>
      </sect2>
    </sect1>


  </chapter>
</book><!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-indent-step:1
sgml-indent-data:nil
End:
-->
