summaryrefslogtreecommitdiff
path: root/graphics/asymptote/parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/asymptote/parser.cc')
-rw-r--r--graphics/asymptote/parser.cc121
1 files changed, 82 insertions, 39 deletions
diff --git a/graphics/asymptote/parser.cc b/graphics/asymptote/parser.cc
index 60123250ed..c6b8f76414 100644
--- a/graphics/asymptote/parser.cc
+++ b/graphics/asymptote/parser.cc
@@ -8,6 +8,7 @@
#include <sstream>
#include <cstring>
#include <fcntl.h>
+#include <algorithm>
#include "common.h"
@@ -15,6 +16,10 @@
#include <sys/stat.h>
#endif
+#ifdef HAVE_LIBCURL
+#include <curl/curl.h>
+#endif
+
#include "interact.h"
#include "locate.h"
#include "errormsg.h"
@@ -30,12 +35,8 @@ extern bool lexerEOF();
extern void reportEOF();
extern bool hangup;
-static int fd;
-
namespace parser {
-static FILE *fin=NULL;
-
namespace yy { // Lexers
std::streambuf *sbuf = NULL;
@@ -45,22 +46,6 @@ size_t stream_input(char *buf, size_t max_size)
return sbuf ? sbuf->sgetn(buf,max_size) : 0;
}
-int fpeek(int fd)
-{
- int flags=fcntl(fd,F_GETFL,0);
- fcntl(fd,F_SETFL,flags | O_NONBLOCK);
- char c=fgetc(fin);
- ungetc(c,fin);
- fcntl(fd,F_SETFL,flags & ~O_NONBLOCK);
- return c;
-}
-
-size_t pipe_input(char *buf, size_t max_size)
-{
- if(hangup && fpeek(fd) == EOF) {hangup=false; return 0;}
- return strlen(fgets(buf,max_size-1,fin));
-}
-
} // namespace yy
void debug(bool state)
@@ -110,27 +95,28 @@ absyntax::file *doParse(size_t (*input) (char* bif, size_t max_size),
absyntax::file *parseStdin()
{
debug(false);
+ yy::sbuf = cin.rdbuf();
+ return doParse(yy::stream_input,"-");
+}
- if(!fin) {
- fd=intcast(settings::getSetting<Int>("inpipe"));
- if(fd >= 0)
- fin=fdopen(fd,"r");
- }
-
- if(fin)
- return doParse(yy::pipe_input,"-");
- else {
- yy::sbuf = cin.rdbuf();
- return doParse(yy::stream_input,"-");
- }
+bool isURL(const string& filename)
+{
+#ifdef HAVE_LIBCURL
+ return filename.find("://") != string::npos;
+#else
+ return false;
+#endif
}
absyntax::file *parseFile(const string& filename,
const char *nameOfAction)
{
+ if(isURL(filename))
+ return parseURL(filename,nameOfAction);
+
if(filename == "-")
return parseStdin();
-
+
string file = settings::locateFile(filename);
if(file.empty())
@@ -138,13 +124,13 @@ absyntax::file *parseFile(const string& filename,
if(nameOfAction && settings::verbose > 1)
cerr << nameOfAction << " " << filename << " from " << file << endl;
-
- debug(false);
+
+ debug(false);
std::filebuf filebuf;
if(!filebuf.open(file.c_str(),std::ios::in))
error(filename);
-
+
#ifdef HAVE_SYS_STAT_H
// Check that the file is not a directory.
static struct stat buf;
@@ -153,14 +139,14 @@ absyntax::file *parseFile(const string& filename,
error(filename);
}
#endif
-
+
// Check that the file can actually be read.
try {
filebuf.sgetc();
} catch (...) {
error(filename);
}
-
+
yy::sbuf = &filebuf;
return doParse(yy::stream_input,file);
}
@@ -175,5 +161,62 @@ absyntax::file *parseString(const string& code,
return doParse(yy::stream_input,filename,extendable);
}
-} // namespace parser
+#ifdef HAVE_LIBCURL
+size_t curlCallback(char *data, size_t size, size_t n, stringstream& buf)
+{
+ size_t Size=size*n;
+ buf.write(data,Size);
+ return Size;
+}
+
+int curlProgress(void *, curl_off_t, curl_off_t, curl_off_t, curl_off_t)
+{
+ return errorstream::interrupt ? -1 : 0;
+}
+
+bool readURL(stringstream& buf, const string& filename)
+{
+ CURL *curl=curl_easy_init();
+ if(settings::verbose > 3)
+ curl_easy_setopt(curl,CURLOPT_VERBOSE,true);
+#ifdef __MSDOS__
+ string cert=settings::getSetting<string>("sysdir")+settings::dirsep+
+ "ca-bundle.crt";
+ curl_easy_setopt(curl,CURLOPT_CAINFO,cert.c_str());
+#endif
+ curl_easy_setopt(curl,CURLOPT_URL,filename.c_str());
+ curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,curlCallback);
+ curl_easy_setopt(curl,CURLOPT_WRITEDATA,&buf);
+ curl_easy_setopt(curl,CURLOPT_NOPROGRESS,0);
+ curl_easy_setopt(curl,CURLOPT_XFERINFOFUNCTION,curlProgress);
+
+ CURLcode res=curl_easy_perform(curl);
+ curl_easy_cleanup(curl);
+
+ if(res != CURLE_OK) {
+ cerr << curl_easy_strerror(res) << endl;
+ return false;
+ }
+ string s=buf.str();
+ return !s.empty() && s != "404: Not Found";
+}
+
+absyntax::file *parseURL(const string& filename,
+ const char *nameOfAction)
+{
+ stringstream code;
+
+ if(!readURL(code,filename))
+ error(filename);
+ if(nameOfAction && settings::verbose > 1)
+ cerr << nameOfAction << " " << filename << endl;
+
+ debug(false);
+
+ yy::sbuf=code.rdbuf();
+ return doParse(yy::stream_input,filename);
+}
+#endif
+
+} // namespace parser