#include <iostream>
#include <string>
#include <cerrno>
typedef std::string rectangle_t;
static const char ldgrs[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0,
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
};
std::string string_digits(std::string str) {
std::string ret;
for (const char *c = str.c_str(); *c; c++)
if (ldgrs[(unsigned char)*c]&4) ret += *c;
return ret;
}
std::size_t string_count(std::string substr, std::string str) {
std::size_t pos = 0, occ = 0;
const std::size_t sublen = substr.length();
while ((pos = str.find(substr, pos)) != std::string::npos)
occ++, pos += sublen;
return occ;
}
void print_help(std::string argv0) {
std::cout << "usage: " << argv0 << " <flag> <WxH+X+Y> " << std::endl;
std::cout << "xposition: " << argv0 << " --xpos (or -x) 640x480+0+0" << std::endl;
std::cout << "yposition: " << argv0 << " --ypos (or -y) 640x480+0+0" << std::endl;
std::cout << "width: " << argv0 << " --width (or -w) 640x480+0+0" << std::endl;
std::cout << "height: " << argv0 << " --height (or -h) 640x480+0+0" << std::endl;
exit(0);
}
void print_error() {
std::cout << "error parsing or invalid rectangle!" << std::endl;
exit(1);
}
void print_int(int value) {
std::cout << value << std::endl;
exit(0);
}
void print_uint(unsigned value) {
std::cout << value << std::endl;
exit(0);
}
void rectangle_getter(rectangle_t rect, int *ret_x, int *ret_y,
unsigned *ret_w, unsigned *ret_h, bool *ret_e) {
bool error = false;
std::size_t wpos = 0;
std::size_t hpos = rect.find("x") + 1;
if (hpos == wpos) error = true;
if (string_count("+", rect) != 2) error = true;
std::size_t xpos = rect.find_first_of("+") + 1;
if (xpos == wpos) error = true;
std::size_t ypos = rect.find_last_of("+") + 1;
if (ypos == wpos) error = true;
std::string w = rect.substr(wpos, hpos - wpos - 1);
if (string_digits(w).empty()) error = true;
std::string h = rect.substr(hpos, xpos - hpos - 1);
if (string_digits(h).empty()) error = true;
std::string x = rect.substr(xpos, ypos - xpos - 1);
if (string_digits(x).empty()) error = true;
std::string y = rect.substr(ypos);
if (string_digits(y).empty()) error = true;
*ret_x = !error ? (int)strtol(x.c_str(), nullptr, 10) : 0;
if (errno == ERANGE) error = true;
*ret_y = !error ? (int)strtol(y.c_str(), nullptr, 10) : 0;
if (errno == ERANGE) error = true;
*ret_w = !error ? (unsigned)strtoul(w.c_str(), nullptr, 10) : 0;
if (errno == ERANGE) error = true;
*ret_h = !error ? (unsigned)strtoul(h.c_str(), nullptr, 10) : 0;
if (errno == ERANGE) error = true;
*ret_e = error;
}
rectangle_t rectangle_setter(int x, int y, unsigned w, unsigned h) {
return std::to_string(w) + "x" + std::to_string(h) + "+" +
std::to_string(x) + "+" + std::to_string(y);
}
unsigned rectangle_get_width(rectangle_t rect) {
bool ret_e;
int ret_x, ret_y;
unsigned ret_w, ret_h;
rectangle_getter(rect, &ret_x, &ret_y, &ret_w, &ret_h, &ret_e);
if (ret_e) { print_error(); }
return ret_w;
}
unsigned rectangle_get_height(rectangle_t rect) {
bool ret_e;
int ret_x, ret_y;
unsigned ret_w, ret_h;
rectangle_getter(rect, &ret_x, &ret_y, &ret_w, &ret_h, &ret_e);
if (ret_e) { print_error(); }
return ret_h;
}
int rectangle_get_x(rectangle_t rect) {
bool ret_e;
int ret_x, ret_y;
unsigned ret_w, ret_h;
rectangle_getter(rect, &ret_x, &ret_y, &ret_w, &ret_h, &ret_e);
if (ret_e) { print_error(); }
return ret_x;
}
int rectangle_get_y(rectangle_t rect) {
bool ret_e;
int ret_x, ret_y;
unsigned ret_w, ret_h;
rectangle_getter(rect, &ret_x, &ret_y, &ret_w, &ret_h, &ret_e);
if (ret_e) { print_error(); }
return ret_y;
}
int main (int argc, char **argv) {
if (argc == 1) { print_help(argv[0]); }
if (argc > 3) { print_error(); }
std::string flag = argv[1];
rectangle_t rect = argv[1];
if (argc == 3) { rect = argv[2]; }
if (argc == 2 && (flag == "--help" || flag == "-h"))
{ print_help(argv[0]); }
int x = rectangle_get_x(rect);
int y = rectangle_get_y(rect);
unsigned w = rectangle_get_width(rect);
unsigned h = rectangle_get_height(rect);
if (flag == "--xpos" || flag == "-x") { print_int(x); }
if (flag == "--ypos" || flag == "-y") { print_int(y); }
if (flag == "--width" || flag == "-w") { print_uint(w); }
if (flag == "--height" || flag == "-h") { print_uint(h); }
rectangle_t r = rectangle_setter(x, y, w, h);
std::cout << "unparsed: " << r << std::endl;
std::cout << "parsed x: " << x << std::endl;
std::cout << "parsed y: " << y << std::endl;
std::cout << "parsed w: " << w << std::endl;
std::cout << "parsed h: " << h << std::endl;
return 0;
}