#include "bloputils.h"
#include "blop_bookkeeper.h"
#include "exc.H"
#include "graph_drawer.h"
#include "pstream.h"
#include "warning.h"
#include "canvas.h"
#include <fstream>
#include <sstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <cstdlib>
#include <map>
#include <cmath>
#include <unistd.h>
namespace blop
{
using namespace std;
bool isfinite(double v) { return std::isfinite(v); }
bool isnan(double v) { return std::isnan(v); }
bool isinf(double v) { return std::isinf(v); }
bool isnormal(double v) { return std::isnormal(v); }
length axislength(axis *a, double from, double to)
{
return length::base_axis_t(a,from,to);
}
length x1len(double a,double b)
{
return length::base_axis_t(frame::current().x1axis(),a,b);
}
length x2len(double a,double b)
{
return length::base_axis_t(frame::current().x2axis(),a,b);
}
length y1len(double a,double b)
{
return length::base_axis_t(frame::current().y1axis(),a,b);
}
length y2len(double a,double b)
{
return length::base_axis_t(frame::current().y2axis(),a,b);
}
std::istream *openin(const var &filename)
{
if(filename.length() == 0)
{
warning::print("empty string","openin(const var &filename)");
return 0;
}
istream *file = 0;
if(filename[0] == '<' && filename[1] == '<')
{
file = new istringstream(filename.c_str()+2);
}
else if(filename[filename.length()-1]=='|')
{
file = new ipstream(filename.str().substr(0,filename.length()-1).c_str());
}
else if(filename.find("scp:
{
file = new iscpstream(filename.str().substr(6,string::npos).c_str());
}
else if(filename.find("http:
{
file = new ihttpstream(filename.str().c_str());
}
else
{
file = new ifstream(filename.str().c_str());
}
if(file->fail())
{
warning::print("Can't open file: " & filename);
delete file;
return 0;
}
return file;
}
std::ostream *openout(const var &filename)
{
if(filename.length() == 0)
{
warning::print("empty string","openout(const var &filename)");
return 0;
}
ostream *file = 0;
if(filename[0] == '>' && filename[1] == '>')
{
file = new ofstream(filename.str().substr(2).c_str(),ios::app);
}
else if(filename[0] == '>')
{
file = new ofstream(filename.str().substr(1).c_str());
}
else if(filename[0] == '|')
{
file = new opstream(filename.str().substr(1).c_str());
}
else if(filename.find("scp:
{
file = new oscpstream(filename.str().substr(6,string::npos).c_str());
}
else
{
file = new ofstream(filename.str().c_str());
}
if(file->fail())
{
warning::print("Can't open file: " & filename);
delete file;
return 0;
}
return file;
}
void print(terminal *t)
TRY
{
canvas::current().print(t);
}
CATCH("print(terminal *)")
int system(const var &cmd)
{
return ::system(cmd.str().c_str());
}
int system_bg(const var &cmd)
{
int pid = fork();
if(pid == 0)
{
const char *shell = "/bin/bash";
struct stat buf;
if(stat(shell,&buf) != 0) shell = "/bin/sh";
execl(shell, "sh", "-c", cmd.c_str(), NULL);
}
else
{
blop_bookkeeper::register_pid(pid);
}
return pid;
}
void shell(const var &cmd)
{
static opstream shellstr("/bin/sh");
shellstr<<cmd.str()<<endl;
}
var readcmd(const var &cmd_orig,int *rc)
{
string resultstr;
var cmd = cmd_orig;
if(cmd[0] == '<')
{
cmd = cmd.str().substr(1);
}
ipstream cmdstr(cmd);
int lineno = 0;
char c;
while(cmdstr.get(c))
{
resultstr += c;
if(c == '\n') ++lineno;
}
if(lineno == 1 && resultstr[resultstr.size()-1] == '\n')
{
resultstr.erase(resultstr.size()-1);
}
if(rc) *rc = cmdstr.close();
return resultstr;
}
int readcmd(const var &cmd, array &out, const var &separator, int *rc)
{
var f = readcmd(cmd, rc);
out = split(f,separator);
return out.size();
}
int readcmd(const var &cmd, std::vector<std::string> &out, const var &separator, int *rc)
{
var f = readcmd(cmd, rc);
split(f, separator, out);
return out.size();
}
var readfile(const var &filename)
{
var result;
char c;
ifstream file(filename.str().c_str());
while(file.get(c)) result &= c;
return result;
}
text &fdraw_file_content(const var &filename)
{
return text::fdraw(tolatex(readfile(filename))).verbatim(true);
}
text &pdraw_file_content(const var &filename)
{
return text::pdraw(tolatex(readfile(filename))).verbatim(true);
}
text &cdraw_file_content(const var &filename)
{
return text::cdraw(tolatex(readfile(filename))).verbatim(true);
}
int readfile(const var &filename, array &out, const var &separator)
{
var f = readfile(filename);
out = split(f,separator);
return out.size();
}
var join(const array &a, const var &sep)
{
if(a.empty()) return "";
var result = a[0];
for(unsigned int i=1; i<a.size(); ++i)
{
result &= sep;
result &= a[i];
}
return result;
}
var join(const std::vector<double> &a, const var &sep)
{
if(a.empty()) return "";
var result = a[0];
for(unsigned int i=1; i<a.size(); ++i)
{
result &= sep;
result &= a[i];
}
return result;
}
var join(const std::vector<std::string> &a, const var &sep)
{
if(a.empty()) return "";
var result = a[0];
for(unsigned int i=1; i<a.size(); ++i)
{
result &= sep;
result &= a[i];
}
return result;
}
array sequence(var start, var stop, var step)
{
array out;
for(double v = start.dbl(); v<=stop.dbl(); v+=step.dbl())
{
out.push_back(var(v));
}
return out;
}
string read_word_from_string(const string &line,std::string::size_type &index,const string &delimiter)
{
string result;
for(; index < line.size() && delimiter.find(line[index]) == string::npos; ++index)
{
result += line[index];
}
return result;
}
void split_quoted(string line, vector<var> &fields)
{
line += ' ';
fields.clear();
string s;
for(string::size_type i=0; i<line.size(); ++i)
{
for(; i<line.size() && ( line[i] == ' ' || line[i] == '\t') ; ++i);
if(i >= line.size()) break;
if(line[i] == '\'')
{
s = read_word_from_string(line,++i,"'");
fields.push_back(s);
}
else if(line[i] == '"')
{
s = read_word_from_string(line,++i,"\"");
fields.push_back(s);
}
else
{
s = read_word_from_string(line,i," \t");
if(s != "") fields.push_back(s);
}
}
}
array split(const var &ss,const var &sep)
{
array out;
string separator = sep.str();
string s = ss.str();
string w;
for(unsigned int i=0; i<s.size(); ++i)
{
if(separator.find(s[i]) != string::npos)
{
if(w != "") out.push_back(w);
w = "";
}
else
{
w += s[i];
}
}
if(w != "") out.push_back(w);
return out;
}
int split(const string &s,const string &separator, std::vector<std::string> &out)
{
out.clear();
string w;
for(unsigned int i=0; i<s.size(); ++i)
{
if(separator.find(s[i]) != string::npos)
{
if(w != "") out.push_back(w);
w = "";
}
else
{
w += s[i];
}
}
if(w != "") out.push_back(w);
return out.size();
}
istream &getline(istream &in, var &line, const var &line_separator)
{
string s;
std::getline(in,s,line_separator[0]);
line = s;
return in;
}
istream &getline(istream &in, array &line, const var &line_separator, const var &field_separator)
{
line.clear();
string s;
std::getline(in,s,line_separator[0]);
line = split(s,field_separator);
return in;
}
istream &getline(istream &in, std::vector<std::string> &line, const std::string &line_separator, const std::string &field_separator)
{
line.clear();
string s;
std::getline(in,s,line_separator[0]);
split(s,field_separator,line);
return in;
}
var getfield(const var &s, unsigned int i, const var &separator)
{
vector<var> out = split(s,separator);
if(i >= out.size()) return "";
if(i < 0) return "";
return out[i];
}
var tolatex(const var &input)
{
string fn = input.str();
string result;
for(unsigned int i=0; i<fn.size(); ++i)
{
switch(fn[i])
{
case '<': result += "$<$"; break;
case '>': result += "$>$"; break;
case '_': result += "\\_"; break;
case '^': result += "\\^"; break;
case '%': result += "\\%"; break;
case '@': result += "\\@"; break;
case '{': result += "$\\{$"; break;
case '}': result += "$\\}$"; break;
case '$': result += "\\$"; break;
case '&': result += "\\&"; break;
default: result += fn[i];
}
}
return result;
}
void parallel_sort(std::vector<double> &x, std::vector<double> &y)
{
parallel_sort<std::vector<double>,std::vector<double> >(x,y);
}
void parallel_sort(std::vector<blop::var> &x, std::vector<blop::var> &y)
{
parallel_sort<std::vector<blop::var>,std::vector<blop::var> >(x,y);
}
void parallel_sort(array &x, array &y)
{
parallel_sort<array,array>(x,y);
}
}