Esempio n. 1
0
File: vcs.py Progetto: KDE/pology
    def export (self, path, rev, dstpath, rewrite=None):
        # Base override.

        if rev is None:
            res = collect_system(["svn", "export", "--force", self._ep(path),
                                  "-r", "BASE", dstpath])
            if res[-1] != 0:
                return False
            return True

        res = collect_system(["svn", "info", self._ep(path)], env=self._env)
        if res[-1] != 0:
            return False
        rx = re.compile(r"^URL:\s*(\S+)", re.I)
        rempath = None
        for line in res[0].split("\n"):
            m = rx.search(line)
            if m:
                rempath = m.group(1)
                break
        if not rempath:
            return False

        if rewrite:
            rempath = rewrite(rempath, rev)

        if collect_system(["svn", "export", "--force", self._ep(rempath),
                           "-r", rev, dstpath])[-1] != 0:
            return False

        return True
Esempio n. 2
0
    def translate(self, texts):

        # Serialize texts to send to Apertium in one go.
        # Separate texts with an inplace tag followed by dot,
        # to have each text interpreted as standalone sentence.
        # FIXME: Any way to really translate each text in turn,
        # without it being horribly slow?
        sep0 = "<br class='..."
        sep1 = "..."
        sep2 = "'/>."
        sep = None
        nsep = 0
        while not sep:  # determine shortest acceptable separator
            sep = sep0 + sep1 * nsep + sep2
            for text in texts:
                if sep in text:
                    sep = None
                    nsep += 1
                    break
        stext = sep.join(texts)

        # Translate empty string to test language pair.
        # Otherwise, if a lot of text is sent and language pair not good,
        # Apertium may just signal broken pipe.
        res = collect_system(self.cmdline, instr="")
        if res[2] != 0:
            warning(
                _("@info",
                  "Executing Apertium failed:\n%(output)s",
                  output=res[0]))
            # ...really res[0], error is output to stdout. Tsk.
            return None

        res = collect_system(self.cmdline, instr=stext)
        if res[2] != 0:
            warning(
                _("@info",
                  "Executing Apertium failed:\n%(output)s",
                  output=res[0]))
            # ...really res[0], error is output to stdout. Tsk.
            return None

        texts_tr = res[0].split(sep)
        if len(texts_tr) != len(texts):
            warning(
                _("@info", "Apertium reported wrong number of translations, "
                  "%(num1)d instead of %(num2)d.",
                  num1=len(texts_tr),
                  num2=len(texts)))
            return None

        texts_tr = [
            resolve_entities_simple(x, self.htmlents) for x in texts_tr
        ]

        return texts_tr
Esempio n. 3
0
File: vcs.py Progetto: KDE/pology
    def log (self, path, rev1=None, rev2=None):
        # Base override.

        res = collect_system(["svn", "log", self._ep(path)], env=self._env)
        if res[-1] != 0:
            return []
        rev = ""
        next_rev, next_cmsg = range(2)
        entries = []
        next = -1
        for line in res[0].strip().split("\n"):
            if line.startswith("----------"):
                if rev:
                    cmsg = "\n".join(cmsg).strip("\n")
                    entries.append((rev, user, dstr, cmsg))
                cmsg = []
                next = next_rev
            elif next == next_rev:
                lst = line.split("|")
                rev, user, dstr = [x.strip() for x in lst[:3]]
                rev = rev[1:] # strip initial "r"
                next = next_cmsg
            elif next == next_cmsg:
                cmsg += [line]

        entries.reverse()

        return _crop_log(entries, rev1, rev2)
