//
// tardy - a tar post-processor
// Copyright (C) 2011 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 <http://www.gnu.org/licenses/>.
//

#include <libtardy/ac/string.h>

#include <libtardy/rcstring.h>
#include <libtardy/rcstring/accumulator.h>


rcstring
rcstring::substitute(const rcstring &from, const rcstring &to,
    size_t how_many_times) const
{
    if (from.empty() || how_many_times == 0)
    {
        rcstring result;
        result.p = str_copy(p);
        return result;
    }
    if (how_many_times == (size_t)-1)
        how_many_times = size();
    const char *cp = c_str();
    const char *end = cp + size();
    rcstring_accumulator ac;
    while (cp < end)
    {
        if (how_many_times == 0)
        {
            ac.push_back(cp, end - cp);
            break;
        }
        --how_many_times;

        // We could use strstr(3) instead, but it isn't as robust.
        // On the other hand, fewer implementations have bugs.
#ifdef HAVE_MEMMEM
        const char *where =
            (const char *)memmem(cp, end - cp, from.c_str(), from.size());
#else
        const char *where = strstr(cp, from.c_str());
#endif
        if (!where)
        {
            ac.push_back(cp, end - cp);
            break;
        }
        cp = where + from.size();
        ac.push_back(to);
    }
    return ac.mkstr();
}
