Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
19 KB
Referenced Files
None
Subscribers
None
diff --git a/util/file-system.cpp b/util/file-system.cpp
index ec33aca5..d4a11a82 100644
--- a/util/file-system.cpp
+++ b/util/file-system.cpp
@@ -1,177 +1,304 @@
#include "funcs.h"
#include "file-system.h"
#include "system.h"
#include <dirent.h>
#include <sstream>
#include <exception>
#include <string>
#ifdef _WIN32
#define _WIN32_IE 0x400
#include <shlobj.h>
#endif
using namespace std;
namespace Filesystem{
NotFound::NotFound(const std::string & file):
exception(),
reason(file){
}
NotFound::~NotFound() throw(){
}
#ifdef _WIN32
-string userDirectory(){
+AbsolutePath userDirectory(){
ostringstream str;
char path[MAX_PATH];
SHGetSpecialFolderPathA(0, path, CSIDL_APPDATA, false);
str << path << "/paintown/";
- return str.str();
+ return AbsolutePath(str.str());
}
-string configFile(){
+AbsolutePath configFile(){
ostringstream str;
char path[MAX_PATH];
SHGetSpecialFolderPathA(0, path, CSIDL_APPDATA, false);
str << path << "/paintown_configuration.txt";
- return str.str();
+ return AbsolutePath(str.str());
}
#else
-string configFile(){
+AbsolutePath configFile(){
ostringstream str;
/* what if HOME isn't set? */
str << getenv("HOME") << "/.paintownrc";
- return str.str();
+ return AbsolutePath(str.str());
}
-string userDirectory(){
+AbsolutePath userDirectory(){
ostringstream str;
/* what if HOME isn't set? */
str << getenv("HOME") << "/.paintown/";
- return str.str();
+ return AbsolutePath(str.str());
}
#endif
-static string lookup(const std::string & path) throw (NotFound){
+static AbsolutePath lookup(const RelativePath path) throw (NotFound){
/* first try the main data directory */
- string final = Util::getDataPath2() + path;
- if (System::readable(final)){
+ AbsolutePath final = Util::getDataPath2().join(path);
+ if (System::readable(final.path())){
return final;
}
/* then try the user directory, like ~/.paintown */
- final = userDirectory() + path;
- if (System::readable(final)){
+ final = userDirectory().join(path);
+ if (System::readable(final.path())){
return final;
}
/* then just look in the cwd */
- if (System::readable(path)){
- return path;
+ if (System::readable(path.path())){
+ return AbsolutePath(path.path());
}
ostringstream out;
- out << "Cannot find " << path << ". I looked in '" << (Util::getDataPath2() + path) << "', '" << (userDirectory() + path) << "', and '" << path << "'" << endl;
+ out << "Cannot find " << path.path() << ". I looked in '" << Util::getDataPath2().join(path).path() << "', '" << userDirectory().join(path).path() << "', and '" << path.path() << "'" << endl;
throw NotFound(out.str());
}
-static vector<string> findDirectoriesIn(const std::string & path){
- vector<string> dirs;
- DIR * dir = opendir(path.c_str());
+static vector<AbsolutePath> findDirectoriesIn(const AbsolutePath & path){
+ vector<AbsolutePath> dirs;
+ DIR * dir = opendir(path.path().c_str());
if (dir == NULL){
return dirs;
}
struct dirent * entry = readdir(dir);
while (entry != NULL){
- string total = path + "/" + entry->d_name;
+ string total = path.path() + "/" + entry->d_name;
if (System::isDirectory(total)){
- dirs.push_back(total);
+ dirs.push_back(AbsolutePath(total));
}
entry = readdir(dir);
}
closedir(dir);
return dirs;
}
-vector<string> findDirectories(const std::string & path){
- vector<string> dirs;
+vector<AbsolutePath> findDirectories(const RelativePath & path){
+ typedef vector<AbsolutePath> Paths;
+ Paths dirs;
- vector<string> main_dirs = findDirectoriesIn(Util::getDataPath2() + path);
- vector<string> user_dirs = findDirectoriesIn(userDirectory() + path);
- vector<string> here_dirs = findDirectoriesIn(path);
+ Paths main_dirs = findDirectoriesIn(Util::getDataPath2().join(path));
+ Paths user_dirs = findDirectoriesIn(userDirectory().join(path));
+ Paths here_dirs = findDirectoriesIn(Filesystem::AbsolutePath(path.path()));
dirs.insert(dirs.end(), main_dirs.begin(), main_dirs.end());
dirs.insert(dirs.end(), user_dirs.begin(), user_dirs.end());
dirs.insert(dirs.end(), here_dirs.begin(), here_dirs.end());
return dirs;
}
/* remove extra path separators (/) */
static string sanitize(string path){
size_t double_slash = path.find("//");
while (double_slash != string::npos){
path.erase(double_slash, 1);
double_slash = path.find("//");
}
return path;
}
-std::string find(const std::string path) throw (NotFound){
+/*
+std::string find(const std::string path){
if (path.length() == 0){
throw NotFound("No path given");
}
if (path[0] == '/'){
string str(path);
str.erase(0, 1);
string out = lookup(str);
if (System::isDirectory(out)){
return sanitize(out + "/");
}
return sanitize(out);
}
string out = lookup(path);
if (System::isDirectory(out)){
return sanitize(out + "/");
}
return sanitize(out);
}
+*/
-std::string cleanse(const std::string & path){
- string str = path;
- if (str.find(Util::getDataPath2()) == 0){
- str.erase(0, Util::getDataPath2().length());
- } else if (str.find(userDirectory()) == 0){
- str.erase(0, userDirectory().length());
+AbsolutePath find(const RelativePath & path){
+ if (path.isEmpty()){
+ throw NotFound("No path given");
}
- return str;
+
+ AbsolutePath out = lookup(path);
+ if (System::isDirectory(out.path())){
+ return AbsolutePath(sanitize(out.path() + "/"));
+ }
+ return AbsolutePath(sanitize(out.path()));
+}
+
+RelativePath cleanse(const AbsolutePath & path){
+ string str = path.path();
+ if (str.find(Util::getDataPath2().path()) == 0){
+ str.erase(0, Util::getDataPath2().path().length());
+ } else if (str.find(userDirectory().path()) == 0){
+ str.erase(0, userDirectory().path().length());
+ }
+ return RelativePath(str);
+}
+
+static string dirname(string path){
+ if (path.find("/") != string::npos ||
+ path.find("\\") != string::npos){
+ size_t rem = path.find_last_of("/");
+ if (rem != string::npos){
+ return path.substr(0, rem+1);
+ }
+
+ rem = path.find_last_of("\\");
+ if (rem != string::npos){
+ return path.substr(0, rem+1);
+ }
+ }
+
+ return "";
}
std::string stripDir(const std::string & str){
std::string temp = str;
if (str.find( "/") != std::string::npos || str.find( "\\") != std::string::npos){
size_t rem = temp.find_last_of( "/" );
if (rem != std::string::npos){
return str.substr(rem+1,str.size());
}
rem = temp.find_last_of( "\\" );
if( rem != std::string::npos ){
return str.substr(rem+1,str.size());
}
}
return str;
}
std::string removeExtension(const std::string & str){
if (str.find(".") != std::string::npos){
return str.substr(0, str.find_last_of("."));
}
return str;
}
+const string & Path::path() const {
+ return mypath;
+}
+
+bool Path::isEmpty() const {
+ return mypath.empty();
+}
+
+Path::~Path(){
+}
+
+Path::Path(){
+}
+
+static const std::string invertSlashes(const string & str){
+ string tempStr = str;
+ if (tempStr.find('\\') != string::npos){
+ for (int i = tempStr.size()-1; i>-1; --i){
+ if (tempStr[i] == '\\'){
+ tempStr[i] = '/';
+ }
+ }
+ }
+
+ return tempStr;
+}
+
+Path::Path(const std::string & path):
+mypath(sanitize(invertSlashes(path))){
+}
+
+Path::Path(const Path & path):
+mypath(sanitize(invertSlashes(path.path()))){
+}
+
+RelativePath::RelativePath(){
+}
+
+RelativePath::RelativePath(const std::string & path):
+Path(path){
+}
+
+RelativePath::RelativePath(const RelativePath & path):
+Path(path){
+}
+
+RelativePath RelativePath::getDirectory() const {
+ return RelativePath(dirname(path()));
+}
+
+RelativePath RelativePath::getFilename() const {
+ return RelativePath(stripDir(path()));
+}
+
+RelativePath RelativePath::join(const RelativePath & him) const {
+ return RelativePath(sanitize(path() + "/" + him.path()));
+}
+
+RelativePath & RelativePath::operator=(const RelativePath & copy){
+ setPath(copy.path());
+ return *this;
+}
+
+AbsolutePath::AbsolutePath(){
+}
+
+AbsolutePath::AbsolutePath(const std::string & path):
+Path(path){
+}
+
+AbsolutePath::AbsolutePath(const AbsolutePath & path):
+Path(path){
+}
+
+AbsolutePath & AbsolutePath::operator=(const AbsolutePath & copy){
+ setPath(copy.path());
+ return *this;
+}
+
+bool AbsolutePath::operator==(const AbsolutePath & path) const {
+ return this->path() == path.path();
+}
+
+AbsolutePath AbsolutePath::getDirectory() const {
+ return AbsolutePath(dirname(path()));
+}
+
+AbsolutePath AbsolutePath::getFilename() const {
+ return AbsolutePath(stripDir(path()));
+}
+
+AbsolutePath AbsolutePath::join(const RelativePath & path) const {
+ return AbsolutePath(sanitize(this->path() + "/" + path.path()));
+}
+
}
diff --git a/util/file-system.h b/util/file-system.h
index 4d2c906e..7bb0c11c 100644
--- a/util/file-system.h
+++ b/util/file-system.h
@@ -1,61 +1,103 @@
#ifndef _paintown_file_system_h
#define _paintown_file_system_h
#include <exception>
#include <string>
#include <vector>
namespace Filesystem{
class NotFound: public std::exception {
public:
NotFound(const std::string & file);
virtual ~NotFound() throw();
const std::string & getReason() const {
return reason;
}
private:
std::string reason;
};
+ class Path{
+ public:
+ const std::string & path() const;
+ bool isEmpty() const;
+
+ virtual ~Path();
+
+ protected:
+ Path();
+ Path(const std::string & path);
+ Path(const Path & path);
+
+ virtual inline void setPath(const std::string & s){
+ mypath = s;
+ }
+
+ std::string mypath;
+ };
+
/* relative path should not have the leading data directory on it, just
* the path within the paintown system.
*/
- class RelativePath{
+ class RelativePath: public Path {
+ public:
+ explicit RelativePath();
+ explicit RelativePath(const std::string & path);
+ RelativePath(const RelativePath & path);
+
+ virtual RelativePath getDirectory() const;
+ virtual RelativePath getFilename() const;
+
+ /* a/ + b/ = a/b/ */
+ RelativePath join(const RelativePath & path) const;
+ RelativePath & operator=(const RelativePath & copy);
};
/* absolute paths should have the entire filesystem path on it */
- class AbsolutePath{
+ class AbsolutePath: public Path {
+ public:
+ explicit AbsolutePath();
+ explicit AbsolutePath(const std::string & path);
+ AbsolutePath(const AbsolutePath & path);
+ AbsolutePath & operator=(const AbsolutePath & copy);
+
+ bool operator==(const AbsolutePath & path) const;
+
+ virtual AbsolutePath getDirectory() const;
+ virtual AbsolutePath getFilename() const;
+
+ AbsolutePath join(const RelativePath & path) const;
};
/* given a relative path like sounds/arrow.png, prepend the proper
* data path to it to give data/sounds/arrow.png
*/
- std::string find(const std::string path) throw (NotFound);
+ AbsolutePath find(const RelativePath & path);
/* remove the data path from a string
* data/sounds/arrow.png -> sounds/arrow.png
*/
- std::string cleanse(const std::string & path);
+ RelativePath cleanse(const AbsolutePath & path);
/* returns all the directories starting with the given path.
* will look in the main data directory, the user directory, and
* the current working directory.
*/
- std::vector<std::string> findDirectories(const std::string & path);
+ std::vector<AbsolutePath> findDirectories(const RelativePath & path);
/* basename, just get the filename and remove the directory part */
std::string stripDir(const std::string & str);
/* remove extension. foo.txt -> foo */
std::string removeExtension(const std::string & str);
/* user specific directory to hold persistent data */
- std::string userDirectory();
+ AbsolutePath userDirectory();
/* user specific path to store the configuration file */
- std::string configFile();
+ AbsolutePath configFile();
}
#endif
diff --git a/util/funcs.cpp b/util/funcs.cpp
index e4a01df7..a91d08cf 100644
--- a/util/funcs.cpp
+++ b/util/funcs.cpp
@@ -1,208 +1,209 @@
#include "funcs.h"
#include "globals.h"
#include <allegro.h>
#include <vector>
#include <string>
+#include "file-system.h"
#ifndef WINDOWS
#include <unistd.h>
#endif
using namespace std;
/* remove this once cmake and scons properly set DATA_PATH */
#ifndef DATA_PATH
#define DATA_PATH "data"
#endif
/* the build system should define DATA_PATH */
static string dataPath = DATA_PATH;
const double Util::pi = 3.14159265;
double Util::radians(double degree){
return degree * pi / 180.0;
}
/*
inline int rnd( int q ){
if ( q <= 0 ) return 0;
return (int)( rand() % q );
}
*/
int Util::max(int a, int b){
if (a>b){
return a;
}
return b;
}
int Util::min(int a, int b){
if (a<b){
return a;
}
return b;
}
int Util::rnd( int q, int min, int range ){
return q - min + rnd( range );
}
int Util::rnd( int min, int max ){
return rnd( max - min ) + min;
}
void Util::rest( int x ){
::rest( x );
}
bool Util::checkVersion(int version){
if (version == Global::getVersion()){
return true;
}
/* when an incompatible version is made, add a check here, like
* version < getVersion(3, 5)
* would mean any client below version 3.5 is incompatible.
*
* assume versions of client's greater than ourself is compatible, but
* this may not be true. There is no way to check this.
*/
if (version < 0){
return false;
}
return true;
}
void Util::setDataPath( const string & str ){
dataPath = str;
}
-string Util::getDataPath2(){
- return dataPath + "/";
+Filesystem::AbsolutePath Util::getDataPath2(){
+ return Filesystem::AbsolutePath(dataPath + "/");
}
bool Util::exists( const string & file ){
return ::exists( file.c_str() ) != 0;
}
-vector< string > Util::getFiles( const string & dataPath, const string & find ){
+vector< string > Util::getFiles( const Filesystem::AbsolutePath & dataPath, const string & find ){
struct al_ffblk info;
vector< string > files;
- if ( al_findfirst( (dataPath + find).c_str(), &info, FA_ALL ) != 0 ){
+ if ( al_findfirst( (dataPath.path() + find).c_str(), &info, FA_ALL ) != 0 ){
return files;
}
- files.push_back( dataPath + string( info.name ) );
+ files.push_back( dataPath.path() + string( info.name ) );
while ( al_findnext( &info ) == 0 ){
- files.push_back( dataPath + string( info.name ) );
+ files.push_back( dataPath.path() + string( info.name ) );
}
al_findclose( &info );
return files;
}
void Util::blend_palette( int * pal, int mp, int sc, int ec ) {
ASSERT( pal );
ASSERT( mp != 0 );
int sc_r = getr( sc );
int sc_g = getg( sc );
int sc_b = getb( sc );
int ec_r = getr( ec );
int ec_g = getg( ec );
int ec_b = getb( ec );
for ( int q = 0; q < mp; q++ ) {
float j = (float)( q + 1 ) / (float)( mp );
int f_r = (int)( 0.5 + (float)( sc_r ) + (float)( ec_r-sc_r ) * j );
int f_g = (int)( 0.5 + (float)( sc_g ) + (float)( ec_g-sc_g ) * j );
int f_b = (int)( 0.5 + (float)( sc_b ) + (float)( ec_b-sc_b ) * j );
pal[q] = makecol( f_r, f_g, f_b );
}
}
string Util::trim(const std::string & str){
string s;
size_t startpos = str.find_first_not_of(" \t");
size_t endpos = str.find_last_not_of(" \t");
// if all spaces or empty return an empty string
if ((string::npos == startpos) ||
(string::npos == endpos)){
return "";
} else {
return str.substr(startpos, endpos-startpos+1);
}
return str;
}
/* makes the first letter of a string upper case */
string Util::upcase(std::string str){
if ( str.length() > 0 && (str[0] >= 'a' && str[0] <= 'z') ){
str[0] = str[0] - 'a' + 'A';
}
return str;
}
/*Gets the minimum of three values*/
static int minimum(int a,int b,int c){
int min=a;
if(b<min)
min=b;
if(c<min)
min=c;
return min;
}
/* Compute levenshtein distance between s and t
* from: http://www.merriampark.com/ldc.htm
*/
static int levenshtein_distance(const char *s, const char *t){
//Step 1
int k,i,j,n,m,cost,distance;
int * d;
n=strlen(s);
m=strlen(t);
if(n!=0&&m!=0){
d = (int*) malloc((sizeof(int))*(m+1)*(n+1));
m++;
n++;
//Step 2
for(k=0;k<n;k++)
d[k]=k;
for(k=0;k<m;k++)
d[k*n]=k;
//Step 3 and 4
for(i=1;i<n;i++)
for(j=1;j<m;j++)
{
//Step 5
if(s[i-1]==t[j-1])
cost=0;
else
cost=1;
//Step 6
d[j*n+i]=minimum(d[(j-1)*n+i]+1,d[j*n+i-1]+1,d[(j-1)*n+i-1]+cost);
}
distance=d[n*m-1];
free(d);
return distance;
} else {
return -1; //a negative return value means that one or both strings are empty.
}
}
int Util::levenshtein(const std::string & str1, const std::string & str2){
return levenshtein_distance(str1.c_str(), str2.c_str());
}
#ifndef ALLEGRO_WINDOWS
int Util::getPipe(int files[2]){
return pipe(files);
}
#endif
diff --git a/util/funcs.h b/util/funcs.h
index 8d87be19..91fa29df 100644
--- a/util/funcs.h
+++ b/util/funcs.h
@@ -1,63 +1,64 @@
-#ifndef _funcs_h
-#define _funcs_h
+#ifndef _paintown_funcs_h
+#define _paintown_funcs_h
#include <stdlib.h>
#include <vector>
#include <string>
#include "regex.h"
+#include "file-system.h"
namespace Util{
extern const double pi;
/* returns a number between 0 and q-1. you will never get `q'. if
* you wanted to get `q' then pass in q+1
*/
inline int rnd( int q ){
if (q <= 0){
return 0;
}
return (int)(rand() % q);
}
-std::vector< std::string > getFiles( const std::string & dataPath, const std::string & find );
+std::vector< std::string > getFiles(const Filesystem::AbsolutePath & dataPath, const std::string & find );
double radians(double degree);
-std::string getDataPath2();
+Filesystem::AbsolutePath getDataPath2();
void setDataPath( const std::string & str );
bool exists( const std::string & file );
/* check that `version' is compatible with this program, mostly used
* for network clients.
*/
bool checkVersion(int version);
/* return a random number + some range between min/max */
int rnd( int q, int min, int max );
int max(int a, int b);
int min(int a, int b);
/* return a number between min/max */
int rnd( int min, int max );
void blend_palette( int * pal, int mp, int sc, int ec );
void rest( int x );
std::string trim(const std::string & str);
std::string upcase(std::string str);
int levenshtein(const std::string & str1, const std::string & str2);
int getPipe(int files[2]);
}
#endif

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jun 11, 1:19 PM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
69212
Default Alt Text
(19 KB)

Event Timeline