Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F126649
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
23 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/util/file-system.cpp b/util/file-system.cpp
index 2604054e..2ab173a7 100644
--- a/util/file-system.cpp
+++ b/util/file-system.cpp
@@ -1,412 +1,420 @@
#ifdef USE_ALLEGRO
#include <allegro.h>
/* FIXME: replace with <winalleg.h> */
#ifdef _WIN32
#define BITMAP dummyBITMAP
#include <windows.h>
#undef BITMAP
#endif
#endif
#include "funcs.h"
#include "file-system.h"
#include "system.h"
#include "globals.h"
#include <dirent.h>
#include <sstream>
#include <exception>
#include <string>
#include <ostream>
#ifndef USE_ALLEGRO
/* some sfl symbols conflict with allegro */
#include "sfl/sfl.h"
#include "sfl/sfldir.h"
#endif
#ifdef _WIN32
#define _WIN32_IE 0x400
#include <shlobj.h>
#endif
using namespace std;
namespace Filesystem{
Exception::Exception(const std::string & where, int line, const std::string & file):
Exc::Base(where, line),
reason(file){
}
Exception::Exception(const std::string & where, int line, const Exc::Base & nested, const std::string & file):
Exc::Base(where, line, nested),
reason(file){
}
Exception::Exception(const Exception & copy):
Exc::Base(copy),
reason(copy.reason){
}
Exception::~Exception() throw (){
}
const std::string Exception::getReason() const {
return reason;
}
NotFound::NotFound(const std::string & where, int line, const std::string & file):
Exception(where, line, file + string(" was not found")){
}
NotFound::NotFound(const std::string & where, int line, const Exc::Base & nested, const std::string & file):
Exception(where, line, nested, file + string(" was not found")){
}
NotFound::NotFound(const NotFound & copy):
Exception(copy){
}
NotFound::~NotFound() throw (){
}
IllegalPath::IllegalPath(const std::string & where, int line, const std::string & file):
Exception(where, line, file){
}
IllegalPath::IllegalPath(const std::string & where, int line, const Exc::Base & nested, const std::string & file):
Exception(where, line, nested, file){
}
IllegalPath::IllegalPath(const IllegalPath & copy):
Exception(copy){
}
IllegalPath::~IllegalPath() throw(){
}
#ifdef _WIN32
AbsolutePath userDirectory(){
ostringstream str;
char path[MAX_PATH];
SHGetSpecialFolderPathA(0, path, CSIDL_APPDATA, false);
str << path << "/paintown/";
return AbsolutePath(str.str());
}
AbsolutePath configFile(){
ostringstream str;
char path[MAX_PATH];
SHGetSpecialFolderPathA(0, path, CSIDL_APPDATA, false);
str << path << "/paintown_configuration.txt";
return AbsolutePath(str.str());
}
#else
AbsolutePath configFile(){
ostringstream str;
/* what if HOME isn't set? */
str << getenv("HOME") << "/.paintownrc";
return AbsolutePath(str.str());
}
AbsolutePath userDirectory(){
ostringstream str;
/* what if HOME isn't set? */
str << getenv("HOME") << "/.paintown/";
return AbsolutePath(str.str());
}
#endif
static AbsolutePath lookup(const RelativePath path) throw (NotFound){
/* first try the main data directory */
AbsolutePath final = Util::getDataPath2().join(path);
if (System::readable(final.path())){
return final;
}
/* then try the user directory, like ~/.paintown */
final = userDirectory().join(path);
if (System::readable(final.path())){
return final;
}
/* then just look in the cwd */
if (System::readable(path.path())){
return AbsolutePath(path.path());
}
ostringstream out;
out << "Cannot find " << path.path() << ". I looked in '" << Util::getDataPath2().join(path).path() << "', '" << userDirectory().join(path).path() << "', and '" << path.path() << "'" << endl;
throw NotFound(__FILE__, __LINE__, out.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.path() + "/" + entry->d_name;
if (System::isDirectory(total)){
dirs.push_back(AbsolutePath(total));
}
entry = readdir(dir);
}
closedir(dir);
return dirs;
}
vector<AbsolutePath> findDirectories(const RelativePath & path){
typedef vector<AbsolutePath> Paths;
Paths dirs;
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;
}
-vector<string> getFiles(const AbsolutePath & dataPath, const string & find, bool caseInsensitive){
+vector<AbsolutePath> getFiles(const AbsolutePath & dataPath, const string & find, bool caseInsensitive){
#ifdef USE_ALLEGRO
struct al_ffblk info;
- vector< string > files;
+ vector<AbsolutePath> files;
if ( al_findfirst( (dataPath.path() + find).c_str(), &info, FA_ALL ) != 0 ){
return files;
}
- files.push_back( dataPath.path() + string( info.name ) );
+ files.push_back(AbsolutePath(dataPath.path() + string(info.name)));
while ( al_findnext( &info ) == 0 ){
- files.push_back( dataPath.path() + string( info.name ) );
+ files.push_back(AbsolutePath(dataPath.path() + string(info.name)));
}
al_findclose( &info );
return files;
#else
- vector<string> files;
+ vector<AbsolutePath> files;
DIRST sflEntry;
bool ok = open_dir(&sflEntry, dataPath.path().c_str());
while (ok){
if (file_matches(sflEntry.file_name, find.c_str())){
- files.push_back(dataPath.path() + string(sflEntry.file_name));
+ files.push_back(AbsolutePath(dataPath.path() + string(sflEntry.file_name)));
}
ok = read_dir(&sflEntry);
}
close_dir(&sflEntry);
// Global::debug(0) << "Warning: Filesystem::getFiles() is not implemented yet for SDL" << endl;
return files;
#endif
}
/* 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){
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);
}
*/
AbsolutePath find(const RelativePath & path){
if (path.isEmpty()){
throw NotFound(__FILE__, __LINE__, "No path given");
}
AbsolutePath out = lookup(path);
if (System::isDirectory(out.path())){
return AbsolutePath(sanitize(out.path() + "/"));
}
return AbsolutePath(sanitize(out.path()));
}
bool exists(const RelativePath & path){
try{
AbsolutePath absolute = find(path);
return true;
} catch (const NotFound & found){
return false;
}
}
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){
if (! path.empty() && path[0] == '/'){
ostringstream out;
out << "Relative path '" << path << "' cannot start with a /. Only absolute paths can start with /";
throw IllegalPath(__FILE__, __LINE__, out.str());
}
}
RelativePath::RelativePath(const RelativePath & path):
Path(path){
}
RelativePath RelativePath::getDirectory() const {
return RelativePath(dirname(path()));
}
RelativePath RelativePath::getFilename() const {
return RelativePath(stripDir(path()));
}
+bool RelativePath::operator<(const RelativePath & path) const {
+ return this->path() < path.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();
}
+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 9dee495f..c131130d 100644
--- a/util/file-system.h
+++ b/util/file-system.h
@@ -1,142 +1,145 @@
#ifndef _paintown_file_system_h
#define _paintown_file_system_h
#include "exceptions/exception.h"
#include <string>
#include <vector>
namespace Filesystem{
/* sorry for the crappy abbreviation, but can't collide with the
* Exception class here
*/
namespace Exc = ::Exception;
class Exception: public Exc::Base {
public:
Exception(const std::string & where, int line, const std::string & file);
Exception(const std::string & where, int line, const Exc::Base & nested, const std::string & file);
Exception(const Exception & copy);
virtual ~Exception() throw ();
protected:
virtual const std::string getReason() const;
virtual Exc::Base * copy() const {
return new Exception(*this);
}
private:
std::string reason;
};
class NotFound: public Exception {
public:
NotFound(const std::string & where, int line, const std::string & file);
NotFound(const std::string & where, int line, const Exc::Base & nested, const std::string & file);
virtual ~NotFound() throw();
NotFound(const NotFound & copy);
protected:
virtual Exc::Base * copy() const {
return new NotFound(*this);
}
};
class IllegalPath: public Exception {
public:
IllegalPath(const std::string & where, int line, const std::string & file);
IllegalPath(const std::string & where, int line, const Exc::Base & nested, const std::string & file);
virtual ~IllegalPath() throw();
IllegalPath(const IllegalPath & copy);
protected:
virtual Exc::Base * copy() const {
return new IllegalPath(*this);
}
};
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: public Path {
public:
explicit RelativePath();
explicit RelativePath(const std::string & path);
RelativePath(const RelativePath & path);
+
+ bool operator<(const RelativePath & path) const;
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: 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;
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
*/
AbsolutePath find(const RelativePath & path);
/* whether the file exists at all */
bool exists(const RelativePath & path);
/* remove the data path from a string
* data/sounds/arrow.png -> sounds/arrow.png
*/
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<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 */
AbsolutePath userDirectory();
/* user specific path to store the configuration file */
AbsolutePath configFile();
- std::vector<std::string> getFiles(const AbsolutePath & dataPath, const std::string & find, bool caseInsensitive = false);
+ std::vector<AbsolutePath> getFiles(const AbsolutePath & dataPath, const std::string & find, bool caseInsensitive = false);
}
#endif
diff --git a/util/funcs.cpp b/util/funcs.cpp
index 0844d4ce..5db3fc8c 100644
--- a/util/funcs.cpp
+++ b/util/funcs.cpp
@@ -1,251 +1,253 @@
#ifdef USE_ALLEGRO
#include <allegro.h>
#endif
#ifdef USE_SDL
#include <SDL.h>
#endif
#include "funcs.h"
#include "globals.h"
#include <vector>
#include <string>
#include <string.h>
#include "file-system.h"
#include "bitmap.h"
#ifndef USE_ALLEGRO
/* FIXME: move this to the filesystem module */
#include "sfl/sfl.h"
#include "sfl/sflfile.h"
#endif
#ifndef WINDOWS
#include <unistd.h>
#endif
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#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;
}
/* sleep for `x' milliseconds */
void Util::rest( int x ){
#ifdef USE_ALLEGRO
::rest(x);
#endif
#ifdef USE_SDL
SDL_Delay(x);
#endif
}
void Util::restSeconds(double x){
Util::rest((int)(x * 1000));
}
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;
}
Filesystem::AbsolutePath Util::getDataPath2(){
return Filesystem::AbsolutePath(dataPath + "/");
}
bool Util::exists( const string & file ){
#ifdef USE_ALLEGRO
return ::exists(file.c_str()) != 0;
#else
return file_exists(file.c_str());
#endif
}
-vector< string > Util::getFiles(const Filesystem::AbsolutePath & dataPath, const string & find){
+/*
+vector<Filesystem::AbsolutePath> Util::getFiles(const Filesystem::AbsolutePath & dataPath, const string & find){
return Filesystem::getFiles(dataPath, find);
}
+*/
void Util::blend_palette(int * pal, int mp, int startColor, int endColor ) {
/*
ASSERT(pal);
ASSERT(mp != 0);
*/
int sc_r = Bitmap::getRed(startColor);
int sc_g = Bitmap::getGreen(startColor);
int sc_b = Bitmap::getBlue(startColor);
int ec_r = Bitmap::getRed(endColor);
int ec_g = Bitmap::getGreen(endColor);
int ec_b = Bitmap::getBlue(endColor);
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] = Bitmap::makeColor( 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;
}
string Util::lowerCaseAll(std::string str){
for (unsigned int i = 0; i < str.length(); i++){
if (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());
}
void Util::limitPrintf(char * buffer, int size, const char * format, va_list args){
#ifdef USE_ALLEGRO
uvszprintf(buffer, size, format, args);
#else
vsnprintf(buffer, size, format, args);
#endif
}
#ifndef WINDOWS
int Util::getPipe(int files[2]){
return pipe(files);
}
#endif
diff --git a/util/funcs.h b/util/funcs.h
index 280aa8ae..bad78fad 100644
--- a/util/funcs.h
+++ b/util/funcs.h
@@ -1,78 +1,78 @@
#ifndef _paintown_funcs_h
#define _paintown_funcs_h
#include <stdlib.h>
#include <vector>
#include <string>
#include <stdarg.h>
#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 Filesystem::AbsolutePath & dataPath, const std::string & find );
+// std::vector< std::string > getFiles(const Filesystem::AbsolutePath & dataPath, const std::string & find );
double radians(double degree);
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);
inline int min(int a, int b){
if (a<b){
return a;
}
return b;
}
/* return a number between min/max */
int rnd( int min, int max );
void blend_palette( int * pal, int mp, int sc, int ec );
/* rest in milliseconds */
void rest( int x );
/* rest in seconds */
void restSeconds(double x);
std::string trim(const std::string & str);
std::string upcase(std::string str);
std::string lowerCaseAll(std::string str);
int levenshtein(const std::string & str1, const std::string & str2);
int getPipe(int files[2]);
void limitPrintf(char * buffer, int size, const char * format, va_list args);
}
#endif
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Jun 11, 12:22 PM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
69013
Default Alt Text
(23 KB)
Attached To
Mode
R75 R-Tech1
Attached
Detach File
Event Timeline