support both decimal and hexadecimal notations for --root-window v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Tue, 26 Dec 2023 12:40:20 +0100
branchv_0
changeset 26 e7ceb915177e
parent 25 717653cedc4a
child 27 2a156cb51479
support both decimal and hexadecimal notations for --root-window
CLIParser.h
--- a/CLIParser.h	Sat Dec 23 23:10:41 2023 +0100
+++ b/CLIParser.h	Tue Dec 26 12:40:20 2023 +0100
@@ -46,17 +46,19 @@
 
 	unsigned long
 	parseHexColor(const std::string& hex) {
-		int r, g, b;
-		int count = sscanf(hex.c_str(), "%02x%02x%02x", &r, &g, &b);
-		if (count == 3) {
-			unsigned long lr, lg, lb;
-			lr = r;
-			lg = g;
-			lb = b;
-			return (lr << 16 | lg << 8 | lb);
-		} else {
-			throw std::logic_error("Invalid hex color string");
-		}
+		size_t count;
+		unsigned long rgb = std::stoul(hex, &count, 16);
+		if (count == 6 || count == 8 && hex.starts_with("0x")) return rgb;
+		else throw std::logic_error("Invalid hex color string");
+		// the input should be (0x)?[0-9a-fA-F]{6}, however:
+		// values like 0x0123 are also accepted and interpreted as 000123
+		// values like +0x012 are also accepted and interpreted as 000012
+	}
+
+	unsigned long
+	parseUL(const std::string& str) {
+		int base = str.starts_with("0x") ? 16 : 10;
+		return std::stoul(str, nullptr, base);
 	}
 
 public:
@@ -78,7 +80,7 @@
 			} else if (option == OPTION_BACKGROUND_COLOR) {
 				c.backgroundColor = parseHexColor(readNext(arguments, i));
 			} else if (option == OPTION_ROOT_WINDOW) {
-				c.rootWindow = std::stoul(readNext(arguments, i));
+				c.rootWindow = parseUL(readNext(arguments, i));
 			} else throw std::logic_error("Unsupported CLI option: " + option);
 		}