Esempio n. 4
0
File: vcs.py Progetto: KDE/pology
    def export (self, path, rev, dstpath, rewrite=None):
        # Base override.

        root, path = self._gitroot(path)
        ret = True

        if rev is None:
            rev = "HEAD"

        if rewrite:
            path = rewrite(path, rev)

        # FIXME: Better temporary location."
        # FIXME: Use list command lines (so must replace piping too).
        tarpdir = "/tmp"
        tarbdir = "git-archive-tree%d" % os.getpid()
        res = collect_system("  git archive --prefix=%s/ %s %s "
                             "| (cd %s && tar xf -)"
                             % (tarbdir, rev, path, tarpdir),
                             wdir=root)
        if res[2] == 0:
            tardir = os.path.join(tarpdir, tarbdir)
            tarpath = os.path.join(tardir, path)
            try:
                shutil.move(tarpath, dstpath)
            except:
                ret = False
            if os.path.isdir(tardir):
                shutil.rmtree(tardir)
        else:
            ret = False

        return ret
Esempio n. 5
0
File: vcs.py Progetto: KDE/pology
    def move (self, spath, dpath):
        # Base override.

        if collect_system(["svn", "move", "--parents",
                           self._ep(spath), dpath])[2] != 0:
            return False
        return True
Esempio n. 6
0
File: vcs.py Progetto: KDE/pology
    def is_clear (self, path):
        # Base override.

        res = collect_system(["svn", "status", path], env=self._env)
        clear = not re.search(r"^\S", res[0])

        return clear
Esempio n. 7
0
File: vcs.py Progetto: KDE/pology
    def remove (self, path):
        # Base override.

        if collect_system(["svn", "remove", path])[2] != 0:
            return False

        return True
Esempio n. 8
0
File: vcs.py Progetto: KDE/pology
    def _paths_to_commit (self, root, path=None):

        if path:
            cmdline = ["git", "status", path]
        else:
            cmdline = ["git", "status"]
        res = collect_system(cmdline, wdir=root, env=self._env)

        sect_rx = re.compile(r"^(?:# )?(\S.*):$", re.I)
        file_rx = re.compile(r"^#?\s+.*\w:\s*(.+?)\s*$", re.I)
        inlist = False
        ipaths = []
        for line in res[0].split("\n"):
            m = sect_rx.search(line)
            if m:
                mstr = m.group(1)
                if (   mstr.endswith("to be committed") # git 1.6.x
                    or mstr.endswith("but not updated") # git 1.7.x
                    or mstr.endswith("not staged for commit") # git 1.7.x
                ):
                    inlist = True
                else:
                    break
            if not inlist:
                continue
            m = file_rx.search(line)
            if m:
                ipaths.append(m.group(1))

        return ipaths
Esempio n. 9
0
File: vcs.py Progetto: KDE/pology
    def log (self, path, rev1=None, rev2=None):
        # Base override.

        root, path = self._gitroot(path)

        res = collect_system(["git", "log", path], wdir=root, env=self._env)
        if res[-1] != 0:
            return []
        rev = ""
        next_auth, next_date, next_cmsg = range(3)
        next = -1
        entries = []
        lines = res[0].split("\n")
        for i in range(len(lines) + 1):
            if i < len(lines):
                line = lines[i]
            if i == len(lines) or line.startswith("commit"):
                if rev:
                    cmsg = "\n".join(cmsg).strip("\n")
                    entries.append((rev, user, dstr, cmsg))
                rev = line[line.find(" ") + 1:].strip()
                cmsg = []
                next = next_auth
            elif next == next_auth:
                user = line[line.find(":") + 1:].strip()
                next = next_date
            elif next == next_date:
                dstr = line[line.find(":") + 1:].strip()
                next = next_cmsg
            elif next == next_cmsg:
                cmsg += [line[4:]]

        entries.reverse()

        return _crop_log(entries, rev1, rev2)
Esempio n. 10
0
File: vcs.py Progetto: KDE/pology
    def revert (self, path):
        # Base override.

        res = collect_system(["svn", "revert", "-R", path], env=self._env)
        if res[-1] != 0:
            warning(_("@info",
                      "Subversion reports it cannot revert path '%(path)s':\n"
                      "%(msg)s",
                      path=path, msg=res[1]))
            return False

        return True
