diff options
Diffstat (limited to 'graphics/asymptote/parser.cc')
-rw-r--r-- | graphics/asymptote/parser.cc | 121 |
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 |