summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/util.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/util.cc')
-rw-r--r--Build/source/utils/asymptote/util.cc130
1 files changed, 100 insertions, 30 deletions
diff --git a/Build/source/utils/asymptote/util.cc b/Build/source/utils/asymptote/util.cc
index 2d66fb2316f..81398491c00 100644
--- a/Build/source/utils/asymptote/util.cc
+++ b/Build/source/utils/asymptote/util.cc
@@ -23,14 +23,17 @@
#include <unistd.h>
#include <cstring>
#include <algorithm>
+#include <dirent.h>
#include "util.h"
#include "settings.h"
#include "errormsg.h"
#include "camperror.h"
#include "interact.h"
+#include "locate.h"
using namespace settings;
+using camp::reportError;
bool False=false;
@@ -61,7 +64,7 @@ string demangle(const char* s)
{
return s;
}
-#endif
+#endif
char *Strdup(string s)
{
@@ -90,10 +93,10 @@ char *StrdupMalloc(string s)
string stripDir(string name)
{
size_t p;
-#ifdef __MSDOS__
+#ifdef __MSDOS__
p=name.rfind('\\');
if(p < string::npos) name.erase(0,p+1);
-#endif
+#endif
p=name.rfind('/');
if(p < string::npos) name.erase(0,p+1);
return name;
@@ -103,24 +106,24 @@ string stripFile(string name)
{
size_t p;
bool dir=false;
-#ifdef __MSDOS__
+#ifdef __MSDOS__
p=name.rfind('\\');
if(p < string::npos) {
dir=true;
while(p > 0 && name[p-1] == '\\') --p;
name.erase(p+1);
}
-#endif
+#endif
p=name.rfind('/');
if(p < string::npos) {
dir=true;
while(p > 0 && name[p-1] == '/') --p;
name.erase(p+1);
}
-
+
return dir ? name : "";
}
-
+
string stripExt(string name, const string& ext)
{
string suffix="."+ext;
@@ -131,14 +134,14 @@ string stripExt(string name, const string& ext)
else return name;
}
-void backslashToSlash(string& s)
+void backslashToSlash(string& s)
{
size_t p;
while((p=s.find('\\')) < string::npos)
s[p]='/';
}
-void spaceToUnderscore(string& s)
+void spaceToUnderscore(string& s)
{
size_t p;
while((p=s.find(' ')) < string::npos)
@@ -154,12 +157,17 @@ string Getenv(const char *name, bool msdos)
return S;
}
+void readDisabled()
+{
+ camp::reportError("Read from other directories disabled; override with option -globalread");
+}
+
void writeDisabled()
{
camp::reportError("Write to other directories disabled; override with option -globalwrite");
}
-string cleanpath(string name)
+string cleanpath(string name)
{
string dir=stripFile(name);
name=stripDir(name);
@@ -167,7 +175,17 @@ string cleanpath(string name)
return dir+name;
}
-string outpath(string name)
+string inpath(string name)
+{
+ bool global=globalread();
+ string dir=stripFile(name);
+ if(global && !dir.empty()) return name;
+ string indir=stripFile(outname());
+ if(!(global || dir.empty() || dir == indir)) readDisabled();
+ return stripDir(name);
+}
+
+string outpath(string name)
{
bool global=globalwrite();
string dir=stripFile(name);
@@ -177,7 +195,7 @@ string outpath(string name)
return outdir+stripDir(name);
}
-string buildname(string name, string suffix, string aux)
+string buildname(string name, string suffix, string aux)
{
name=stripExt(outpath(name),defaultformat())+aux;
if(!suffix.empty()) name += "."+suffix;
@@ -195,11 +213,11 @@ sighandler_t Signal(int signum, sighandler_t handler)
action.sa_handler=handler;
sigemptyset(&action.sa_mask);
action.sa_flags=0;
- return sigaction(signum,&action,&oldaction) == 0 ? oldaction.sa_handler :
+ return sigaction(signum,&action,&oldaction) == 0 ? oldaction.sa_handler :
SIG_ERR;
}
-void push_split(mem::vector<string>& a, const string& S)
+void push_split(mem::vector<string>& a, const string& S)
{
const char *p=S.c_str();
string s;
@@ -219,18 +237,18 @@ void push_split(mem::vector<string>& a, const string& S)
char **args(const mem::vector<string>& s, bool quiet)
{
size_t count=s.size();
-
+
char **argv=NULL;
argv=new char*[count+1];
for(size_t i=0; i < count; ++i)
argv[i]=StrdupNoGC(s[i]);
-
+
if(!quiet && settings::verbose > 1) {
cerr << argv[0];
for(size_t i=1; i < count; ++i) cerr << " " << argv[i];
cerr << endl;
}
-
+
argv[count]=NULL;
return argv;
}
@@ -241,21 +259,21 @@ void execError(const char *command, const char *hint, const char *application)
if(*application == 0) application=hint;
if(hint) {
string s=string(hint);
- transform(s.begin(), s.end(), s.begin(), toupper);
+ transform(s.begin(), s.end(), s.begin(), toupper);
cerr << "Please put in a file " << getSetting<string>("config")
<< ": " << endl << endl
<< "import settings;" << endl
<< hint << "=\"LOCATION\";" << endl << endl
- << "where LOCATION specifies the location of "
+ << "where LOCATION specifies the location of "
<< application << "." << endl << endl
- << "Alternatively, set the environment variable ASYMPTOTE_" << s
- << endl << "or use the command line option -" << hint
+ << "Alternatively, set the environment variable ASYMPTOTE_" << s
+ << endl << "or use the command line option -" << hint
<< "=\"LOCATION\". For further details, see" << endl
- << "http://asymptote.sourceforge.net/doc/Configuring.html" << endl
- << "http://asymptote.sourceforge.net/doc/Search-paths.html" << endl;
+ << "https://asymptote.sourceforge.io/doc/Configuring.html" << endl
+ << "https://asymptote.sourceforge.io/doc/Search-paths.html" << endl;
}
}
-
+
// quiet: 0=none; 1=suppress stdout; 2=suppress stdout+stderr.
int System(const mem::vector<string> &command, int quiet, bool wait,
const char *hint, const char *application, int *ppid)
@@ -263,13 +281,13 @@ int System(const mem::vector<string> &command, int quiet, bool wait,
int status;
cout.flush(); // Flush stdout to avoid duplicate output.
-
+
char **argv=args(command);
int pid=fork();
if(pid == -1)
camp::reportError("Cannot fork process");
-
+
if(pid == 0) {
if(interact::interactive) signal(SIGINT,SIG_IGN);
if(quiet) {
@@ -329,7 +347,7 @@ string stripblanklines(const string& s)
bool blank=true;
const char *t=S.c_str();
size_t len=S.length();
-
+
for(size_t i=0; i < len; i++) {
if(t[i] == '\n') {
if(blank) S[i]=' ';
@@ -380,7 +398,59 @@ const char *setPath(const char *s, bool quiet)
return p;
}
-void push_command(mem::vector<string>& a, const string& s)
+void fatal(const char *msg, const char *s=NULL)
+{
+ ostringstream buf;
+ buf << msg;
+ if(s) {
+ buf << " " << getPath();
+ if(*s) buf << "/";
+ buf << s;
+ }
+ buf << ": " << strerror(errno) << endl;
+ camp::reportError(buf);
+}
+
+void empty_current_dir()
+{
+ static struct stat buf;
+ DIR *dir=opendir(".");
+ if(dir == NULL) fatal("Cannot open directory","");
+ dirent *p;
+ while((p=readdir(dir)) != NULL) {
+ if(strcmp(p->d_name,".") == 0 || strcmp(p->d_name,"..") == 0) continue;
+ if(lstat(p->d_name,&buf) == 0) {
+ if(S_ISDIR(buf.st_mode)) {
+ if(chdir(p->d_name)) fatal("Cannot change directory to",p->d_name);
+ empty_current_dir();
+ if(chdir(".."))
+ fatal("Cannot change to parent directory of",p->d_name);
+ if(rmdir(p->d_name))
+ fatal("Cannot remove directory",p->d_name);
+ } else {
+ if(unlink(p->d_name)) fatal("Cannot remove file",p->d_name);
+ }
+ }
+ }
+ if(closedir(dir)) fatal("Invalid current directory stream descriptor");
+}
+
+void recursive_delete(char *name)
+{
+ static struct stat buf;
+ if(lstat(name,&buf) == 0) {
+ if(S_ISDIR(buf.st_mode)) {
+ const char *path=getPath();
+ if(chdir(name)) fatal("Cannot change directory to",name);
+ empty_current_dir();
+ if(chdir(path)) fatal("Cannot change to directory","");
+ if(rmdir(name)) fatal("Cannot remove directory", name);
+ }
+ else unlink(name);
+ }
+}
+
+void push_command(mem::vector<string>& a, const string& s)
{
a.push_back(s);
#ifdef __MSDOS__
@@ -389,7 +459,7 @@ void push_command(mem::vector<string>& a, const string& s)
a.push_back("start");
a.push_back("\"\"");
}
-#endif
+#endif
}
void popupHelp() {
@@ -404,7 +474,7 @@ void popupHelp() {
if (pid==0 || (waitpid(pid, &status, WNOHANG) == pid)) {
mem::vector<string> cmd;
push_command(cmd,getSetting<string>("pdfviewer"));
- string viewerOptions=getSetting<string>("pdfviewerOptions");
+ string viewerOptions=getSetting<string>("pdfviewerOptions");
if(!viewerOptions.empty())
cmd.push_back(viewerOptions);
cmd.push_back(docdir+dirsep+"asymptote.pdf");