mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
277 lines
6.5 KiB
C++
277 lines
6.5 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
// taskwarrior - a command line task list manager.
|
|
//
|
|
// Copyright 2010 - 2011, Johannes Schlatow.
|
|
// 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.,
|
|
// 51 Franklin Street, Fifth Floor,
|
|
// Boston, MA
|
|
// 02110-1301
|
|
// USA
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "Context.h"
|
|
#include "Uri.h"
|
|
|
|
extern Context context;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Uri::Uri ()
|
|
{
|
|
parsed = false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Uri::Uri (const Uri& other)
|
|
{
|
|
if (this != &other)
|
|
{
|
|
data = other.data;
|
|
host = other.host;
|
|
path = other.path;
|
|
user = other.user;
|
|
port = other.port;
|
|
protocol = other.protocol;
|
|
parsed = other.parsed;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Uri::Uri (const std::string& in, const std::string& configPrefix)
|
|
{
|
|
data = in;
|
|
parsed = false;
|
|
if (configPrefix != "")
|
|
expand(configPrefix);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Uri::~Uri ()
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Uri& Uri::operator= (const Uri& other)
|
|
{
|
|
if (this != &other)
|
|
{
|
|
this->data = other.data;
|
|
this->host = other.host;
|
|
this->path = other.path;
|
|
this->user = other.user;
|
|
this->port = other.port;
|
|
this->protocol = other.protocol;
|
|
this->parsed = other.parsed;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
Uri::operator std::string () const
|
|
{
|
|
return data;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
std::string Uri::name () const
|
|
{
|
|
if (path.length ())
|
|
{
|
|
std::string::size_type slash = path.rfind ('/');
|
|
if (slash != std::string::npos)
|
|
return path.substr (slash + 1, std::string::npos);
|
|
}
|
|
|
|
return path;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
std::string Uri::parent () const
|
|
{
|
|
if (path.length ())
|
|
{
|
|
std::string::size_type slash = path.rfind ('/');
|
|
if (slash != std::string::npos)
|
|
return path.substr (0, slash+1);
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
std::string Uri::extension () const
|
|
{
|
|
if (path.length ())
|
|
{
|
|
std::string::size_type dot = path.rfind ('.');
|
|
if (dot != std::string::npos)
|
|
return path.substr (dot + 1, std::string::npos);
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
bool Uri::is_directory () const
|
|
{
|
|
if (is_local ()) {
|
|
return Path (this->data).is_directory ();
|
|
} else
|
|
return (path == ".")
|
|
|| (path == "")
|
|
|| (path[path.length()-1] == '/');
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
bool Uri::is_local () const
|
|
{
|
|
if (parsed)
|
|
return (protocol == "");
|
|
else
|
|
return ( (data.find("://") == std::string::npos)
|
|
&& (data.find(":") == std::string::npos) );
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
bool Uri::append (const std::string& path)
|
|
{
|
|
if (is_directory ())
|
|
{
|
|
this->path += path;
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
bool Uri::expand (const std::string& configPrefix )
|
|
{
|
|
std::string tmp;
|
|
if (data.length ())
|
|
{
|
|
// try to replace argument with uri from config
|
|
tmp = context.config.get (configPrefix + "." + data + ".uri");
|
|
}
|
|
else
|
|
{
|
|
// get default target from config
|
|
tmp = context.config.get (configPrefix + ".default.uri");
|
|
}
|
|
|
|
if (tmp != "")
|
|
{
|
|
data = tmp;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void Uri::parse ()
|
|
{
|
|
if (parsed)
|
|
return;
|
|
|
|
if (is_local ())
|
|
{
|
|
path = data;
|
|
parsed = true;
|
|
return;
|
|
}
|
|
|
|
std::string::size_type pos;
|
|
std::string data = this->data;
|
|
std::string pathDelimiter = "/";
|
|
|
|
user = "";
|
|
port = "";
|
|
|
|
// skip ^.*://
|
|
if ((pos = data.find ("://")) != std::string::npos)
|
|
{
|
|
protocol = data.substr(0, pos);
|
|
data = data.substr (pos+3);
|
|
// standard syntax: protocol://[user@]host.xz[:port]/path/to/undo.data
|
|
pathDelimiter = "/";
|
|
}
|
|
else
|
|
{
|
|
protocol = "ssh";
|
|
// scp-like syntax: [user@]host.xz:path/to/undo.data
|
|
pathDelimiter = ":";
|
|
}
|
|
|
|
// user delimited by single quotes?
|
|
if ( data[0] == '\''
|
|
&& (pos = data.find("'", 1)) != std::string::npos )
|
|
{
|
|
if (data[pos+1] == '@')
|
|
{
|
|
// end of user name
|
|
user = data.substr (1, pos-1);
|
|
data = data.substr (pos+2);
|
|
}
|
|
else
|
|
{
|
|
throw std::string ("Could not parse uri '") + data + "', wrong usage of single quotes.";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// find user name
|
|
if ((pos = data.find ("@")) != std::string::npos)
|
|
{
|
|
user = data.substr (0, pos);
|
|
data = data.substr (pos+1);
|
|
}
|
|
}
|
|
|
|
// get host, port and path
|
|
if ((pos = data.find (pathDelimiter)) != std::string::npos)
|
|
{
|
|
host = data.substr (0, pos);
|
|
path = data.substr (pos+1);
|
|
}
|
|
else
|
|
{
|
|
throw std::string ("The uri '") + data + "' is not in the expected format.";
|
|
}
|
|
|
|
// path is absolute for ssh:// syntax
|
|
if ( (protocol == "ssh") && (pathDelimiter == "/") )
|
|
{
|
|
path = "/" + path;
|
|
}
|
|
|
|
// port specified?
|
|
// remark: this find() will never be != npos for scp-like syntax
|
|
// because we found pathDelimiter, which is ":", before
|
|
if ((pos = host.find (":")) != std::string::npos)
|
|
{
|
|
port = host.substr (pos+1);
|
|
host = host.substr (0,pos);
|
|
}
|
|
|
|
parsed = true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// vim: et ts=2 sw=2
|