//
// tardy - a tar post-processor
// Copyright (C) 1998, 1999, 2002, 2008, 2009, 2011, 2012 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/assert.h>

#include <libtardy/cannonical.h>


rcstring
cannonicalize(const rcstring &in)
{
    rcstring out;
    rcstring path_text;
    const char *path_pos = in.c_str();
    enum path_token_ty { path_dot, path_slash, path_name, path_end };
    path_token_ty path_token;

    int state = 0;
    while (state >= 0)
    {
        //
        // figure the next token in the path
        //
        switch (*path_pos)
        {
        case 0:
            path_text = "";
            path_token = path_end;
            break;

        case '/':
            ++path_pos;
            while (*path_pos == '/')
                ++path_pos;
            path_text = "/";
            path_token = path_slash;
            break;

        default:
            const char *cp = path_pos;
            for (;;)
            {
                ++path_pos;
                if (!*path_pos || *path_pos == '/')
                    break;
            }
            path_text = rcstring(cp, path_pos - cp);
            static rcstring dot(".");
            if (path_text == dot)
                path_token = path_dot;
            else
                path_token = path_name;
            break;
        }

        //
        // do something with the token
        //
        switch (path_token)
        {
        case path_dot:
            switch (state)
            {
            case 0:
            case 2:
                ++state;
                break;

            default:
                assert(0);
                state = -1;
                break;
            }
            break;

        case path_name:
            switch (state)
            {
            case 0:
                out += path_text;
                state = 4;
                break;

            case 2:
                out += "/";
                out += path_text;
                state = 4;
                break;

            default:
                assert(0);
                state = -1;
                break;
            }
            break;

        case path_slash:
            switch (state)
            {
            case 0:
            case 3:
            case 4:
                state = 2;
                break;

            case 1:
                state = 0;
                break;

            default:
                assert(0);
                state = -1;
                break;
            }
            break;

        case path_end:
            switch (state)
            {
            case 0:
            case 1:
                out += ".";
                break;
            }
            state = -1;
            break;
        }
    }
    return out;
}


// vim: set ts=8 sw=4 et :
