/* * tardy - a tar post-processor * Copyright (C) 1998, 1999, 2002 Peter Miller; * All rights reserved. * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * * MANIFEST: functions to manipulate cannonical path names */ #include #include rcstring cannonicalize(const rcstring &in) { rcstring out; rcstring path_text; const char *path_pos = in.to_c_string(); 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; }