REMOVED USER_STD macros, code formating, csv changes, few file functions
This commit is contained in:
parent
125c73ac33
commit
c1532e78b1
|
|
@ -2,3 +2,4 @@ build
|
||||||
/cmake-build-debug/
|
/cmake-build-debug/
|
||||||
.idea
|
.idea
|
||||||
ml
|
ml
|
||||||
|
.DS_Store
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ set(PROJECT_NAME ml)
|
||||||
|
|
||||||
set(SOURCE
|
set(SOURCE
|
||||||
ml.cpp
|
ml.cpp
|
||||||
|
ml_io.cpp
|
||||||
clib/csvparser.cpp
|
clib/csvparser.cpp
|
||||||
clib/sslclient.cpp
|
clib/sslclient.cpp
|
||||||
clib/json11.cpp)
|
clib/json11.cpp)
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
|
|
||||||
### TODO
|
### TODO
|
||||||
- support for strings with " included
|
- move system_cmd into ml_io
|
||||||
- logical operators
|
- logical operators
|
||||||
- documentation
|
- documentation
|
||||||
- add url of source/inspiration to clib/*.cpp
|
- add url of source/inspiration to clib/*.cpp
|
||||||
- load std lib when starting
|
- load std lib when starting
|
||||||
- add more command line args
|
- add more command line args
|
||||||
- split into more files
|
- add stdtest
|
||||||
- prejmenovat ivaluize
|
- rename ivaluize
|
||||||
- add benchmark
|
- add benchmark
|
||||||
- add some debug support??
|
- add some debug support??
|
||||||
- add instrumentation (time, nr of evals, debug info, debug environment etc)
|
- add instrumentation (time, nr of evals, debug info, debug environment etc)
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,13 @@ CsvParser::CsvParser(bool skip_hdr, char field_sep, char quote_ch, char line_sep
|
||||||
header_skiped = false;
|
header_skiped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvParser::parseCSV(const std::string &csvSource, std::vector< std::vector<std::string> > &lines) {
|
MlValue CsvParser::parseCSV(const std::string &csvSource) {
|
||||||
bool inQuote(false);
|
bool inQuote(false);
|
||||||
bool newLine(false);
|
bool newLine(false);
|
||||||
std::string field;
|
std::string field;
|
||||||
lines.clear();
|
|
||||||
|
// PERF optimize it for memory usage and performance
|
||||||
|
std::vector<std::vector<std::string>> parsed_data; // TODO some default size here
|
||||||
std::vector<std::string> line;
|
std::vector<std::string> line;
|
||||||
|
|
||||||
std::string::const_iterator aChar = csvSource.begin();
|
std::string::const_iterator aChar = csvSource.begin();
|
||||||
|
|
@ -38,7 +40,7 @@ void CsvParser::parseCSV(const std::string &csvSource, std::vector< std::vector<
|
||||||
} else {
|
} else {
|
||||||
if (newLine == false) {
|
if (newLine == false) {
|
||||||
line.push_back(field);
|
line.push_back(field);
|
||||||
addLine(line, lines);
|
addLine(line, parsed_data);
|
||||||
field.clear();
|
field.clear();
|
||||||
line.clear();
|
line.clear();
|
||||||
newLine = true;
|
newLine = true;
|
||||||
|
|
@ -55,37 +57,39 @@ void CsvParser::parseCSV(const std::string &csvSource, std::vector< std::vector<
|
||||||
if (field.size())
|
if (field.size())
|
||||||
line.push_back(field);
|
line.push_back(field);
|
||||||
|
|
||||||
addLine(line, lines);
|
addLine(line, parsed_data);
|
||||||
|
|
||||||
|
return ivalualize(parsed_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
MlValue CsvParser::ivalualize(std::vector< std::vector<std::string> > &parsed_data) const {
|
MlValue CsvParser::ivalualize(std::vector<std::vector<std::string> > &parsed_data) const {
|
||||||
int rows = parsed_data.size();
|
int rows = parsed_data.size();
|
||||||
int cols = rows > 0 ? parsed_data[0].size() : 0;
|
int cols = rows > 0 ? parsed_data[0].size() : 0;
|
||||||
|
|
||||||
std::vector<MlValue> result;
|
std::vector<MlValue> result;
|
||||||
|
|
||||||
if (rows > 0 && cols > 0) {
|
if (rows > 0 && cols > 0) {
|
||||||
for (int r = 0; r < rows; r++) {
|
for (int r = 0; r < rows; r++) {
|
||||||
std::vector<MlValue> row;
|
std::vector<MlValue> row;
|
||||||
for (int c = 0; c < cols; c++) {
|
for (int c = 0; c < cols; c++) {
|
||||||
std::string value = parsed_data[r][c];
|
std::string value = parsed_data[r][c];
|
||||||
if (is_string_int(value)) {
|
if (is_string_int(value)) {
|
||||||
row.push_back(MlValue(stoi(value)));
|
row.push_back(MlValue(stoi(value)));
|
||||||
}
|
}
|
||||||
if (is_string_float(value)) {
|
if (is_string_float(value)) {
|
||||||
row.push_back(MlValue(std::stod(value)));
|
row.push_back(MlValue(std::stod(value)));
|
||||||
} else {
|
} else {
|
||||||
row.push_back(MlValue::string(value));
|
row.push_back(MlValue::string(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.push_back(row);
|
result.push_back(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsvParser::addLine(const std::vector<std::string> &line, std::vector< std::vector<std::string> > &lines) {
|
void CsvParser::addLine(const std::vector<std::string> &line, std::vector<std::vector<std::string> > &lines) {
|
||||||
if (skip_header && !header_skiped) {
|
if (skip_header && !header_skiped) {
|
||||||
header_skiped = true;
|
header_skiped = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -101,10 +105,10 @@ std::regex double_regex("[0-9]+\\.[0-9]+");
|
||||||
|
|
||||||
// Is string representing int value
|
// Is string representing int value
|
||||||
bool CsvParser::is_string_int(const std::string &str) const {
|
bool CsvParser::is_string_int(const std::string &str) const {
|
||||||
return std::regex_match(str, int_regex);
|
return std::regex_match(str, int_regex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is string representing float value
|
// Is string representing float value
|
||||||
bool CsvParser::is_string_float(const std::string &str) const {
|
bool CsvParser::is_string_float(const std::string &str) const {
|
||||||
return std::regex_match(str, double_regex);
|
return std::regex_match(str, double_regex);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,23 +8,26 @@
|
||||||
class CsvParser {
|
class CsvParser {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char field_separator;
|
char field_separator;
|
||||||
char line_separator;
|
char line_separator;
|
||||||
char line_separator2;
|
char line_separator2;
|
||||||
char quote_character;
|
char quote_character;
|
||||||
|
|
||||||
bool skip_header;
|
bool skip_header;
|
||||||
bool header_skiped;
|
bool header_skiped;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CsvParser(bool skip_hdr = false, char field_sep = ',', char quote_ch = '"', char line_sep = '\r', char line_sep2 = '\n');
|
CsvParser(bool skip_hdr = false, char field_sep = ',', char quote_ch = '"', char line_sep = '\r',
|
||||||
|
char line_sep2 = '\n');
|
||||||
|
|
||||||
void parseCSV(const std::string &csvSource, std::vector< std::vector<std::string> > &lines);
|
MlValue parseCSV(const std::string &csvSource);
|
||||||
|
|
||||||
MlValue ivalualize(std::vector< std::vector<std::string> > &parsed_data) const;
|
|
||||||
private:
|
private:
|
||||||
void addLine(const std::vector<std::string> &line, std::vector< std::vector<std::string> > &lines);
|
void addLine(const std::vector<std::string> &line, std::vector<std::vector<std::string> > &lines);
|
||||||
|
|
||||||
|
MlValue ivalualize(std::vector<std::vector<std::string> > &parsed_data) const;
|
||||||
|
|
||||||
bool is_string_int(const std::string &str) const;
|
bool is_string_int(const std::string &str) const;
|
||||||
|
|
||||||
bool is_string_float(const std::string &str) const;
|
bool is_string_float(const std::string &str) const;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
1221
clib/json11.cpp
1221
clib/json11.cpp
File diff suppressed because it is too large
Load Diff
293
clib/json11.h
293
clib/json11.h
|
|
@ -11,165 +11,200 @@
|
||||||
namespace json11 {
|
namespace json11 {
|
||||||
|
|
||||||
enum JsonParse {
|
enum JsonParse {
|
||||||
STANDARD, COMMENTS
|
STANDARD, COMMENTS
|
||||||
};
|
};
|
||||||
|
|
||||||
class JsonValue;
|
class JsonValue;
|
||||||
|
|
||||||
class Json final {
|
class Json final {
|
||||||
public:
|
public:
|
||||||
// Types
|
// Types
|
||||||
enum Type {
|
enum Type {
|
||||||
NUL, NUMBER, BOOL, STRING, ARRAY, OBJECT
|
NUL, NUMBER, BOOL, STRING, ARRAY, OBJECT
|
||||||
};
|
};
|
||||||
|
|
||||||
// Array and object typedefs
|
// Array and object typedefs
|
||||||
typedef std::vector<Json> array;
|
typedef std::vector<Json> array;
|
||||||
typedef std::map<std::string, Json> object;
|
typedef std::map<std::string, Json> object;
|
||||||
|
|
||||||
// Constructors for the various types of JSON value.
|
// Constructors for the various types of JSON value.
|
||||||
Json() noexcept; // NUL
|
Json() noexcept; // NUL
|
||||||
Json(std::nullptr_t) noexcept; // NUL
|
Json(std::nullptr_t) noexcept; // NUL
|
||||||
Json(double value); // NUMBER
|
Json(double value); // NUMBER
|
||||||
Json(int value); // NUMBER
|
Json(int value); // NUMBER
|
||||||
Json(bool value); // BOOL
|
Json(bool value); // BOOL
|
||||||
Json(const std::string &value); // STRING
|
Json(const std::string &value); // STRING
|
||||||
Json(std::string &&value); // STRING
|
Json(std::string &&value); // STRING
|
||||||
Json(const char * value); // STRING
|
Json(const char *value); // STRING
|
||||||
Json(const array &values); // ARRAY
|
Json(const array &values); // ARRAY
|
||||||
Json(array &&values); // ARRAY
|
Json(array &&values); // ARRAY
|
||||||
Json(const object &values); // OBJECT
|
Json(const object &values); // OBJECT
|
||||||
Json(object &&values); // OBJECT
|
Json(object &&values); // OBJECT
|
||||||
|
|
||||||
// Implicit constructor: anything with a to_json() function.
|
// Implicit constructor: anything with a to_json() function.
|
||||||
template <class T, class = decltype(&T::to_json)>
|
template<class T, class = decltype(&T::to_json)>
|
||||||
Json(const T & t) : Json(t.to_json()) {}
|
Json(const T &t) : Json(t.to_json()) {}
|
||||||
|
|
||||||
// Implicit constructor: map-like objects (std::map, std::unordered_map, etc)
|
// Implicit constructor: map-like objects (std::map, std::unordered_map, etc)
|
||||||
template <class M, typename std::enable_if<
|
template<class M, typename std::enable_if<
|
||||||
std::is_constructible<std::string, decltype(std::declval<M>().begin()->first)>::value
|
std::is_constructible<std::string, decltype(std::declval<M>().begin()->first)>::value
|
||||||
&& std::is_constructible<Json, decltype(std::declval<M>().begin()->second)>::value,
|
&& std::is_constructible<Json, decltype(std::declval<M>().begin()->second)>::value,
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
Json(const M & m) : Json(object(m.begin(), m.end())) {}
|
Json(const M &m) : Json(object(m.begin(), m.end())) {}
|
||||||
|
|
||||||
// Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc)
|
// Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc)
|
||||||
template <class V, typename std::enable_if<
|
template<class V, typename std::enable_if<
|
||||||
std::is_constructible<Json, decltype(*std::declval<V>().begin())>::value,
|
std::is_constructible<Json, decltype(*std::declval<V>().begin())>::value,
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
Json(const V & v) : Json(array(v.begin(), v.end())) {}
|
Json(const V &v) : Json(array(v.begin(), v.end())) {}
|
||||||
|
|
||||||
// This prevents Json(some_pointer) from accidentally producing a bool. Use
|
// This prevents Json(some_pointer) from accidentally producing a bool. Use
|
||||||
// Json(bool(some_pointer)) if that behavior is desired.
|
// Json(bool(some_pointer)) if that behavior is desired.
|
||||||
Json(void *) = delete;
|
Json(void *) = delete;
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
Type type() const;
|
Type type() const;
|
||||||
|
|
||||||
bool is_null() const { return type() == NUL; }
|
bool is_null() const { return type() == NUL; }
|
||||||
bool is_number() const { return type() == NUMBER; }
|
|
||||||
bool is_bool() const { return type() == BOOL; }
|
|
||||||
bool is_string() const { return type() == STRING; }
|
|
||||||
bool is_array() const { return type() == ARRAY; }
|
|
||||||
bool is_object() const { return type() == OBJECT; }
|
|
||||||
|
|
||||||
// Return the enclosed value if this is a number, 0 otherwise. Note that json11 does not
|
bool is_number() const { return type() == NUMBER; }
|
||||||
// distinguish between integer and non-integer numbers - number_value() and int_value()
|
|
||||||
// can both be applied to a NUMBER-typed object.
|
|
||||||
double number_value() const;
|
|
||||||
int int_value() const;
|
|
||||||
|
|
||||||
// Return the enclosed value if this is a boolean, false otherwise.
|
bool is_bool() const { return type() == BOOL; }
|
||||||
bool bool_value() const;
|
|
||||||
// Return the enclosed string if this is a string, "" otherwise.
|
|
||||||
const std::string &string_value() const;
|
|
||||||
// Return the enclosed std::vector if this is an array, or an empty vector otherwise.
|
|
||||||
const array &array_items() const;
|
|
||||||
// Return the enclosed std::map if this is an object, or an empty map otherwise.
|
|
||||||
const object &object_items() const;
|
|
||||||
|
|
||||||
// Return a reference to arr[i] if this is an array, Json() otherwise.
|
bool is_string() const { return type() == STRING; }
|
||||||
const Json & operator[](size_t i) const;
|
|
||||||
// Return a reference to obj[key] if this is an object, Json() otherwise.
|
|
||||||
const Json & operator[](const std::string &key) const;
|
|
||||||
|
|
||||||
// Serialize.
|
bool is_array() const { return type() == ARRAY; }
|
||||||
void dump(std::string &out) const;
|
|
||||||
std::string dump() const {
|
|
||||||
std::string out;
|
|
||||||
dump(out);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
MlValue ivalualize() const;
|
bool is_object() const { return type() == OBJECT; }
|
||||||
|
|
||||||
// Parse. If parse fails, return Json() and assign an error message to err.
|
// Return the enclosed value if this is a number, 0 otherwise. Note that json11 does not
|
||||||
static Json parse(const std::string & in,
|
// distinguish between integer and non-integer numbers - number_value() and int_value()
|
||||||
std::string & err,
|
// can both be applied to a NUMBER-typed object.
|
||||||
JsonParse strategy = JsonParse::STANDARD);
|
double number_value() const;
|
||||||
static Json parse(const char * in,
|
|
||||||
std::string & err,
|
|
||||||
JsonParse strategy = JsonParse::STANDARD) {
|
|
||||||
if (in) {
|
|
||||||
return parse(std::string(in), err, strategy);
|
|
||||||
} else {
|
|
||||||
err = "null input";
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Parse multiple objects, concatenated or separated by whitespace
|
|
||||||
static std::vector<Json> parse_multi(
|
|
||||||
const std::string & in,
|
|
||||||
std::string::size_type & parser_stop_pos,
|
|
||||||
std::string & err,
|
|
||||||
JsonParse strategy = JsonParse::STANDARD);
|
|
||||||
|
|
||||||
static inline std::vector<Json> parse_multi(
|
int int_value() const;
|
||||||
const std::string & in,
|
|
||||||
std::string & err,
|
|
||||||
JsonParse strategy = JsonParse::STANDARD) {
|
|
||||||
std::string::size_type parser_stop_pos;
|
|
||||||
return parse_multi(in, parser_stop_pos, err, strategy);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator== (const Json &rhs) const;
|
// Return the enclosed value if this is a boolean, false otherwise.
|
||||||
bool operator< (const Json &rhs) const;
|
bool bool_value() const;
|
||||||
bool operator!= (const Json &rhs) const { return !(*this == rhs); }
|
|
||||||
bool operator<= (const Json &rhs) const { return !(rhs < *this); }
|
|
||||||
bool operator> (const Json &rhs) const { return (rhs < *this); }
|
|
||||||
bool operator>= (const Json &rhs) const { return !(*this < rhs); }
|
|
||||||
|
|
||||||
/* has_shape(types, err)
|
// Return the enclosed string if this is a string, "" otherwise.
|
||||||
*
|
const std::string &string_value() const;
|
||||||
* Return true if this is a JSON object and, for each item in types, has a field of
|
|
||||||
* the given type. If not, return false and set err to a descriptive message.
|
// Return the enclosed std::vector if this is an array, or an empty vector otherwise.
|
||||||
*/
|
const array &array_items() const;
|
||||||
typedef std::initializer_list<std::pair<std::string, Type>> shape;
|
|
||||||
bool has_shape(const shape & types, std::string & err) const;
|
// Return the enclosed std::map if this is an object, or an empty map otherwise.
|
||||||
|
const object &object_items() const;
|
||||||
|
|
||||||
|
// Return a reference to arr[i] if this is an array, Json() otherwise.
|
||||||
|
const Json &operator[](size_t i) const;
|
||||||
|
|
||||||
|
// Return a reference to obj[key] if this is an object, Json() otherwise.
|
||||||
|
const Json &operator[](const std::string &key) const;
|
||||||
|
|
||||||
|
// Serialize.
|
||||||
|
void dump(std::string &out) const;
|
||||||
|
|
||||||
|
std::string dump() const {
|
||||||
|
std::string out;
|
||||||
|
dump(out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
MlValue ivalualize() const;
|
||||||
|
|
||||||
|
// Parse. If parse fails, return Json() and assign an error message to err.
|
||||||
|
static Json parse(const std::string &in,
|
||||||
|
std::string &err,
|
||||||
|
JsonParse strategy = JsonParse::STANDARD);
|
||||||
|
|
||||||
|
static Json parse(const char *in,
|
||||||
|
std::string &err,
|
||||||
|
JsonParse strategy = JsonParse::STANDARD) {
|
||||||
|
if (in) {
|
||||||
|
return parse(std::string(in), err, strategy);
|
||||||
|
} else {
|
||||||
|
err = "null input";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse multiple objects, concatenated or separated by whitespace
|
||||||
|
static std::vector<Json> parse_multi(
|
||||||
|
const std::string &in,
|
||||||
|
std::string::size_type &parser_stop_pos,
|
||||||
|
std::string &err,
|
||||||
|
JsonParse strategy = JsonParse::STANDARD);
|
||||||
|
|
||||||
|
static inline std::vector<Json> parse_multi(
|
||||||
|
const std::string &in,
|
||||||
|
std::string &err,
|
||||||
|
JsonParse strategy = JsonParse::STANDARD) {
|
||||||
|
std::string::size_type parser_stop_pos;
|
||||||
|
return parse_multi(in, parser_stop_pos, err, strategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const Json &rhs) const;
|
||||||
|
|
||||||
|
bool operator<(const Json &rhs) const;
|
||||||
|
|
||||||
|
bool operator!=(const Json &rhs) const { return !(*this == rhs); }
|
||||||
|
|
||||||
|
bool operator<=(const Json &rhs) const { return !(rhs < *this); }
|
||||||
|
|
||||||
|
bool operator>(const Json &rhs) const { return (rhs < *this); }
|
||||||
|
|
||||||
|
bool operator>=(const Json &rhs) const { return !(*this < rhs); }
|
||||||
|
|
||||||
|
/* has_shape(types, err)
|
||||||
|
*
|
||||||
|
* Return true if this is a JSON object and, for each item in types, has a field of
|
||||||
|
* the given type. If not, return false and set err to a descriptive message.
|
||||||
|
*/
|
||||||
|
typedef std::initializer_list<std::pair<std::string, Type>> shape;
|
||||||
|
|
||||||
|
bool has_shape(const shape &types, std::string &err) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<JsonValue> m_ptr;
|
std::shared_ptr<JsonValue> m_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Internal class hierarchy - JsonValue objects are not exposed to users of this API.
|
// Internal class hierarchy - JsonValue objects are not exposed to users of this API.
|
||||||
class JsonValue {
|
class JsonValue {
|
||||||
protected:
|
protected:
|
||||||
friend class Json;
|
friend class Json;
|
||||||
friend class JsonInt;
|
|
||||||
friend class JsonDouble;
|
friend class JsonInt;
|
||||||
virtual Json::Type type() const = 0;
|
|
||||||
virtual bool equals(const JsonValue * other) const = 0;
|
friend class JsonDouble;
|
||||||
virtual bool less(const JsonValue * other) const = 0;
|
|
||||||
virtual void dump(std::string &out) const = 0;
|
virtual Json::Type type() const = 0;
|
||||||
virtual MlValue ivalualize() const = 0;
|
|
||||||
virtual double number_value() const;
|
virtual bool equals(const JsonValue *other) const = 0;
|
||||||
virtual int int_value() const;
|
|
||||||
virtual bool bool_value() const;
|
virtual bool less(const JsonValue *other) const = 0;
|
||||||
virtual const std::string &string_value() const;
|
|
||||||
virtual const Json::array &array_items() const;
|
virtual void dump(std::string &out) const = 0;
|
||||||
virtual const Json &operator[](size_t i) const;
|
|
||||||
virtual const Json::object &object_items() const;
|
virtual MlValue ivalualize() const = 0;
|
||||||
virtual const Json &operator[](const std::string &key) const;
|
|
||||||
virtual ~JsonValue() {}
|
virtual double number_value() const;
|
||||||
|
|
||||||
|
virtual int int_value() const;
|
||||||
|
|
||||||
|
virtual bool bool_value() const;
|
||||||
|
|
||||||
|
virtual const std::string &string_value() const;
|
||||||
|
|
||||||
|
virtual const Json::array &array_items() const;
|
||||||
|
|
||||||
|
virtual const Json &operator[](size_t i) const;
|
||||||
|
|
||||||
|
virtual const Json::object &object_items() const;
|
||||||
|
|
||||||
|
virtual const Json &operator[](const std::string &key) const;
|
||||||
|
|
||||||
|
virtual ~JsonValue() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace json11
|
} // namespace json11
|
||||||
|
|
|
||||||
|
|
@ -17,59 +17,60 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
HttpClient::HttpClient(){};
|
HttpClient::HttpClient() {};
|
||||||
|
|
||||||
std::pair<int, std::string> HttpClient::doGetRequest(const std::string &url, const std::unordered_map<std::string, std::string> &headers) {
|
std::pair<int, std::string>
|
||||||
|
HttpClient::doGetRequest(const std::string &url, const std::unordered_map<std::string, std::string> &headers) {
|
||||||
// https://stackoverflow.com/questions/25896916/parse-http-headers-in-c
|
// https://stackoverflow.com/questions/25896916/parse-http-headers-in-c
|
||||||
|
|
||||||
std::regex rgx{R"(^(?:((?:https?|s?ftp):)//)([^:/\s]+)(?::(\d*))?(?:/([^\s?#]+)?([?][^?#]*)?(#.*)?)?)"};
|
std::regex rgx{R"(^(?:((?:https?|s?ftp):)//)([^:/\s]+)(?::(\d*))?(?:/([^\s?#]+)?([?][^?#]*)?(#.*)?)?)"};
|
||||||
std::smatch matches;
|
std::smatch matches;
|
||||||
|
|
||||||
if (std::regex_search(url, matches, rgx)) {
|
if (std::regex_search(url, matches, rgx)) {
|
||||||
for (size_t i = 0; i < matches.size(); ++i) {
|
for (size_t i = 0; i < matches.size(); ++i) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
full_url = matches[i].str();
|
full_url = matches[i].str();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
proto = matches[i].str();
|
proto = matches[i].str();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
server = matches[i].str();
|
server = matches[i].str();
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
port = matches[i].str();
|
port = matches[i].str();
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
uri = matches[i].str();
|
uri = matches[i].str();
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
params = matches[i].str();
|
params = matches[i].str();
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
href = matches[i].str();
|
href = matches[i].str();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// std::cout << i << ": '" << matches[i].str() << "'\n";
|
// std::cout << i << ": '" << matches[i].str() << "'\n";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Match not found" << std::endl; // TODO better message
|
std::cerr << "Match not found" << std::endl; // TODO better message
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string headers_string = "";
|
std::string headers_string = "";
|
||||||
for (auto it = headers.begin(); it != headers.end(); ++it) {
|
for (auto it = headers.begin(); it != headers.end(); ++it) {
|
||||||
headers_string.append("\r\n" + it->first + ": " + it->second);
|
headers_string.append("\r\n" + it->first + ": " + it->second);
|
||||||
// std::cerr << "KEY: `" << it->first << "`, VALUE: `" << it->second << '`' << std::endl;
|
// std::cerr << "KEY: `" << it->first << "`, VALUE: `" << it->second << '`' << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string request = "GET " + full_url + " HTTP/1.0\r\nHost: " + server + headers_string + "\r\n\r\n";
|
std::string request = "GET " + full_url + " HTTP/1.0\r\nHost: " + server + headers_string + "\r\n\r\n";
|
||||||
|
|
||||||
// TODO memory leaks ???
|
// TODO memory leaks ???
|
||||||
int bytes_read = sslRequest(server, request);
|
int bytes_read = sslRequest(server, request);
|
||||||
if (bytes_read <= 0) {
|
if (bytes_read <= 0) {
|
||||||
std::cerr << "no data read" << std::endl;
|
std::cerr << "no data read" << std::endl;
|
||||||
return std::make_pair(403, "");
|
return std::make_pair(403, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string::size_type position = ssl_read_packet.find("\r\n\r\n");
|
std::string::size_type position = ssl_read_packet.find("\r\n\r\n");
|
||||||
|
|
@ -88,8 +89,8 @@ std::pair<int, std::string> HttpClient::doGetRequest(const std::string &url, con
|
||||||
std::smatch status_matches;
|
std::smatch status_matches;
|
||||||
if (std::regex_search(status_str, status_matches, status_rgx)) {
|
if (std::regex_search(status_str, status_matches, status_rgx)) {
|
||||||
if (status_matches.size() > 1) {
|
if (status_matches.size() > 1) {
|
||||||
auto sta = status_matches[1].str(); // string "200"
|
auto sta = status_matches[1].str(); // string "200"
|
||||||
// std::cout << "status: " << sta << std::endl;
|
// std::cout << "status: " << sta << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,7 +117,7 @@ std::string HttpClient::inetAddress(std::string hostname) {
|
||||||
std::cerr << hostname << " is unavailable" << std::endl;
|
std::cerr << hostname << " is unavailable" << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
in_addr *address = (in_addr *)record->h_addr;
|
in_addr *address = (in_addr *) record->h_addr;
|
||||||
std::string ip_address = inet_ntoa(*address);
|
std::string ip_address = inet_ntoa(*address);
|
||||||
|
|
||||||
return ip_address;
|
return ip_address;
|
||||||
|
|
@ -131,8 +132,8 @@ int HttpClient::sslRecvPacket() {
|
||||||
do {
|
do {
|
||||||
len = SSL_read(ssl, buf, len);
|
len = SSL_read(ssl, buf, len);
|
||||||
if (len >= 0) {
|
if (len >= 0) {
|
||||||
buf[len] = 0;
|
buf[len] = 0;
|
||||||
ssl_read_packet.append((const char *)buf);
|
ssl_read_packet.append((const char *) buf);
|
||||||
}
|
}
|
||||||
} while (len > 0);
|
} while (len > 0);
|
||||||
|
|
||||||
|
|
@ -154,15 +155,15 @@ int HttpClient::sslSendPacket(std::string buf) {
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
int err = SSL_get_error(ssl, len);
|
int err = SSL_get_error(ssl, len);
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
return 0;
|
return 0;
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
return 0;
|
return 0;
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
case SSL_ERROR_SSL:
|
case SSL_ERROR_SSL:
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,7 +189,7 @@ int HttpClient::sslRequest(const std::string &server_name, const std::string &re
|
||||||
socklen_t socklen = sizeof(sa);
|
socklen_t socklen = sizeof(sa);
|
||||||
|
|
||||||
// connect to server
|
// connect to server
|
||||||
if (connect(s, (struct sockaddr *)&sa, socklen)) {
|
if (connect(s, (struct sockaddr *) &sa, socklen)) {
|
||||||
printf("MlError connecting to server.\n");
|
printf("MlError connecting to server.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -206,8 +207,8 @@ int HttpClient::sslRequest(const std::string &server_name, const std::string &re
|
||||||
}
|
}
|
||||||
sock = SSL_get_fd(ssl);
|
sock = SSL_get_fd(ssl);
|
||||||
SSL_set_fd(ssl, s);
|
SSL_set_fd(ssl, s);
|
||||||
|
|
||||||
SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, (void*)server.c_str());
|
SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, (void *) server.c_str());
|
||||||
|
|
||||||
int err = SSL_connect(ssl);
|
int err = SSL_connect(ssl);
|
||||||
if (err <= 0) {
|
if (err <= 0) {
|
||||||
|
|
@ -221,7 +222,7 @@ int HttpClient::sslRequest(const std::string &server_name, const std::string &re
|
||||||
// printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
|
// printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
|
||||||
|
|
||||||
// send request
|
// send request
|
||||||
//std::err << request << std::endl;
|
//std::err << request << std::endl;
|
||||||
sslSendPacket(request);
|
sslSendPacket(request);
|
||||||
|
|
||||||
// read response and return its length
|
// read response and return its length
|
||||||
|
|
|
||||||
|
|
@ -7,26 +7,30 @@
|
||||||
|
|
||||||
|
|
||||||
class HttpClient {
|
class HttpClient {
|
||||||
// TODO at this moment only https is implemented
|
// TODO at this moment only https is implemented
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
std::string full_url, proto, server, port, uri, params, href;
|
std::string full_url, proto, server, port, uri, params, href;
|
||||||
std::basic_string<char> ssl_read_packet;
|
std::basic_string<char> ssl_read_packet;
|
||||||
std::unordered_map<std::string, std::string> headers_map;
|
std::unordered_map<std::string, std::string> headers_map;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HttpClient();
|
HttpClient();
|
||||||
|
|
||||||
std::pair<int, std::string> doGetRequest(const std::string &url, const std::unordered_map<std::string, std::string> &headers);
|
std::pair<int, std::string>
|
||||||
|
doGetRequest(const std::string &url, const std::unordered_map<std::string, std::string> &headers);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string inetAddress(std::string hostname);
|
std::string inetAddress(std::string hostname);
|
||||||
|
|
||||||
int sslRecvPacket();
|
int sslRecvPacket();
|
||||||
int sslSendPacket(std::string buf);
|
|
||||||
int sslRequest(const std::string &server_name, const std::string &request);
|
int sslSendPacket(std::string buf);
|
||||||
void log_ssl();
|
|
||||||
|
int sslRequest(const std::string &server_name, const std::string &request);
|
||||||
|
|
||||||
|
void log_ssl();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,15 @@
|
||||||
(define pdate (second (first (filter (lambda (x) (= (first x) "payment_Date")) e))))
|
(define pdate (second (first (filter (lambda (x) (= (first x) "payment_Date")) e))))
|
||||||
(define rdate (second (first (filter (lambda (x) (= (first x) "record_Date")) e))))
|
(define rdate (second (first (filter (lambda (x) (= (first x) "record_Date")) e))))
|
||||||
|
|
||||||
(print symbol edate pdate divrate)
|
;(print symbol edate pdate divrate)
|
||||||
|
'(symbol edate pdate divrate)
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
(print (ls-dir "/tmp"))
|
||||||
|
(print (is-file? "/tmp/file"))
|
||||||
|
(print (is-file? "/tmp/hovinko"))
|
||||||
|
(print (is-dir? "/tmp/powerlog"))
|
||||||
|
|
||||||
(print "Debug ends")
|
(print "Debug ends")
|
||||||
|
|
|
||||||
204
ml.h
204
ml.h
|
|
@ -1,11 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Comment this define out to drop support for standard library functions.
|
|
||||||
// This allows the program to run without a runtime.
|
|
||||||
#define USE_STD
|
|
||||||
|
|
||||||
// Comment this define out to drop support for libm functions
|
|
||||||
#define HAS_LIBM
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -14,7 +8,7 @@
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
|
|
||||||
// // Forward declaration for MlEnvironment class definition
|
// Forward declaration for MlEnvironment class definition
|
||||||
class MlValue;
|
class MlValue;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -29,19 +23,22 @@ public:
|
||||||
// This is only used to determine which atoms to capture when
|
// This is only used to determine which atoms to capture when
|
||||||
// creating a lambda function.
|
// creating a lambda function.
|
||||||
bool has(std::string name) const;
|
bool has(std::string name) const;
|
||||||
|
|
||||||
// Get the value associated with this name in this scope
|
// Get the value associated with this name in this scope
|
||||||
MlValue get(const std::string& name) const;
|
MlValue get(const std::string &name) const;
|
||||||
|
|
||||||
// Set the value associated with this name in this scope
|
// Set the value associated with this name in this scope
|
||||||
void set(std::string name, MlValue value);
|
void set(std::string name, MlValue value);
|
||||||
|
|
||||||
void combine(MlEnvironment const &other);
|
void combine(MlEnvironment const &other);
|
||||||
|
|
||||||
void set_parent_scope(MlEnvironment *parent) {
|
void set_parent_scope(MlEnvironment *parent) {
|
||||||
parent_scope = parent;
|
parent_scope = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output this scope in readable form to a stream.
|
// Output this scope in readable form to a stream.
|
||||||
friend std::ostream &operator<<(std::ostream &os, MlEnvironment const &v);
|
friend std::ostream &operator<<(std::ostream &os, MlEnvironment const &v);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// The definitions in the scope.
|
// The definitions in the scope.
|
||||||
|
|
@ -50,20 +47,21 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// An exception thrown by the lisp
|
// An exception thrown by the lisp
|
||||||
class MlError {
|
class MlError {
|
||||||
public:
|
public:
|
||||||
// Create an error with the value that caused the error,
|
// Create an error with the value that caused the error,
|
||||||
// the scope where the error was found, and the message.
|
// the scope where the error was found, and the message.
|
||||||
MlError(const MlValue &v, MlEnvironment const &env, const char *msg);
|
MlError(const MlValue &v, MlEnvironment const &env, const char *msg);
|
||||||
|
|
||||||
// Copy constructor is needed to prevent double frees
|
// Copy constructor is needed to prevent double frees
|
||||||
MlError(MlError const &other);
|
MlError(MlError const &other);
|
||||||
|
|
||||||
~MlError();
|
~MlError();
|
||||||
|
|
||||||
// Get the printable error description.
|
// Get the printable error description.
|
||||||
std::string description();
|
std::string description();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MlValue *cause;
|
MlValue *cause;
|
||||||
MlEnvironment env;
|
MlEnvironment env;
|
||||||
|
|
@ -71,142 +69,144 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// The type for a builtin function, which takes a list of values,
|
// The type for a builtin function, which takes a list of values,
|
||||||
// and the environment to run the function in.
|
// and the environment to run the function in.
|
||||||
typedef MlValue (*Builtin)(std::vector<MlValue>, MlEnvironment &);
|
typedef MlValue (*Builtin)(std::vector<MlValue>, MlEnvironment &);
|
||||||
|
|
||||||
|
|
||||||
class MlValue {
|
class MlValue {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructs a unit value
|
// Constructs a unit value
|
||||||
MlValue();
|
MlValue();
|
||||||
|
|
||||||
// Constructs an integer
|
// Constructs an integer
|
||||||
MlValue(int i);
|
MlValue(int i);
|
||||||
// Constructs a floating point value
|
|
||||||
MlValue(double f);
|
|
||||||
// Constructs a list
|
|
||||||
MlValue(const std::vector<MlValue> &list);
|
|
||||||
|
|
||||||
// Construct a quoted value
|
// Constructs a floating point value
|
||||||
static MlValue quote(const MlValue& quoted);
|
MlValue(double f);
|
||||||
|
|
||||||
// Construct an atom
|
// Constructs a list
|
||||||
static MlValue atom(const std::string &s);
|
MlValue(const std::vector<MlValue> &list);
|
||||||
|
|
||||||
// Construct a string
|
// Construct a quoted value
|
||||||
static MlValue string(const std::string &s);
|
static MlValue quote(const MlValue "ed);
|
||||||
|
|
||||||
// Construct a lambda function
|
// Construct an atom
|
||||||
MlValue(const std::vector<MlValue> ¶ms, MlValue ret, MlEnvironment const &env);
|
static MlValue atom(const std::string &s);
|
||||||
|
|
||||||
// Construct a builtin function
|
// Construct a string
|
||||||
MlValue(const std::string &name, Builtin b);
|
static MlValue string(const std::string &s);
|
||||||
|
|
||||||
std::vector<std::string> get_used_atoms();
|
// Construct a lambda function
|
||||||
|
MlValue(const std::vector<MlValue> ¶ms, MlValue ret, MlEnvironment const &env);
|
||||||
|
|
||||||
// Is this a builtin function?
|
// Construct a builtin function
|
||||||
bool is_builtin();
|
MlValue(const std::string &name, Builtin b);
|
||||||
|
|
||||||
// Apply this as a function to a list of arguments in a given environment.
|
std::vector<std::string> get_used_atoms();
|
||||||
MlValue apply(std::vector<MlValue> args, MlEnvironment &env);
|
|
||||||
// Evaluate this value as lisp code.
|
|
||||||
MlValue eval(MlEnvironment &env);
|
|
||||||
|
|
||||||
bool is_number() const;
|
// Is this a builtin function?
|
||||||
|
bool is_builtin();
|
||||||
|
|
||||||
// Get the "truthy" boolean value of this value.
|
// Apply this as a function to a list of arguments in a given environment.
|
||||||
bool as_bool() const;
|
MlValue apply(std::vector<MlValue> args, MlEnvironment &env);
|
||||||
|
|
||||||
// Get this item's integer value
|
// Evaluate this value as lisp code.
|
||||||
int as_int() const;
|
MlValue eval(MlEnvironment &env);
|
||||||
|
|
||||||
// Get this item's floating point value
|
bool is_number() const;
|
||||||
double as_float() const;
|
|
||||||
|
|
||||||
// Get this item's string value
|
// Get the "truthy" boolean value of this value.
|
||||||
std::string as_string() const;
|
bool as_bool() const;
|
||||||
|
|
||||||
// Get this item's atom value
|
// Get this item's integer value
|
||||||
std::string as_atom() const;
|
int as_int() const;
|
||||||
|
|
||||||
// Get this item's list value
|
// Get this item's floating point value
|
||||||
std::vector<MlValue> as_list() const;
|
double as_float() const;
|
||||||
|
|
||||||
// Push an item to the end of this list
|
// Get this item's string value
|
||||||
void push(MlValue val);
|
std::string as_string() const;
|
||||||
|
|
||||||
// Push an item from the end of this list
|
// Get this item's atom value
|
||||||
MlValue pop();
|
std::string as_atom() const;
|
||||||
|
|
||||||
|
// Get this item's list value
|
||||||
|
std::vector<MlValue> as_list() const;
|
||||||
|
|
||||||
|
// Push an item to the end of this list
|
||||||
|
void push(MlValue val);
|
||||||
|
|
||||||
|
// Push an item from the end of this list
|
||||||
|
MlValue pop();
|
||||||
|
|
||||||
|
|
||||||
// Cast this to an integer value
|
// Cast this to an integer value
|
||||||
MlValue cast_to_int() const;
|
MlValue cast_to_int() const;
|
||||||
|
|
||||||
// Cast this to a floating point value
|
// Cast this to a floating point value
|
||||||
MlValue cast_to_float() const;
|
MlValue cast_to_float() const;
|
||||||
|
|
||||||
|
|
||||||
bool operator==(MlValue other) const;
|
bool operator==(MlValue other) const;
|
||||||
|
|
||||||
bool operator!=(const MlValue &other) const;
|
bool operator!=(const MlValue &other) const;
|
||||||
|
|
||||||
|
|
||||||
bool operator>=(const MlValue &other) const;
|
bool operator>=(const MlValue &other) const;
|
||||||
|
|
||||||
bool operator<=(const MlValue &other) const;
|
bool operator<=(const MlValue &other) const;
|
||||||
|
|
||||||
bool operator>(const MlValue &other) const;
|
bool operator>(const MlValue &other) const;
|
||||||
|
|
||||||
bool operator<(const MlValue &other) const;
|
bool operator<(const MlValue &other) const;
|
||||||
|
|
||||||
|
|
||||||
// This function adds two lisp values, and returns the lisp value result.
|
// This function adds two lisp values, and returns the lisp value result.
|
||||||
MlValue operator+(const MlValue &other) const;
|
MlValue operator+(const MlValue &other) const;
|
||||||
|
|
||||||
// This function subtracts two lisp values, and returns the lisp value result.
|
// This function subtracts two lisp values, and returns the lisp value result.
|
||||||
MlValue operator-(const MlValue &other) const;
|
MlValue operator-(const MlValue &other) const;
|
||||||
|
|
||||||
// This function multiplies two lisp values, and returns the lisp value result.
|
// This function multiplies two lisp values, and returns the lisp value result.
|
||||||
MlValue operator*(const MlValue &other) const;
|
MlValue operator*(const MlValue &other) const;
|
||||||
|
|
||||||
// This function divides two lisp values, and returns the lisp value result.
|
// This function divides two lisp values, and returns the lisp value result.
|
||||||
MlValue operator/(const MlValue &other) const;
|
MlValue operator/(const MlValue &other) const;
|
||||||
|
|
||||||
// This function finds the remainder of two lisp values, and returns the lisp value result.
|
// This function finds the remainder of two lisp values, and returns the lisp value result.
|
||||||
MlValue operator%(const MlValue &other) const;
|
MlValue operator%(const MlValue &other) const;
|
||||||
|
|
||||||
// Get the name of the type of this value
|
// Get the name of the type of this value
|
||||||
std::string get_type_name();
|
std::string get_type_name();
|
||||||
|
|
||||||
std::string display() const;
|
std::string display() const;
|
||||||
|
|
||||||
std::string debug() const;
|
std::string debug() const;
|
||||||
|
|
||||||
friend std::ostream &operator<<(std::ostream &os, MlValue const &v);
|
friend std::ostream &operator<<(std::ostream &os, MlValue const &v);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
QUOTE,
|
QUOTE,
|
||||||
ATOM,
|
ATOM,
|
||||||
INT,
|
INT,
|
||||||
FLOAT,
|
FLOAT,
|
||||||
LIST,
|
LIST,
|
||||||
STRING,
|
STRING,
|
||||||
LAMBDA,
|
LAMBDA,
|
||||||
BUILTIN,
|
BUILTIN,
|
||||||
UNIT
|
UNIT
|
||||||
} type;
|
} type;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
int i;
|
int i;
|
||||||
double f;
|
double f;
|
||||||
Builtin b;
|
Builtin b;
|
||||||
} stack_data;
|
} stack_data;
|
||||||
|
|
||||||
std::string str;
|
std::string str;
|
||||||
std::vector<MlValue> list;
|
std::vector<MlValue> list;
|
||||||
MlEnvironment lambda_scope;
|
MlEnvironment lambda_scope;
|
||||||
};
|
};
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
|
||||||
|
#include "ml_io.h"
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
||||||
|
std::string read_file_contents(const std::string &filename) {
|
||||||
|
std::ifstream f;
|
||||||
|
f.open(filename.c_str());
|
||||||
|
if (!f)
|
||||||
|
throw std::runtime_error("could not open file");
|
||||||
|
|
||||||
|
f.seekg(0, std::ios::end);
|
||||||
|
std::string contents;
|
||||||
|
contents.reserve(f.tellg());
|
||||||
|
f.seekg(0, std::ios::beg);
|
||||||
|
contents.assign(std::istreambuf_iterator<char>(f),
|
||||||
|
std::istreambuf_iterator<char>());
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
MlValue list_dir(const std::string &path) {
|
||||||
|
std::vector<MlValue> entries;
|
||||||
|
|
||||||
|
DIR *dirp = opendir(path.c_str());
|
||||||
|
if (dirp == NULL) {
|
||||||
|
// handle error - probably not a dir or non existing path
|
||||||
|
}
|
||||||
|
struct dirent *dp;
|
||||||
|
while ((dp = readdir(dirp)) != NULL) {
|
||||||
|
entries.push_back(MlValue::string(dp->d_name));
|
||||||
|
}
|
||||||
|
closedir(dirp);
|
||||||
|
|
||||||
|
return MlValue(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_path_file(const std::string &path) {
|
||||||
|
std::ifstream ifile(path.c_str());
|
||||||
|
return (bool) ifile;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_path_dir(const std::string &path) {
|
||||||
|
struct stat buf;
|
||||||
|
stat(path.c_str(), &buf);
|
||||||
|
return (bool) S_ISDIR(buf.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mk_dir(const std::string &path) {
|
||||||
|
int r = ::mkdir(path.c_str(), 0755);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rm_dir(const std::string &path) {
|
||||||
|
int r = ::rmdir(path.c_str());
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../ml.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
std::string read_file_contents(const std::string &filename);
|
||||||
|
|
||||||
|
MlValue list_dir(const std::string &path);
|
||||||
|
|
||||||
|
bool is_path_file(const std::string &path);
|
||||||
|
|
||||||
|
bool is_path_dir(const std::string &path);
|
||||||
|
|
||||||
|
int mk_dir(const std::string &path);
|
||||||
|
|
||||||
|
int rm_dir(const std::string &path);
|
||||||
|
|
||||||
Loading…
Reference in New Issue