Esempio n. 11
0
File: vcs.py Progetto: KDE/pology
    def revert (self, path):
        # Base override.

        res = collect_system(["git", "checkout", path],
                             wdir=root, env=self._env)
        if res[-1] != 0:
            warning(_("@info"
                      "Git reports it cannot revert path '%(path)s':\n"
                      "%(msg)s",
                      path=path, msg=res[1]))
            return []

        return True
Esempio n. 12
0
File: vcs.py Progetto: KDE/pology
    def is_versioned (self, path):
        # Base override.

        res = collect_system(["svn", "info", self._ep(path)], env=self._env)
        if res[-1] != 0:
            return False

        rx = re.compile(r"^Repository", re.I)
        for line in res[0].split("\n"):
            if rx.search(line):
                return True

        return False
Esempio n. 13
0
File: vcs.py Progetto: KDE/pology
    def revision (self, path):
        # Base override.

        res = collect_system(["svn", "info", self._ep(path)], env=self._env)
        rx = re.compile(r"^Last Changed Rev: *([0-9]+)", re.I)
        revid = ""
        for line in res[0].split("\n"):
            m = rx.search(line)
            if m:
                revid = m.group(1)
                break

        return revid
Esempio n. 14
0
File: vcs.py Progetto: KDE/pology
    def to_commit (self, path):
        # Base override.

        res = collect_system(["svn", "status", path], env=self._env)
        if res[-1] != 0:
            return []

        ncpaths = []
        for line in res[0].split("\n"):
            if line[:1] in ("A", "M"):
                path = line[1:].strip()
                ncpaths.append(path)

        return ncpaths
Esempio n. 15
0
File: vcs.py Progetto: KDE/pology
    def move (self, spath, dpath):
        # Base override.

        root1, spath = self._gitroot(spath)
        root2, dpath = self._gitroot(dpath)
        if root1 != root2:
            warning(_("@info",
                      "Trying to move paths between different repositories."))
            return False

        if collect_system(["git", "mv", spath, dpath], wdir=root1)[2] != 0:
            return False

        return True
Esempio n. 16
0
File: vcs.py Progetto: KDE/pology
    def revision (self, path):
        # Base override.

        root, path = self._gitroot(path)

        res = collect_system(["git", "log", path], wdir=root, env=self._env)
        rx = re.compile(r"^commit\s*([0-9abcdef]+)", re.I)
        revid = ""
        for line in res[0].split("\n"):
            m = rx.search(line)
            if m:
                revid = m.group(1)
                break

        return revid
Esempio n. 17
0
File: vcs.py Progetto: KDE/pology
    def remove (self, path):
        # Base override.

        if os.path.isdir(path):
            warning(_("@info",
                      "Git cannot remove directories (tried on '%(path)s').",
                      path=path))
            return False

        root, path = self._gitroot(path)

        if collect_system(["git", "rm", path], wdir=root)[2] != 0:
            return False

        return True
Esempio n. 18
0
File: vcs.py Progetto: KDE/pology
    def diff (self, path, rev1=None, rev2=None):
        # Base override.

        root, path = self._gitroot(path)

        if rev1 is not None and rev2 is not None:
            rspec = "%s..%s" % (rev1, rev2)
        elif rev1 is not None:
            rspec = "%s" % rev1
        elif rev2 is not None:
            raise PologyError(
                _("@info"
                  "Git cannot diff from non-staged paths to a commit."))
        else:
            rspec = ""

        res = collect_system(["git", "diff", rspec, path],
                             wdir=root, env=self._env)
        if res[-1] != 0:
            warning(_("@info"
                      "Git reports it cannot diff path '%(path)s':\n"
                      "%(msg)s",
                      path=path, msg=res[1]))
            return []

        udiff = []
        nskip = 0
        for line in res[0].split("\n"):
            if nskip > 0:
                nskip -= 1
                continue

            if line.startswith("diff"):
                m = re.search(r"a/(.*?) *b/", line)
                udiff.append((":", m.group(1) if m else ""))
                nskip = 3
            elif line.startswith("@@"):
                m = re.search(r"-(\d+),(\d+) *\+(\d+),(\d+)", line)
                spans = tuple(map(int, m.groups())) if m else (0, 0, 0, 0)
                udiff.append(("@", spans))
            elif line.startswith(" "):
                udiff.append((" ", line[1:]))
            elif line.startswith("-"):
                udiff.append(("-", line[1:]))
            elif line.startswith("+"):
                udiff.append(("+", line[1:]))

        return udiff
