//
// aegis - project change supervisor
// Copyright (C) 2014 Peter Miller
//
// This program 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 of the License, or (at
// your option) any later version.
//
// This program 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.
//
// You should have received a copy of the GNU General Public License along
// with this program. If not, see .
//
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct table_t
{
const char *name;
bool (*candidate)(const input::pointer &ifp);
iformat::pointer (*create)(const input::pointer &ifp);
};
static const table_t table[] =
{
{ "aedist", &iformat_cpio::candidate, &iformat_cpio::create },
{ "cpio", &iformat_cpio::candidate, &iformat_cpio::create },
{ "ae", &iformat_cpio::candidate, &iformat_cpio::create },
// { "aeexport", &iformat_git_fast::candidate, &iformat_git_fast::create },
// { "git-fast-import",
// &iformat_git_fast::candidate, &iformat_git_fast::create },
// { "patch", &iformat_patch::candidate, &iformat_patch::create },
// { "diff", &iformat_patch::candidate, &iformat_patch::create },
// { "aepatch", &iformat_patch::candidate, &iformat_patch::create },
// { "revml", &iformat_revml::candidate, &iformat_revml::create },
// { "aerevml", &iformat_revml::candidate, &iformat_revml::create },
// { "tailor", &iformat_tailor::candidate, &iformat_tailor::create },
// { "aetailor", &iformat_tailor::candidate, &iformat_tailor::create },
{ "tar", &iformat_tar::candidate, &iformat_tar::create },
{ "aetar", &iformat_tar::candidate, &iformat_tar::create },
};
void
iformat::list(void)
{
for (const table_t *tp = table; tp < ENDOF(table); ++tp)
{
printf("%s\n", tp->name);
while ((tp + 1) < ENDOF(table))
{
// suppress duplicates
if (tp->create != tp[1].create)
break;
++tp;
}
}
}
iformat::pointer
iformat::factory(const nstring &name, const input::pointer &ifp)
{
trace(("%s\n", __PRETTY_FUNCTION__));
nstring name_lc = nstring(name).downcase();
if (name_lc.empty())
name_lc = nstring(progname_get()).downcase();
trace(("name_lc = %s\n", name_lc.quote_c().c_str()));
//
// First we attempt to choose the format based on argv[0], or a name
// given to the --input-format=name option. This means the old
// programs work, but everything is directed into aedist(1).
//
if (!name_lc.empty())
{
for (const table_t *tp = table; tp < ENDOF(table); ++tp)
{
if (name_lc == nstring(tp->name))
{
trace(("found by name\n"));
if (option_verbose_get())
{
error_raw
(
"using container type of --input-format=%s",
nstring(tp->name).quote_c().c_str()
);
}
return tp->create(ifp);
}
}
trace(("not found by name\n"));
double best_weight = 0.6;
const table_t *best_tp = 0;
for (const table_t *tp = table; tp < ENDOF(table); ++tp)
{
double w = fstrcmp(name_lc.c_str(), tp->name);
if (w > best_weight)
{
best_weight = w;
best_tp = tp;
}
}
if (best_tp)
{
error_raw
(
"unable to determine container type of --input-format=%s "
"option, did you mean %s instead?",
name.quote_c().c_str(),
nstring(best_tp->name).quote_c().c_str()
);
}
else
{
error_raw
(
"unable to determine container type of --input-format=%s "
"option",
name.quote_c().c_str()
);
}
trace(("mark\n"));
}
//
// Guess what to do based on the input file name.
// Or its contents, etc.
//
for (const table_t *tp = table; tp < ENDOF(table); ++tp)
{
trace(("candidate? %s\n", nstring(tp->name).quote_c().c_str()));
if (tp->candidate(ifp))
{
trace(("found by candidate\n"));
if (option_verbose_get())
{
error_raw
(
"using container type of --input-format=%s",
nstring(tp->name).quote_shell().c_str()
);
}
return tp->create(ifp);
}
}
trace(("no candidates\n"));
if (option_verbose_get())
{
error_raw
(
"unable to determine container type of %s, "
"defaulting to --input-format=aedist",
ifp->name().quote_c().c_str()
);
}
// Default to the historical format.
return iformat_cpio::create(ifp);
}
// vim: set ts=8 sw=4 et :