2014-07-11 07:48:07 +02:00
|
|
|
/* Gcc offline profile processing tool support. */
|
2016-01-04 14:03:35 +01:00
|
|
|
/* Copyright (C) 2014-2016 Free Software Foundation, Inc.
|
2014-07-11 07:48:07 +02:00
|
|
|
Contributed by Rong Xu <xur@google.com>.
|
|
|
|
|
|
|
|
This file is part of GCC.
|
|
|
|
|
|
|
|
GCC is free software; you can redistribute it and/or modify it under
|
|
|
|
the terms of the GNU General Public License as published by the Free
|
|
|
|
Software Foundation; either version 3, or (at your option) any later
|
|
|
|
version.
|
|
|
|
|
|
|
|
GCC 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.
|
|
|
|
|
|
|
|
Under Section 7 of GPL version 3, you are granted additional
|
|
|
|
permissions described in the GCC Runtime Library Exception, version
|
|
|
|
3.1, as published by the Free Software Foundation.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License and
|
|
|
|
a copy of the GCC Runtime Library Exception along with this program;
|
|
|
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#include "system.h"
|
|
|
|
#include "coretypes.h"
|
|
|
|
#include "tm.h"
|
|
|
|
#include "intl.h"
|
|
|
|
#include "diagnostic.h"
|
|
|
|
#include "version.h"
|
|
|
|
#include "gcov-io.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
2015-02-10 04:40:20 +01:00
|
|
|
#if HAVE_FTW_H
|
2014-07-11 07:48:07 +02:00
|
|
|
#include <ftw.h>
|
2015-02-10 04:40:20 +01:00
|
|
|
#endif
|
2014-07-11 07:48:07 +02:00
|
|
|
#include <getopt.h>
|
|
|
|
|
|
|
|
extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, int, int);
|
2014-10-08 23:51:41 +02:00
|
|
|
extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
|
2014-07-11 07:48:07 +02:00
|
|
|
extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
|
|
|
|
extern int gcov_profile_scale (struct gcov_info*, float, int, int);
|
|
|
|
extern struct gcov_info* gcov_read_profile_dir (const char*, int);
|
2014-07-29 15:48:38 +02:00
|
|
|
extern void gcov_do_dump (struct gcov_info *, int);
|
2014-07-11 07:48:07 +02:00
|
|
|
extern void gcov_set_verbose (void);
|
|
|
|
|
|
|
|
/* Set to verbose output mode. */
|
|
|
|
static bool verbose;
|
|
|
|
|
2015-02-10 04:40:20 +01:00
|
|
|
#if HAVE_FTW_H
|
|
|
|
|
2014-07-11 07:48:07 +02:00
|
|
|
/* Remove file NAME if it has a gcda suffix. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
unlink_gcda_file (const char *name,
|
|
|
|
const struct stat *status ATTRIBUTE_UNUSED,
|
|
|
|
int type ATTRIBUTE_UNUSED,
|
|
|
|
struct FTW *ftwbuf ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
int len = strlen (name);
|
|
|
|
int len1 = strlen (GCOV_DATA_SUFFIX);
|
|
|
|
|
|
|
|
if (len > len1 && !strncmp (len -len1 + name, GCOV_DATA_SUFFIX, len1))
|
|
|
|
ret = remove (name);
|
|
|
|
|
|
|
|
if (ret)
|
Always pass explicit location to fatal_error.
The patch <https://gcc.gnu.org/ml/gcc-patches/2014-11/msg00698.html>
adding an overload for fatal_error that passes an explicit location
broke gcc.pot regeneration because xgettext cannot handle function
overloads with the diagnostic string argument in different positions.
As the desired direction is for all diagnostics to have explicit
locations, this patch addresses the regression by removing the version
of fatal_error that does not pass a location, passing explicit
input_location everywhere (in the hope that those will incrementally
be changed to other locations, much as with the addition of a location
argument to pedwarn some time ago - a lot of cases aren't meaningfully
associated with a source file so UNKNOWN_LOCATION may be better).
Note that this patch does not attempt to fix any existing issues with
these diagnostics (such as wrongly starting with capital letters or
ending with '.' or '\n'); it just adds the input_location argument.
Bootstrapped with no regressions for x86_64-unknown-linux-gnu (Go
excluded).
gcc:
* diagnostic.c (fatal_error (const char *, ...)): Remove function.
* diagnostic-core.h (fatal_error (const char *, ...)): Remove
prototype.
* toplev.h (init_asm_output): Update comment on use of
UNKNOWN_LOCATION with fatal_error.
* cgraph.c, collect-utils.c, collect2.c, config/arc/arc.c,
config/arc/arc.md, config/avr/avr.c, config/c6x/c6x.h,
config/darwin.c, config/host-darwin.c, config/i386/host-cygwin.c,
config/i386/intelmic-mkoffload.c, config/nios2/nios2.c,
config/nvptx/mkoffload.c, config/nvptx/nvptx.h,
config/rs6000/host-darwin.c, config/rs6000/rs6000.c,
config/s390/s390.c, gcc.c, gcov-io.h, gcov-tool.c, ggc-common.c,
ggc-page.c, graph.c, ipa-inline-analysis.c, ipa-reference.c,
lto-cgraph.c, lto-section-in.c, lto-streamer-in.c, lto-streamer.c,
lto-wrapper.c, objc/objc-act.c, opts.c, passes.c, plugin.c,
tlink.c, toplev.c, tree-streamer-in.c, varpool.c: All callers of
fatal_error changed to pass input_location as first argument.
gcc/c-family:
* c-opts.c, c-pch.c, cppspec.c: All callers of fatal_error changed
to pass input_location as first argument.
gcc/cp:
* class.c, except.c, parser.c, pt.c: All callers of fatal_error
changed to pass input_location as first argument.
gcc/fortran:
* f95-lang.c, gfortranspec.c, trans-const.c, trans-expr.c: All
callers of fatal_error changed to pass input_location as first
argument.
gcc/java:
* class.c, expr.c, jcf-parse.c, jvspec.c: All callers of
fatal_error changed to pass input_location as first argument.
gcc/lto:
* lto-object.c, lto-symtab.c, lto.c: All callers of fatal_error
changed to pass input_location as first argument.
libcc1:
* plugin.cc: All callers of fatal_error changed to pass
input_location as first argument.
From-SVN: r220293
2015-01-30 17:15:00 +01:00
|
|
|
fatal_error (input_location, "error in removing %s\n", name);
|
2014-07-11 07:48:07 +02:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2015-02-10 04:40:20 +01:00
|
|
|
#endif
|
2014-07-11 07:48:07 +02:00
|
|
|
|
|
|
|
/* Remove the gcda files in PATH recursively. */
|
|
|
|
|
|
|
|
static int
|
2015-02-10 04:40:20 +01:00
|
|
|
unlink_profile_dir (const char *path ATTRIBUTE_UNUSED)
|
2014-07-11 07:48:07 +02:00
|
|
|
{
|
2015-02-10 04:40:20 +01:00
|
|
|
#if HAVE_FTW_H
|
2014-07-11 07:48:07 +02:00
|
|
|
return nftw(path, unlink_gcda_file, 64, FTW_DEPTH | FTW_PHYS);
|
2015-02-10 04:40:20 +01:00
|
|
|
#else
|
|
|
|
return -1;
|
|
|
|
#endif
|
2014-07-11 07:48:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Output GCOV_INFO lists PROFILE to directory OUT. Note that
|
|
|
|
we will remove all the gcda files in OUT. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
gcov_output_files (const char *out, struct gcov_info *profile)
|
|
|
|
{
|
|
|
|
char *pwd;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* Try to make directory if it doesn't already exist. */
|
|
|
|
if (access (out, F_OK) == -1)
|
|
|
|
{
|
2014-07-11 18:59:30 +02:00
|
|
|
if (mkdir (out, S_IRWXU | S_IRWXG | S_IRWXO) == -1 && errno != EEXIST)
|
Always pass explicit location to fatal_error.
The patch <https://gcc.gnu.org/ml/gcc-patches/2014-11/msg00698.html>
adding an overload for fatal_error that passes an explicit location
broke gcc.pot regeneration because xgettext cannot handle function
overloads with the diagnostic string argument in different positions.
As the desired direction is for all diagnostics to have explicit
locations, this patch addresses the regression by removing the version
of fatal_error that does not pass a location, passing explicit
input_location everywhere (in the hope that those will incrementally
be changed to other locations, much as with the addition of a location
argument to pedwarn some time ago - a lot of cases aren't meaningfully
associated with a source file so UNKNOWN_LOCATION may be better).
Note that this patch does not attempt to fix any existing issues with
these diagnostics (such as wrongly starting with capital letters or
ending with '.' or '\n'); it just adds the input_location argument.
Bootstrapped with no regressions for x86_64-unknown-linux-gnu (Go
excluded).
gcc:
* diagnostic.c (fatal_error (const char *, ...)): Remove function.
* diagnostic-core.h (fatal_error (const char *, ...)): Remove
prototype.
* toplev.h (init_asm_output): Update comment on use of
UNKNOWN_LOCATION with fatal_error.
* cgraph.c, collect-utils.c, collect2.c, config/arc/arc.c,
config/arc/arc.md, config/avr/avr.c, config/c6x/c6x.h,
config/darwin.c, config/host-darwin.c, config/i386/host-cygwin.c,
config/i386/intelmic-mkoffload.c, config/nios2/nios2.c,
config/nvptx/mkoffload.c, config/nvptx/nvptx.h,
config/rs6000/host-darwin.c, config/rs6000/rs6000.c,
config/s390/s390.c, gcc.c, gcov-io.h, gcov-tool.c, ggc-common.c,
ggc-page.c, graph.c, ipa-inline-analysis.c, ipa-reference.c,
lto-cgraph.c, lto-section-in.c, lto-streamer-in.c, lto-streamer.c,
lto-wrapper.c, objc/objc-act.c, opts.c, passes.c, plugin.c,
tlink.c, toplev.c, tree-streamer-in.c, varpool.c: All callers of
fatal_error changed to pass input_location as first argument.
gcc/c-family:
* c-opts.c, c-pch.c, cppspec.c: All callers of fatal_error changed
to pass input_location as first argument.
gcc/cp:
* class.c, except.c, parser.c, pt.c: All callers of fatal_error
changed to pass input_location as first argument.
gcc/fortran:
* f95-lang.c, gfortranspec.c, trans-const.c, trans-expr.c: All
callers of fatal_error changed to pass input_location as first
argument.
gcc/java:
* class.c, expr.c, jcf-parse.c, jvspec.c: All callers of
fatal_error changed to pass input_location as first argument.
gcc/lto:
* lto-object.c, lto-symtab.c, lto.c: All callers of fatal_error
changed to pass input_location as first argument.
libcc1:
* plugin.cc: All callers of fatal_error changed to pass
input_location as first argument.
From-SVN: r220293
2015-01-30 17:15:00 +01:00
|
|
|
fatal_error (input_location, "Cannot make directory %s", out);
|
2014-07-11 07:48:07 +02:00
|
|
|
} else
|
|
|
|
unlink_profile_dir (out);
|
|
|
|
|
|
|
|
/* Output new profile. */
|
|
|
|
pwd = getcwd (NULL, 0);
|
|
|
|
|
|
|
|
if (pwd == NULL)
|
Always pass explicit location to fatal_error.
The patch <https://gcc.gnu.org/ml/gcc-patches/2014-11/msg00698.html>
adding an overload for fatal_error that passes an explicit location
broke gcc.pot regeneration because xgettext cannot handle function
overloads with the diagnostic string argument in different positions.
As the desired direction is for all diagnostics to have explicit
locations, this patch addresses the regression by removing the version
of fatal_error that does not pass a location, passing explicit
input_location everywhere (in the hope that those will incrementally
be changed to other locations, much as with the addition of a location
argument to pedwarn some time ago - a lot of cases aren't meaningfully
associated with a source file so UNKNOWN_LOCATION may be better).
Note that this patch does not attempt to fix any existing issues with
these diagnostics (such as wrongly starting with capital letters or
ending with '.' or '\n'); it just adds the input_location argument.
Bootstrapped with no regressions for x86_64-unknown-linux-gnu (Go
excluded).
gcc:
* diagnostic.c (fatal_error (const char *, ...)): Remove function.
* diagnostic-core.h (fatal_error (const char *, ...)): Remove
prototype.
* toplev.h (init_asm_output): Update comment on use of
UNKNOWN_LOCATION with fatal_error.
* cgraph.c, collect-utils.c, collect2.c, config/arc/arc.c,
config/arc/arc.md, config/avr/avr.c, config/c6x/c6x.h,
config/darwin.c, config/host-darwin.c, config/i386/host-cygwin.c,
config/i386/intelmic-mkoffload.c, config/nios2/nios2.c,
config/nvptx/mkoffload.c, config/nvptx/nvptx.h,
config/rs6000/host-darwin.c, config/rs6000/rs6000.c,
config/s390/s390.c, gcc.c, gcov-io.h, gcov-tool.c, ggc-common.c,
ggc-page.c, graph.c, ipa-inline-analysis.c, ipa-reference.c,
lto-cgraph.c, lto-section-in.c, lto-streamer-in.c, lto-streamer.c,
lto-wrapper.c, objc/objc-act.c, opts.c, passes.c, plugin.c,
tlink.c, toplev.c, tree-streamer-in.c, varpool.c: All callers of
fatal_error changed to pass input_location as first argument.
gcc/c-family:
* c-opts.c, c-pch.c, cppspec.c: All callers of fatal_error changed
to pass input_location as first argument.
gcc/cp:
* class.c, except.c, parser.c, pt.c: All callers of fatal_error
changed to pass input_location as first argument.
gcc/fortran:
* f95-lang.c, gfortranspec.c, trans-const.c, trans-expr.c: All
callers of fatal_error changed to pass input_location as first
argument.
gcc/java:
* class.c, expr.c, jcf-parse.c, jvspec.c: All callers of
fatal_error changed to pass input_location as first argument.
gcc/lto:
* lto-object.c, lto-symtab.c, lto.c: All callers of fatal_error
changed to pass input_location as first argument.
libcc1:
* plugin.cc: All callers of fatal_error changed to pass
input_location as first argument.
From-SVN: r220293
2015-01-30 17:15:00 +01:00
|
|
|
fatal_error (input_location, "Cannot get current directory name");
|
2014-07-11 07:48:07 +02:00
|
|
|
|
|
|
|
ret = chdir (out);
|
|
|
|
if (ret)
|
Always pass explicit location to fatal_error.
The patch <https://gcc.gnu.org/ml/gcc-patches/2014-11/msg00698.html>
adding an overload for fatal_error that passes an explicit location
broke gcc.pot regeneration because xgettext cannot handle function
overloads with the diagnostic string argument in different positions.
As the desired direction is for all diagnostics to have explicit
locations, this patch addresses the regression by removing the version
of fatal_error that does not pass a location, passing explicit
input_location everywhere (in the hope that those will incrementally
be changed to other locations, much as with the addition of a location
argument to pedwarn some time ago - a lot of cases aren't meaningfully
associated with a source file so UNKNOWN_LOCATION may be better).
Note that this patch does not attempt to fix any existing issues with
these diagnostics (such as wrongly starting with capital letters or
ending with '.' or '\n'); it just adds the input_location argument.
Bootstrapped with no regressions for x86_64-unknown-linux-gnu (Go
excluded).
gcc:
* diagnostic.c (fatal_error (const char *, ...)): Remove function.
* diagnostic-core.h (fatal_error (const char *, ...)): Remove
prototype.
* toplev.h (init_asm_output): Update comment on use of
UNKNOWN_LOCATION with fatal_error.
* cgraph.c, collect-utils.c, collect2.c, config/arc/arc.c,
config/arc/arc.md, config/avr/avr.c, config/c6x/c6x.h,
config/darwin.c, config/host-darwin.c, config/i386/host-cygwin.c,
config/i386/intelmic-mkoffload.c, config/nios2/nios2.c,
config/nvptx/mkoffload.c, config/nvptx/nvptx.h,
config/rs6000/host-darwin.c, config/rs6000/rs6000.c,
config/s390/s390.c, gcc.c, gcov-io.h, gcov-tool.c, ggc-common.c,
ggc-page.c, graph.c, ipa-inline-analysis.c, ipa-reference.c,
lto-cgraph.c, lto-section-in.c, lto-streamer-in.c, lto-streamer.c,
lto-wrapper.c, objc/objc-act.c, opts.c, passes.c, plugin.c,
tlink.c, toplev.c, tree-streamer-in.c, varpool.c: All callers of
fatal_error changed to pass input_location as first argument.
gcc/c-family:
* c-opts.c, c-pch.c, cppspec.c: All callers of fatal_error changed
to pass input_location as first argument.
gcc/cp:
* class.c, except.c, parser.c, pt.c: All callers of fatal_error
changed to pass input_location as first argument.
gcc/fortran:
* f95-lang.c, gfortranspec.c, trans-const.c, trans-expr.c: All
callers of fatal_error changed to pass input_location as first
argument.
gcc/java:
* class.c, expr.c, jcf-parse.c, jvspec.c: All callers of
fatal_error changed to pass input_location as first argument.
gcc/lto:
* lto-object.c, lto-symtab.c, lto.c: All callers of fatal_error
changed to pass input_location as first argument.
libcc1:
* plugin.cc: All callers of fatal_error changed to pass
input_location as first argument.
From-SVN: r220293
2015-01-30 17:15:00 +01:00
|
|
|
fatal_error (input_location, "Cannot change directory to %s", out);
|
2014-07-11 07:48:07 +02:00
|
|
|
|
2014-07-29 15:48:38 +02:00
|
|
|
gcov_do_dump (profile, 0);
|
2014-07-11 07:48:07 +02:00
|
|
|
|
|
|
|
ret = chdir (pwd);
|
|
|
|
if (ret)
|
Always pass explicit location to fatal_error.
The patch <https://gcc.gnu.org/ml/gcc-patches/2014-11/msg00698.html>
adding an overload for fatal_error that passes an explicit location
broke gcc.pot regeneration because xgettext cannot handle function
overloads with the diagnostic string argument in different positions.
As the desired direction is for all diagnostics to have explicit
locations, this patch addresses the regression by removing the version
of fatal_error that does not pass a location, passing explicit
input_location everywhere (in the hope that those will incrementally
be changed to other locations, much as with the addition of a location
argument to pedwarn some time ago - a lot of cases aren't meaningfully
associated with a source file so UNKNOWN_LOCATION may be better).
Note that this patch does not attempt to fix any existing issues with
these diagnostics (such as wrongly starting with capital letters or
ending with '.' or '\n'); it just adds the input_location argument.
Bootstrapped with no regressions for x86_64-unknown-linux-gnu (Go
excluded).
gcc:
* diagnostic.c (fatal_error (const char *, ...)): Remove function.
* diagnostic-core.h (fatal_error (const char *, ...)): Remove
prototype.
* toplev.h (init_asm_output): Update comment on use of
UNKNOWN_LOCATION with fatal_error.
* cgraph.c, collect-utils.c, collect2.c, config/arc/arc.c,
config/arc/arc.md, config/avr/avr.c, config/c6x/c6x.h,
config/darwin.c, config/host-darwin.c, config/i386/host-cygwin.c,
config/i386/intelmic-mkoffload.c, config/nios2/nios2.c,
config/nvptx/mkoffload.c, config/nvptx/nvptx.h,
config/rs6000/host-darwin.c, config/rs6000/rs6000.c,
config/s390/s390.c, gcc.c, gcov-io.h, gcov-tool.c, ggc-common.c,
ggc-page.c, graph.c, ipa-inline-analysis.c, ipa-reference.c,
lto-cgraph.c, lto-section-in.c, lto-streamer-in.c, lto-streamer.c,
lto-wrapper.c, objc/objc-act.c, opts.c, passes.c, plugin.c,
tlink.c, toplev.c, tree-streamer-in.c, varpool.c: All callers of
fatal_error changed to pass input_location as first argument.
gcc/c-family:
* c-opts.c, c-pch.c, cppspec.c: All callers of fatal_error changed
to pass input_location as first argument.
gcc/cp:
* class.c, except.c, parser.c, pt.c: All callers of fatal_error
changed to pass input_location as first argument.
gcc/fortran:
* f95-lang.c, gfortranspec.c, trans-const.c, trans-expr.c: All
callers of fatal_error changed to pass input_location as first
argument.
gcc/java:
* class.c, expr.c, jcf-parse.c, jvspec.c: All callers of
fatal_error changed to pass input_location as first argument.
gcc/lto:
* lto-object.c, lto-symtab.c, lto.c: All callers of fatal_error
changed to pass input_location as first argument.
libcc1:
* plugin.cc: All callers of fatal_error changed to pass
input_location as first argument.
From-SVN: r220293
2015-01-30 17:15:00 +01:00
|
|
|
fatal_error (input_location, "Cannot change directory to %s", pwd);
|
2014-07-11 07:48:07 +02:00
|
|
|
|
|
|
|
free (pwd);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Merging profile D1 and D2 with weight as W1 and W2, respectively.
|
|
|
|
The result profile is written to directory OUT.
|
|
|
|
Return 0 on success. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
profile_merge (const char *d1, const char *d2, const char *out, int w1, int w2)
|
|
|
|
{
|
|
|
|
struct gcov_info *d1_profile;
|
|
|
|
struct gcov_info *d2_profile;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
d1_profile = gcov_read_profile_dir (d1, 0);
|
|
|
|
if (!d1_profile)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (d2)
|
|
|
|
{
|
|
|
|
d2_profile = gcov_read_profile_dir (d2, 0);
|
|
|
|
if (!d2_profile)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
/* The actual merge: we overwrite to d1_profile. */
|
|
|
|
ret = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
gcov_output_files (out, d1_profile);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Usage message for profile merge. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_merge_usage_message (int error_p)
|
|
|
|
{
|
|
|
|
FILE *file = error_p ? stderr : stdout;
|
|
|
|
|
|
|
|
fnotice (file, " merge [options] <dir1> <dir2> Merge coverage file contents\n");
|
|
|
|
fnotice (file, " -v, --verbose Verbose mode\n");
|
|
|
|
fnotice (file, " -o, --output <dir> Output directory\n");
|
|
|
|
fnotice (file, " -w, --weight <w1,w2> Set weights (float point values)\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct option merge_options[] =
|
|
|
|
{
|
|
|
|
{ "verbose", no_argument, NULL, 'v' },
|
|
|
|
{ "output", required_argument, NULL, 'o' },
|
|
|
|
{ "weight", required_argument, NULL, 'w' },
|
|
|
|
{ 0, 0, 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Print merge usage and exit. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
merge_usage (void)
|
|
|
|
{
|
|
|
|
fnotice (stderr, "Merge subcomand usage:");
|
|
|
|
print_merge_usage_message (true);
|
|
|
|
exit (FATAL_EXIT_CODE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Driver for profile merge sub-command. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_merge (int argc, char **argv)
|
|
|
|
{
|
|
|
|
int opt;
|
|
|
|
const char *output_dir = 0;
|
|
|
|
int w1 = 1, w2 = 1;
|
|
|
|
|
|
|
|
optind = 0;
|
|
|
|
while ((opt = getopt_long (argc, argv, "vo:w:", merge_options, NULL)) != -1)
|
|
|
|
{
|
|
|
|
switch (opt)
|
|
|
|
{
|
|
|
|
case 'v':
|
|
|
|
verbose = true;
|
|
|
|
gcov_set_verbose ();
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
output_dir = optarg;
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
sscanf (optarg, "%d,%d", &w1, &w2);
|
|
|
|
if (w1 < 0 || w2 < 0)
|
Always pass explicit location to fatal_error.
The patch <https://gcc.gnu.org/ml/gcc-patches/2014-11/msg00698.html>
adding an overload for fatal_error that passes an explicit location
broke gcc.pot regeneration because xgettext cannot handle function
overloads with the diagnostic string argument in different positions.
As the desired direction is for all diagnostics to have explicit
locations, this patch addresses the regression by removing the version
of fatal_error that does not pass a location, passing explicit
input_location everywhere (in the hope that those will incrementally
be changed to other locations, much as with the addition of a location
argument to pedwarn some time ago - a lot of cases aren't meaningfully
associated with a source file so UNKNOWN_LOCATION may be better).
Note that this patch does not attempt to fix any existing issues with
these diagnostics (such as wrongly starting with capital letters or
ending with '.' or '\n'); it just adds the input_location argument.
Bootstrapped with no regressions for x86_64-unknown-linux-gnu (Go
excluded).
gcc:
* diagnostic.c (fatal_error (const char *, ...)): Remove function.
* diagnostic-core.h (fatal_error (const char *, ...)): Remove
prototype.
* toplev.h (init_asm_output): Update comment on use of
UNKNOWN_LOCATION with fatal_error.
* cgraph.c, collect-utils.c, collect2.c, config/arc/arc.c,
config/arc/arc.md, config/avr/avr.c, config/c6x/c6x.h,
config/darwin.c, config/host-darwin.c, config/i386/host-cygwin.c,
config/i386/intelmic-mkoffload.c, config/nios2/nios2.c,
config/nvptx/mkoffload.c, config/nvptx/nvptx.h,
config/rs6000/host-darwin.c, config/rs6000/rs6000.c,
config/s390/s390.c, gcc.c, gcov-io.h, gcov-tool.c, ggc-common.c,
ggc-page.c, graph.c, ipa-inline-analysis.c, ipa-reference.c,
lto-cgraph.c, lto-section-in.c, lto-streamer-in.c, lto-streamer.c,
lto-wrapper.c, objc/objc-act.c, opts.c, passes.c, plugin.c,
tlink.c, toplev.c, tree-streamer-in.c, varpool.c: All callers of
fatal_error changed to pass input_location as first argument.
gcc/c-family:
* c-opts.c, c-pch.c, cppspec.c: All callers of fatal_error changed
to pass input_location as first argument.
gcc/cp:
* class.c, except.c, parser.c, pt.c: All callers of fatal_error
changed to pass input_location as first argument.
gcc/fortran:
* f95-lang.c, gfortranspec.c, trans-const.c, trans-expr.c: All
callers of fatal_error changed to pass input_location as first
argument.
gcc/java:
* class.c, expr.c, jcf-parse.c, jvspec.c: All callers of
fatal_error changed to pass input_location as first argument.
gcc/lto:
* lto-object.c, lto-symtab.c, lto.c: All callers of fatal_error
changed to pass input_location as first argument.
libcc1:
* plugin.cc: All callers of fatal_error changed to pass
input_location as first argument.
From-SVN: r220293
2015-01-30 17:15:00 +01:00
|
|
|
fatal_error (input_location, "weights need to be non-negative\n");
|
2014-07-11 07:48:07 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
merge_usage ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (output_dir == NULL)
|
|
|
|
output_dir = "merged_profile";
|
|
|
|
|
2015-05-07 19:57:11 +02:00
|
|
|
if (argc - optind != 2)
|
2014-07-11 07:48:07 +02:00
|
|
|
merge_usage ();
|
|
|
|
|
2015-05-07 19:57:11 +02:00
|
|
|
return profile_merge (argv[optind], argv[optind+1], output_dir, w1, w2);
|
2014-07-11 07:48:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* If N_VAL is no-zero, normalize the profile by setting the largest counter
|
|
|
|
counter value to N_VAL and scale others counters proportionally.
|
|
|
|
Otherwise, multiply the all counters by SCALE. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
profile_rewrite (const char *d1, const char *out, long long n_val,
|
|
|
|
float scale, int n, int d)
|
|
|
|
{
|
|
|
|
struct gcov_info * d1_profile;
|
|
|
|
|
|
|
|
d1_profile = gcov_read_profile_dir (d1, 0);
|
|
|
|
if (!d1_profile)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (n_val)
|
|
|
|
gcov_profile_normalize (d1_profile, (gcov_type) n_val);
|
|
|
|
else
|
|
|
|
gcov_profile_scale (d1_profile, scale, n, d);
|
|
|
|
|
|
|
|
gcov_output_files (out, d1_profile);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Usage function for profile rewrite. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_rewrite_usage_message (int error_p)
|
|
|
|
{
|
|
|
|
FILE *file = error_p ? stderr : stdout;
|
|
|
|
|
|
|
|
fnotice (file, " rewrite [options] <dir> Rewrite coverage file contents\n");
|
|
|
|
fnotice (file, " -v, --verbose Verbose mode\n");
|
|
|
|
fnotice (file, " -o, --output <dir> Output directory\n");
|
|
|
|
fnotice (file, " -s, --scale <float or simple-frac> Scale the profile counters\n");
|
|
|
|
fnotice (file, " -n, --normalize <long long> Normalize the profile\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct option rewrite_options[] =
|
|
|
|
{
|
|
|
|
{ "verbose", no_argument, NULL, 'v' },
|
|
|
|
{ "output", required_argument, NULL, 'o' },
|
|
|
|
{ "scale", required_argument, NULL, 's' },
|
|
|
|
{ "normalize", required_argument, NULL, 'n' },
|
|
|
|
{ 0, 0, 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Print profile rewrite usage and exit. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
rewrite_usage (void)
|
|
|
|
{
|
|
|
|
fnotice (stderr, "Rewrite subcommand usage:");
|
|
|
|
print_rewrite_usage_message (true);
|
|
|
|
exit (FATAL_EXIT_CODE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Driver for profile rewrite sub-command. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_rewrite (int argc, char **argv)
|
|
|
|
{
|
|
|
|
int opt;
|
|
|
|
int ret;
|
|
|
|
const char *output_dir = 0;
|
2015-01-09 01:50:49 +01:00
|
|
|
#ifdef HAVE_LONG_LONG
|
2014-07-11 07:48:07 +02:00
|
|
|
long long normalize_val = 0;
|
2015-01-09 01:50:49 +01:00
|
|
|
#else
|
|
|
|
int64_t normalize_val = 0;
|
|
|
|
#endif
|
2014-07-11 07:48:07 +02:00
|
|
|
float scale = 0.0;
|
|
|
|
int numerator = 1;
|
|
|
|
int denominator = 1;
|
|
|
|
int do_scaling = 0;
|
|
|
|
|
|
|
|
optind = 0;
|
|
|
|
while ((opt = getopt_long (argc, argv, "vo:s:n:", rewrite_options, NULL)) != -1)
|
|
|
|
{
|
|
|
|
switch (opt)
|
|
|
|
{
|
|
|
|
case 'v':
|
|
|
|
verbose = true;
|
|
|
|
gcov_set_verbose ();
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
output_dir = optarg;
|
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
if (!do_scaling)
|
2015-01-09 01:50:49 +01:00
|
|
|
#if defined(HAVE_LONG_LONG)
|
|
|
|
normalize_val = strtoll (optarg, (char **)NULL, 10);
|
|
|
|
#elif defined(INT64_T_IS_LONG)
|
|
|
|
normalize_val = strtol (optarg, (char **)NULL, 10);
|
|
|
|
#else
|
|
|
|
sscanf (optarg, "%" SCNd64, &normalize_val);
|
|
|
|
#endif
|
2014-07-11 07:48:07 +02:00
|
|
|
else
|
|
|
|
fnotice (stderr, "scaling cannot co-exist with normalization,"
|
|
|
|
" skipping\n");
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
ret = 0;
|
|
|
|
do_scaling = 1;
|
|
|
|
if (strstr (optarg, "/"))
|
|
|
|
{
|
|
|
|
ret = sscanf (optarg, "%d/%d", &numerator, &denominator);
|
|
|
|
if (ret == 2)
|
|
|
|
{
|
|
|
|
if (numerator < 0 || denominator <= 0)
|
|
|
|
{
|
|
|
|
fnotice (stderr, "incorrect format in scaling, using 1/1\n");
|
|
|
|
denominator = 1;
|
|
|
|
numerator = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ret != 2)
|
|
|
|
{
|
|
|
|
ret = sscanf (optarg, "%f", &scale);
|
|
|
|
if (ret != 1)
|
|
|
|
fnotice (stderr, "incorrect format in scaling, using 1/1\n");
|
|
|
|
else
|
|
|
|
denominator = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scale < 0.0)
|
Always pass explicit location to fatal_error.
The patch <https://gcc.gnu.org/ml/gcc-patches/2014-11/msg00698.html>
adding an overload for fatal_error that passes an explicit location
broke gcc.pot regeneration because xgettext cannot handle function
overloads with the diagnostic string argument in different positions.
As the desired direction is for all diagnostics to have explicit
locations, this patch addresses the regression by removing the version
of fatal_error that does not pass a location, passing explicit
input_location everywhere (in the hope that those will incrementally
be changed to other locations, much as with the addition of a location
argument to pedwarn some time ago - a lot of cases aren't meaningfully
associated with a source file so UNKNOWN_LOCATION may be better).
Note that this patch does not attempt to fix any existing issues with
these diagnostics (such as wrongly starting with capital letters or
ending with '.' or '\n'); it just adds the input_location argument.
Bootstrapped with no regressions for x86_64-unknown-linux-gnu (Go
excluded).
gcc:
* diagnostic.c (fatal_error (const char *, ...)): Remove function.
* diagnostic-core.h (fatal_error (const char *, ...)): Remove
prototype.
* toplev.h (init_asm_output): Update comment on use of
UNKNOWN_LOCATION with fatal_error.
* cgraph.c, collect-utils.c, collect2.c, config/arc/arc.c,
config/arc/arc.md, config/avr/avr.c, config/c6x/c6x.h,
config/darwin.c, config/host-darwin.c, config/i386/host-cygwin.c,
config/i386/intelmic-mkoffload.c, config/nios2/nios2.c,
config/nvptx/mkoffload.c, config/nvptx/nvptx.h,
config/rs6000/host-darwin.c, config/rs6000/rs6000.c,
config/s390/s390.c, gcc.c, gcov-io.h, gcov-tool.c, ggc-common.c,
ggc-page.c, graph.c, ipa-inline-analysis.c, ipa-reference.c,
lto-cgraph.c, lto-section-in.c, lto-streamer-in.c, lto-streamer.c,
lto-wrapper.c, objc/objc-act.c, opts.c, passes.c, plugin.c,
tlink.c, toplev.c, tree-streamer-in.c, varpool.c: All callers of
fatal_error changed to pass input_location as first argument.
gcc/c-family:
* c-opts.c, c-pch.c, cppspec.c: All callers of fatal_error changed
to pass input_location as first argument.
gcc/cp:
* class.c, except.c, parser.c, pt.c: All callers of fatal_error
changed to pass input_location as first argument.
gcc/fortran:
* f95-lang.c, gfortranspec.c, trans-const.c, trans-expr.c: All
callers of fatal_error changed to pass input_location as first
argument.
gcc/java:
* class.c, expr.c, jcf-parse.c, jvspec.c: All callers of
fatal_error changed to pass input_location as first argument.
gcc/lto:
* lto-object.c, lto-symtab.c, lto.c: All callers of fatal_error
changed to pass input_location as first argument.
libcc1:
* plugin.cc: All callers of fatal_error changed to pass
input_location as first argument.
From-SVN: r220293
2015-01-30 17:15:00 +01:00
|
|
|
fatal_error (input_location, "scale needs to be non-negative\n");
|
2014-07-11 07:48:07 +02:00
|
|
|
|
|
|
|
if (normalize_val != 0)
|
|
|
|
{
|
|
|
|
fnotice (stderr, "normalization cannot co-exist with scaling\n");
|
|
|
|
normalize_val = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
rewrite_usage ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (output_dir == NULL)
|
|
|
|
output_dir = "rewrite_profile";
|
|
|
|
|
|
|
|
if (argc - optind == 1)
|
|
|
|
{
|
|
|
|
if (denominator > 0)
|
|
|
|
ret = profile_rewrite (argv[optind], output_dir, 0, 0.0, numerator, denominator);
|
|
|
|
else
|
|
|
|
ret = profile_rewrite (argv[optind], output_dir, normalize_val, scale, 0, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
rewrite_usage ();
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-10-08 23:51:41 +02:00
|
|
|
/* Driver function to computer the overlap score b/w profile D1 and D2.
|
|
|
|
Return 1 on error and 0 if OK. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
profile_overlap (const char *d1, const char *d2)
|
|
|
|
{
|
|
|
|
struct gcov_info *d1_profile;
|
|
|
|
struct gcov_info *d2_profile;
|
|
|
|
|
|
|
|
d1_profile = gcov_read_profile_dir (d1, 0);
|
|
|
|
if (!d1_profile)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (d2)
|
|
|
|
{
|
|
|
|
d2_profile = gcov_read_profile_dir (d2, 0);
|
|
|
|
if (!d2_profile)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return gcov_profile_overlap (d1_profile, d2_profile);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Usage message for profile overlap. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_overlap_usage_message (int error_p)
|
|
|
|
{
|
|
|
|
FILE *file = error_p ? stderr : stdout;
|
|
|
|
|
|
|
|
fnotice (file, " overlap [options] <dir1> <dir2> Compute the overlap of two profiles\n");
|
|
|
|
fnotice (file, " -v, --verbose Verbose mode\n");
|
|
|
|
fnotice (file, " -h, --hotonly Only print info for hot objects/functions\n");
|
|
|
|
fnotice (file, " -f, --function Print function level info\n");
|
|
|
|
fnotice (file, " -F, --fullname Print full filename\n");
|
|
|
|
fnotice (file, " -o, --object Print object level info\n");
|
|
|
|
fnotice (file, " -t <float>, --hot_threshold <float> Set the threshold for hotness\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct option overlap_options[] =
|
|
|
|
{
|
|
|
|
{ "verbose", no_argument, NULL, 'v' },
|
|
|
|
{ "function", no_argument, NULL, 'f' },
|
|
|
|
{ "fullname", no_argument, NULL, 'F' },
|
|
|
|
{ "object", no_argument, NULL, 'o' },
|
|
|
|
{ "hotonly", no_argument, NULL, 'h' },
|
|
|
|
{ "hot_threshold", required_argument, NULL, 't' },
|
|
|
|
{ 0, 0, 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Print overlap usage and exit. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
overlap_usage (void)
|
|
|
|
{
|
|
|
|
fnotice (stderr, "Overlap subcomand usage:");
|
|
|
|
print_overlap_usage_message (true);
|
|
|
|
exit (FATAL_EXIT_CODE);
|
|
|
|
}
|
|
|
|
|
|
|
|
int overlap_func_level;
|
|
|
|
int overlap_obj_level;
|
|
|
|
int overlap_hot_only;
|
|
|
|
int overlap_use_fullname;
|
|
|
|
double overlap_hot_threshold = 0.005;
|
|
|
|
|
|
|
|
/* Driver for profile overlap sub-command. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
do_overlap (int argc, char **argv)
|
|
|
|
{
|
|
|
|
int opt;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
optind = 0;
|
|
|
|
while ((opt = getopt_long (argc, argv, "vfFoht:", overlap_options, NULL)) != -1)
|
|
|
|
{
|
|
|
|
switch (opt)
|
|
|
|
{
|
|
|
|
case 'v':
|
|
|
|
verbose = true;
|
|
|
|
gcov_set_verbose ();
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
overlap_func_level = 1;
|
|
|
|
break;
|
|
|
|
case 'F':
|
|
|
|
overlap_use_fullname = 1;
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
overlap_obj_level = 1;
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
overlap_hot_only = 1;
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
overlap_hot_threshold = atof (optarg);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
overlap_usage ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (argc - optind == 2)
|
|
|
|
ret = profile_overlap (argv[optind], argv[optind+1]);
|
|
|
|
else
|
|
|
|
overlap_usage ();
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-07-11 07:48:07 +02:00
|
|
|
/* Print a usage message and exit. If ERROR_P is nonzero, this is an error,
|
|
|
|
otherwise the output of --help. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_usage (int error_p)
|
|
|
|
{
|
|
|
|
FILE *file = error_p ? stderr : stdout;
|
|
|
|
int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
|
|
|
|
|
|
|
|
fnotice (file, "Usage: %s [OPTION]... SUB_COMMAND [OPTION]...\n\n", progname);
|
|
|
|
fnotice (file, "Offline tool to handle gcda counts\n\n");
|
|
|
|
fnotice (file, " -h, --help Print this help, then exit\n");
|
|
|
|
fnotice (file, " -v, --version Print version number, then exit\n");
|
|
|
|
print_merge_usage_message (error_p);
|
|
|
|
print_rewrite_usage_message (error_p);
|
2014-10-08 23:51:41 +02:00
|
|
|
print_overlap_usage_message (error_p);
|
2014-07-11 07:48:07 +02:00
|
|
|
fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
|
|
|
|
bug_report_url);
|
|
|
|
exit (status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Print version information and exit. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_version (void)
|
|
|
|
{
|
|
|
|
fnotice (stdout, "%s %s%s\n", progname, pkgversion_string, version_string);
|
2016-01-04 14:03:35 +01:00
|
|
|
fnotice (stdout, "Copyright %s 2014-2016 Free Software Foundation, Inc.\n",
|
2014-07-11 07:48:07 +02:00
|
|
|
_("(C)"));
|
|
|
|
fnotice (stdout,
|
|
|
|
_("This is free software; see the source for copying conditions.\n"
|
|
|
|
"There is NO warranty; not even for MERCHANTABILITY or \n"
|
|
|
|
"FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
|
|
|
|
exit (SUCCESS_EXIT_CODE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct option options[] =
|
|
|
|
{
|
|
|
|
{ "help", no_argument, NULL, 'h' },
|
|
|
|
{ "version", no_argument, NULL, 'v' },
|
|
|
|
{ 0, 0, 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Process args, return index to first non-arg. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
process_args (int argc, char **argv)
|
|
|
|
{
|
|
|
|
int opt;
|
|
|
|
|
|
|
|
while ((opt = getopt_long (argc, argv, "+hv", options, NULL)) != -1)
|
|
|
|
{
|
|
|
|
switch (opt)
|
|
|
|
{
|
|
|
|
case 'h':
|
|
|
|
print_usage (false);
|
|
|
|
/* Print_usage will exit. */
|
|
|
|
case 'v':
|
|
|
|
print_version ();
|
|
|
|
/* Print_version will exit. */
|
|
|
|
default:
|
|
|
|
print_usage (true);
|
|
|
|
/* Print_usage will exit. */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return optind;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Main function for gcov-tool. */
|
|
|
|
|
|
|
|
int
|
|
|
|
main (int argc, char **argv)
|
|
|
|
{
|
|
|
|
const char *p;
|
|
|
|
const char *sub_command;
|
|
|
|
|
|
|
|
p = argv[0] + strlen (argv[0]);
|
|
|
|
while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
|
|
|
|
--p;
|
|
|
|
progname = p;
|
|
|
|
|
|
|
|
xmalloc_set_program_name (progname);
|
|
|
|
|
|
|
|
/* Unlock the stdio streams. */
|
|
|
|
unlock_std_streams ();
|
|
|
|
|
|
|
|
gcc_init_libintl ();
|
|
|
|
|
|
|
|
diagnostic_initialize (global_dc, 0);
|
|
|
|
|
|
|
|
/* Handle response files. */
|
|
|
|
expandargv (&argc, &argv);
|
|
|
|
|
|
|
|
process_args (argc, argv);
|
|
|
|
if (optind >= argc)
|
|
|
|
print_usage (true);
|
|
|
|
|
|
|
|
sub_command = argv[optind];
|
|
|
|
|
|
|
|
if (!strcmp (sub_command, "merge"))
|
|
|
|
return do_merge (argc - optind, argv + optind);
|
|
|
|
else if (!strcmp (sub_command, "rewrite"))
|
|
|
|
return do_rewrite (argc - optind, argv + optind);
|
2014-10-08 23:51:41 +02:00
|
|
|
else if (!strcmp (sub_command, "overlap"))
|
|
|
|
return do_overlap (argc - optind, argv + optind);
|
2014-07-11 07:48:07 +02:00
|
|
|
|
|
|
|
print_usage (true);
|
|
|
|
}
|