Esempio n. 19
0
File: vcs.py Progetto: KDE/pology
    def is_versioned (self, path):
        # Base override.

        root, path = self._gitroot(path)
        if not path:
            return True

        res = collect_system(["git", "status"], wdir=root, env=self._env)
        rx = re.compile(r"untracked.*?:", re.I)
        m = rx.search(res[0])
        if m:
            for line in res[0][m.end():].split("\n"):
                line = line.lstrip("#").strip()
                if line == path:
                    return False

        return True
Esempio n. 20
0
File: vcs.py Progetto: KDE/pology
    def diff (self, path, rev1=None, rev2=None):
        # Base override.

        if rev1 is not None and rev2 is not None:
            rspec = "-r %s:%s" % (rev1, rev2)
        elif rev1 is not None:
            rspec = "-r %s" % rev1
        elif rev2 is not None:
            raise PologyError(
                _("@info \"Subversion\" is a version control system",
                  "Subversion cannot diff from working copy "
                  "to a named revision."))
        else:
            rspec = ""

        res = collect_system(["svn", "diff", path, rspec], env=self._env)
        if res[-1] != 0:
            warning(_("@info",
                      "Subversion reports it cannot diff path '%(path)s':\n"
                       "%(msg)s",
                       path=path, msg=res[1]))
            return []

        udiff = []
        nskip = 0
        for line in res[0].split("\n"):
            if nskip > 0:
                nskip -= 1
                continue

            if line.startswith("Index:"):
                udiff.append((":", line[line.find(":") + 1:].strip()))
                nskip = 3
            elif line.startswith("@@"):
                m = re.search(r"-(\d+),(\d+) *\+(\d+),(\d+)", line)
                spans = tuple(map(int, m.groups())) if m else (0, 0, 0, 0)
                udiff.append(("@", spans))
            elif line.startswith(" "):
                udiff.append((" ", line[1:]))
            elif line.startswith("-"):
                udiff.append(("-", line[1:]))
            elif line.startswith("+"):
                udiff.append(("+", line[1:]))

        return udiff
Esempio n. 21
0
File: vcs.py Progetto: KDE/pology
    def is_clear (self, path):
        # Base override.

        root, path = self._gitroot(path)

        res = collect_system(["git", "status", path], wdir=root, env=self._env)
        rx = re.compile(r"\bmodified:\s*(\S.*)", re.I)
        for line in res[0].split("\n"):
            m = rx.search(line)
            if m:
                mpath = m.group(1)
                if os.path.isfile(path):
                    if mpath == path:
                        return False
                else:
                    if not path or mpath[len(path):].startswith(os.path.sep):
                        return False

        return True
Esempio n. 22
0
File: vcs.py Progetto: KDE/pology
    def add (self, paths, repadd=False):
        # Base override.

        if isinstance(paths, basestring):
            paths = [paths]
        if not paths:
            return True

        root, paths = self._gitroot(paths)

        success = True
        apaths = []
        for path in paths:
            if collect_system(["git", "add", path], wdir=root)[2] != 0:
                success = False
                break
            apaths.append(path)

        return success if not repadd else [success, apaths]
Esempio n. 23
0
File: vcs.py Progetto: KDE/pology
    def add (self, paths, repadd=False):
        # Base override.

        if isinstance(paths, basestring):
            paths = [paths]
        if not paths:
            return True

        tmppath = _temp_paths_file(paths)
        res = collect_system(["svn", "add", "--force", "--parents",
                              "--targets", tmppath],
                             env=self._env)
        success = (res[2] == 0)
        os.remove(tmppath)

        if repadd:
            apaths = []
            for line in res[0].split("\n"):
                if line.startswith("A"):
                    apaths.append(line[1:].strip())
            return success, apaths
        else:
            return success
