--- a/sc2src/pathut.cpp
+++ b/sc2src/pathut.cpp
@@ -1,15 +1,15 @@
/* Copyright (C) 2004 J.F.Dockes
* 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
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 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.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
@@ -52,6 +52,7 @@
#include <stack>
#include <set>
#include <vector>
+#include <regex>
#include "pathut.h"
#include "smallut.h"
@@ -761,6 +762,96 @@
return url.find("file://") == 0;
}
+static std::regex
+re_uriparse("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?",
+ std::regex::extended);
+
+ParsedUri::ParsedUri(std::string uri)
+{
+ std::smatch mr;
+ parsed = regex_match(uri, mr, re_uriparse);
+ if (!parsed)
+ return;
+ // cf http://www.ietf.org/rfc/rfc2396.txt
+ // scheme = $2
+ // authority = $4
+ // path = $5
+ // query = $7
+ // fragment = $9
+ if (mr[2].matched) {
+ scheme = mr[2].str();
+ }
+ if (mr[4].matched) {
+ string auth = mr[4].str();
+ // user:pass@host, user@host
+ string::size_type at = auth.find_first_of('@');
+ if (at != string::npos) {
+ host = auth.substr(at+1);
+ string::size_type colon = auth.find_first_of(':');
+ if (colon != string::npos && colon < at) {
+ user = auth.substr(0, colon);
+ pass = auth.substr(colon+1, at-colon-1);
+ } else {
+ user = auth.substr(0, at);
+ }
+ } else {
+ host.swap(auth);
+ }
+ string::size_type pc = host.find_first_of(':');
+ if (pc != string::npos) {
+ port = host.substr(pc+1);
+ host = host.substr(0, pc);
+ }
+ }
+ if (mr[5].matched) {
+ path = mr[5].str();
+ }
+ if (mr[7].matched) {
+ query = mr[7].str();
+ string::size_type pos=0, amp, eq;
+ string nm, val;
+ for (;;) {
+ nm.clear();
+ val.clear();
+ amp = query.find_first_of('&', pos);
+ //cerr << "pos " << pos << " amp " << amp << endl;
+ if (amp > pos && amp != string::npos) {
+ eq = query.find_first_of('=', pos);
+ if (eq > amp || eq == string::npos) {
+ nm = query.substr(pos, amp-pos);
+ } else {
+ nm = query.substr(pos, eq-pos);
+ val = query.substr(eq+1, amp-eq-1);
+ }
+ pos = amp + 1;
+ } else if (amp == string::npos) {
+ if (pos < query.size()-1) {
+ eq = query.find_first_of('=', pos);
+ if (eq == string::npos) {
+ nm = query.substr(pos);
+ } else {
+ nm = query.substr(pos, eq-pos);
+ val = query.substr(eq+1);
+ }
+ }
+ pos = query.size()-1;
+ } else {
+ pos++;
+ }
+ if (!nm.empty()) {
+ parsedquery.push_back(pair<string,string>(nm, val));
+ }
+ if (pos >= query.size()-1) {
+ break;
+ }
+ }
+
+ }
+ if (mr[9].matched) {
+ fragment = mr[9].str();
+ }
+}
+
bool readdir(const string& dir, string& reason, set<string>& entries)
{
struct stat st;