Esempio n. 24
0
def main():

    locale.setlocale(locale.LC_ALL, "")

    # Get defaults for command line options from global config.
    cfgsec = pology_config.section("posieve")
    def_do_skip = cfgsec.boolean("skip-on-error", True)
    def_msgfmt_check = cfgsec.boolean("msgfmt-check", False)
    def_skip_obsolete = cfgsec.boolean("skip-obsolete", False)

    # Setup options and parse the command line.
    usage = _("@info command usage",
              "%(cmd)s [OPTIONS] SIEVE [POPATHS...]",
              cmd="%prog")
    desc = _(
        "@info command description",
        "Apply sieves to PO paths, which may be either single PO files or "
        "directories to search recursively for PO files. "
        "Some of the sieves only examine PO files, while others "
        "modify them as well. "
        "The first non-option argument is the sieve name; "
        "a list of several comma-separated sieves can be given too.")
    ver = _("@info command version", u"%(cmd)s (Pology) %(version)s\n"
            u"Copyright © 2007, 2008, 2009, 2010 "
            u"Chusslove Illich (Часлав Илић) &lt;%(email)s&gt;",
            cmd="%prog",
            version=version(),
            email="*****@*****.**")

    opars = ColorOptionParser(usage=usage, description=desc, version=ver)
    opars.add_option(
        "-a",
        "--announce-entry",
        action="store_true",
        dest="announce_entry",
        default=False,
        help=_("@info command line option description",
               "Announce that header or message is just about to be sieved."))
    opars.add_option("-b",
                     "--skip-obsolete",
                     action="store_true",
                     dest="skip_obsolete",
                     default=def_skip_obsolete,
                     help=_("@info command line option description",
                            "Do not sieve obsolete messages."))
    opars.add_option(
        "-c",
        "--msgfmt-check",
        action="store_true",
        dest="msgfmt_check",
        default=def_msgfmt_check,
        help=_("@info command line option description",
               "Check catalogs by %(cmd)s and skip those which do not pass.",
               cmd="msgfmt -c"))
    opars.add_option("-u",
                     "--single-entry",
                     metavar=_("@info command line value placeholder",
                               "ENTRY_NUMBER"),
                     action="store",
                     dest="single_entry",
                     default=0,
                     help=_("@info command line option description",
                            "Only perform the check on this ENTRY_NUMBER."))
    opars.add_option(
        "--force-sync",
        action="store_true",
        dest="force_sync",
        default=False,
        help=_("@info command line option description",
               "Force rewriting of all messages, whether modified or not."))
    opars.add_option("-H",
                     "--help-sieves",
                     action="store_true",
                     dest="help_sieves",
                     default=False,
                     help=_("@info command line option description",
                            "Show help for applied sieves."))
    opars.add_option("--issued-params",
                     action="store_true",
                     dest="issued_params",
                     default=False,
                     help=_(
                         "@info command line option description",
                         "Show all issued sieve parameters "
                         "(from command line and user configuration)."))
    opars.add_option("-l",
                     "--list-sieves",
                     action="store_true",
                     dest="list_sieves",
                     default=False,
                     help=_("@info command line option description",
                            "List available internal sieves."))
    opars.add_option("--list-options",
                     action="store_true",
                     dest="list_options",
                     default=False,
                     help=_("@info command line option description",
                            "List the names of available options."))
    opars.add_option("--list-sieve-names",
                     action="store_true",
                     dest="list_sieve_names",
                     default=False,
                     help=_("@info command line option description",
                            "List the names of available internal sieves."))
    opars.add_option("--list-sieve-params",
                     action="store_true",
                     dest="list_sieve_params",
                     default=False,
                     help=_("@info command line option description",
                            "List the parameters known to issued sieves."))
    opars.add_option("-m",
                     "--output-modified",
                     metavar=_("@info command line value placeholder", "FILE"),
                     action="store",
                     dest="output_modified",
                     default=None,
                     help=_("@info command line option description",
                            "Output names of modified files into FILE."))
    opars.add_option("--no-skip",
                     action="store_false",
                     dest="do_skip",
                     default=def_do_skip,
                     help=_(
                         "@info command line option description",
                         "Do not try to skip catalogs which signal errors."))
    opars.add_option("--no-sync",
                     action="store_false",
                     dest="do_sync",
                     default=True,
                     help=_("@info command line option description",
                            "Do not write any modifications to catalogs."))
    opars.add_option("-q",
                     "--quiet",
                     action="store_true",
                     dest="quiet",
                     default=False,
                     help=_(
                         "@info command line option description",
                         "Do not display any progress info "
                         "(does not influence sieves themselves)."))
    opars.add_option("-s",
                     metavar=_("@info command line value placeholder",
                               "NAME[:VALUE]"),
                     action="append",
                     dest="sieve_params",
                     default=[],
                     help=_("@info command line option description",
                            "Pass a parameter to sieves."))
    opars.add_option(
        "-S",
        metavar=_("@info command line value placeholder", "NAME[:VALUE]"),
        action="append",
        dest="sieve_no_params",
        default=[],
        help=_(
            "@info command line option description",
            "Remove a parameter to sieves "
            "(e.g. if it was issued through user configuration)."))
    opars.add_option("-v",
                     "--verbose",
                     action="store_true",
                     dest="verbose",
                     default=False,
                     help=_("@info command line option description",
                            "Output more detailed progress information."))
    add_cmdopt_filesfrom(opars)
    add_cmdopt_incexc(opars)
    add_cmdopt_colors(opars)

    (op, free_args) = opars.parse_args(str_to_unicode(sys.argv[1:]))

    if op.list_options:
        report(list_options(opars))
        sys.exit(0)

    if len(free_args) < 1 and not (op.list_sieves or op.list_sieve_names):
        error(_("@info", "No sieve to apply given."))

    op.raw_sieves = []
    op.raw_paths = []
    if len(free_args) > 2 and op.single_entry != 0:
        error(
            _("@info",
              "With single entry mode, you can only give one input file."))

    if len(free_args) >= 1:
        op.raw_sieves = free_args[0]
        op.raw_paths = free_args[1:]

    # Could use some speedup.
    try:
        import psyco
        psyco.full()
    except ImportError:
        pass

    set_coloring_globals(ctype=op.coloring_type, outdep=(not op.raw_colors))

    # Dummy-set all internal sieves as requested if sieve listing required.
    sieves_requested = []
    if op.list_sieves or op.list_sieve_names:
        # Global sieves.
        modpaths = glob.glob(os.path.join(datadir(), "sieve", "[a-z]*.py"))
        modpaths.sort()
        for modpath in modpaths:
            sname = os.path.basename(modpath)[:-3]  # minus .py
            sname = sname.replace("_", "-")
            sieves_requested.append(sname)
        # Language-specific sieves.
        modpaths = glob.glob(
            os.path.join(datadir(), "lang", "*", "sieve", "[a-z]*.py"))
        modpaths.sort()
        for modpath in modpaths:
            sname = os.path.basename(modpath)[:-3]  # minus .py
            sname = sname.replace("_", "-")
            lang = os.path.basename(os.path.dirname(os.path.dirname(modpath)))
            sieves_requested.append(lang + ":" + sname)

    # No need to load and setup sieves if only listing sieve names requested.
    if op.list_sieve_names:
        report("\n".join(sieves_requested))
        sys.exit(0)

    # Load sieve modules from supplied names in the command line.
    if not sieves_requested:
        sieves_requested = op.raw_sieves.split(",")
    sieve_modules = []
    for sieve_name in sieves_requested:
        # Resolve sieve file.
        if not sieve_name.endswith(".py"):
            # One of internal sieves.
            if ":" in sieve_name:
                # Language-specific internal sieve.
                lang, name = sieve_name.split(":")
                sieve_path_base = os.path.join("lang", lang, "sieve", name)
            else:
                sieve_path_base = os.path.join("sieve", sieve_name)
            sieve_path_base = sieve_path_base.replace("-", "_") + ".py"
            sieve_path = os.path.join(datadir(), sieve_path_base)
        else:
            # Sieve name is its path.
            sieve_path = sieve_name
        try:
            sieve_file = open(unicode_to_str(sieve_path))
            # ...unicode_to_str because of exec below.
        except IOError:
            error(_("@info", "Cannot load sieve '%(file)s'.", file=sieve_path))
        # Load file into new module.
        sieve_mod_name = "sieve_" + str(len(sieve_modules))
        sieve_mod = imp.new_module(sieve_mod_name)
        exec sieve_file in sieve_mod.__dict__
        sieve_file.close()
        sys.modules[sieve_mod_name] = sieve_mod  # to avoid garbage collection
        sieve_modules.append((sieve_name, sieve_mod))
        if not hasattr(sieve_mod, "Sieve"):
            error(
                _("@info",
                  "Module '%(file)s' does not define %(classname)s class.",
                  file=sieve_path,
                  classname="Sieve"))

    # Setup sieves (description, known parameters...)
    pp = ParamParser()
    snames = []
    for name, mod in sieve_modules:
        scview = pp.add_subcmd(name)
        if hasattr(mod, "setup_sieve"):
            mod.setup_sieve(scview)
        snames.append(name)

    # If info on sieves requested, report and exit.
    if op.list_sieves:
        report(_("@info", "Available internal sieves:"))
        report(pp.listcmd(snames))
        sys.exit(0)
    elif op.list_sieve_params:
        params = set()
        for scview in pp.cmdviews():
            params.update(scview.params(addcol=True))
        report("\n".join(sorted(params)))
        sys.exit(0)
    elif op.help_sieves:
        report(_("@info", "Help for sieves:"))
        report("")
        report(pp.help(snames))
        sys.exit(0)

    # Prepare sieve parameters for parsing.
    sieve_params = list(op.sieve_params)
    # - append paramaters according to configuration
    sieve_params.extend(read_config_params(pp.cmdviews(), sieve_params))
    # - remove paramaters according to command line
    if op.sieve_no_params:
        sieve_params_mod = []
        for parspec in sieve_params:
            if parspec.split(":", 1)[0] not in op.sieve_no_params:
                sieve_params_mod.append(parspec)
        sieve_params = sieve_params_mod

    # If assembly of issued parameters requested, report and exit.
    if op.issued_params:
        escparams = []
        for parspec in sieve_params:
            if ":" in parspec:
                param, value = parspec.split(":", 1)
                escparam = "%s:%s" % (param, escape_sh(value))
            else:
                escparam = parspec
            escparams.append(escparam)
        fmtparams = " ".join(["-s%s" % x for x in sorted(escparams)])
        if fmtparams:
            report(fmtparams)
        sys.exit(0)

    # Parse sieve parameters.
    sparams, nacc_params = pp.parse(sieve_params, snames)
    if nacc_params:
        error(
            _("@info", "Parameters not accepted by any of issued subcommands: "
              "%(paramlist)s.",
              paramlist=format_item_list(nacc_params)))

    # ========================================
    # FIXME: Think of something less ugly.
    # Add as special parameter to each sieve:
    # - root paths from which the catalogs are collected
    # - whether destination independent coloring is in effect
    # - test function for catalog selection
    root_paths = []
    if op.raw_paths:
        root_paths.extend(op.raw_paths)
    if op.files_from:
        for ffpath in op.files_from:
            root_paths.extend(collect_paths_from_file(ffpath))
    if not op.raw_paths and not op.files_from:
        root_paths = ["."]
    is_cat_included = build_path_selector(incnames=op.include_names,
                                          incpaths=op.include_paths,
                                          excnames=op.exclude_names,
                                          excpaths=op.exclude_paths)
    for p in sparams.values():
        p.root_paths = root_paths
        p.raw_colors = op.raw_colors
        p.is_cat_included = is_cat_included
    # ========================================

    # Create sieves.
    sieves = []
    for name, mod in sieve_modules:
        sieves.append(mod.Sieve(sparams[name]))

    # Get the message monitoring indicator from the sieves.
    # Monitor unless all sieves have requested otherwise.
    use_monitored = False
    for sieve in sieves:
        if getattr(sieve, "caller_monitored", True):
            use_monitored = True
            break
    if op.verbose and not use_monitored:
        report(_("@info:progress", "--> Not monitoring messages."))

    # Get the sync indicator from the sieves.
    # Sync unless all sieves have requested otherwise,
    # and unless syncing is disabled globally in command line.
    do_sync = False
    for sieve in sieves:
        if getattr(sieve, "caller_sync", True):
            do_sync = True
            break
    if not op.do_sync:
        do_sync = False
    if op.verbose and not do_sync:
        report(_("@info:progress", "--> Not syncing after sieving."))

    # Open in header-only mode if no sieve has message processor.
    # Categorize sieves by the presence of message/header processors.
    use_headonly = True
    header_sieves = []
    header_sieves_last = []
    message_sieves = []
    for sieve in sieves:
        if hasattr(sieve, "process"):
            use_headonly = False
            message_sieves.append(sieve)
        if hasattr(sieve, "process_header"):
            header_sieves.append(sieve)
        if hasattr(sieve, "process_header_last"):
            header_sieves_last.append(sieve)
    if op.verbose and use_headonly:
        report(_("@info:progress",
                 "--> Opening catalogs in header-only mode."))

    # Collect catalog paths.
    fnames = collect_paths_cmdline(rawpaths=op.raw_paths,
                                   incnames=op.include_names,
                                   incpaths=op.include_paths,
                                   excnames=op.exclude_names,
                                   excpaths=op.exclude_paths,
                                   filesfrom=op.files_from,
                                   elsecwd=True,
                                   respathf=collect_catalogs,
                                   abort=True)

    if op.do_skip:
        errwarn = warning
        errwarn_on_msg = warning_on_msg
    else:
        errwarn = error
        errwarn_on_msg = error_on_msg

    # Prepare inline progress indicator.
    if not op.quiet:
        update_progress = init_file_progress(fnames,
                                             addfmt=t_("@info:progress",
                                                       "Sieving: %(file)s"))

    # Sieve catalogs.
    modified_files = []
    for fname in fnames:
        if op.verbose:
            report(_("@info:progress", "Sieving %(file)s...", file=fname))
        elif not op.quiet:
            update_progress(fname)

        if op.msgfmt_check:
            d1, oerr, ret = collect_system(
                ["msgfmt", "-o", "/dev/null", "-c", fname])
            if ret != 0:
                oerr = oerr.strip()
                errwarn(
                    _("@info:progress", "%(file)s: %(cmd)s check failed:\n"
                      "%(msg)s",
                      file=fname,
                      cmd="msgfmt -c",
                      msg=oerr))
                warning(
                    _("@info:progress",
                      "Skipping catalog due to syntax check failure."))
                continue

        try:
            cat = Catalog(fname,
                          monitored=use_monitored,
                          headonly=use_headonly,
                          single_entry=int(op.single_entry))
        except CatalogSyntaxError, e:
            errwarn(
                _("@info:progress",
                  "%(file)s: Parsing failed: %(msg)s",
                  file=fname,
                  msg=e))
            warning(
                _("@info:progress",
                  "Skipping catalog due to parsing failure."))
            continue

        skip = False
        # First run all header sieves.
        if header_sieves and op.announce_entry:
            report(
                _("@info:progress",
                  "Sieving header of %(file)s...",
                  file=fname))
        for sieve in header_sieves:
            try:
                ret = sieve.process_header(cat.header, cat)
            except SieveCatalogError, e:
                errwarn(
                    _("@info:progress",
                      "%(file)s:header: Sieving failed: %(msg)s",
                      file=fname,
                      msg=e))
                skip = True
                break
            if ret not in (None, 0):
                break