/* * Copyright 2026 Axel Waggershauser */ // SPDX-License-Identifier: Apache-2.0 #include "BarcodeFormat.h" #include #ifdef __cpp_lib_format #include "StdPrint.h" #include #include #include #include #include static void PrintUsage(const char* exePath) { std::print("ZXingBarcodeFormat - A command line tool to generate wrapper source code for the BarcodeFormat enum\n\n"); std::println("Usage: {} ", exePath); } static void PrintBFs( std::format_string fmt, std::function name = [](const char* name) { return std::string(name); }) { std::println(fmt, name("Invalid"), 0xffff); #define X(NAME, SYM, VAR, FLAGS, ZINT, ENABLED, HRI) std::println(fmt, name(#NAME), ZX_BCF_ID(SYM, VAR)); ZX_BCF_LIST(X) #undef X } int main(int argc, char* argv[]) { auto is = [&, i=1](const char* str) { return strncmp(argv[i], str, strlen(argv[i])) == 0; }; if (argc != 2) { PrintUsage(argv[0]); return -1; } else if (is("Go")) { std::println("package zxingcpp\n"); std::println("const ("); PrintBFs(" BarcodeFormat{:14} BarcodeFormat = 0x{:04X}"); std::println(")"); } else if (is("C#")) { PrintBFs(" public static readonly BarcodeFormat {:15} = new BarcodeFormat(0x{:04X});"); } else if (is("K/N")) { PrintBFs(" {0:15}(ZXing_BarcodeFormat.ZXing_BarcodeFormat_{0}),"); } else if (is("Rust")) { PrintBFs("pub const ZXing_BarcodeFormat_{}: ZXing_BarcodeFormat = 0x{:04X};"); } else if (is("Swift")) { auto swiftName = [](const char* name) { std::string sv(name); std::string ret = (char)std::tolower(sv[0]) + sv.substr(1); // Convert to camelCase, but keep uppercase letters if they are followed by a lowercase letter // (e.g. QRCode -> qrCode). This is a bit hacky, but it works for the current set of names and avoids the // need for a manual mapping. This ensures that the generated Swift code follows typical naming patterns. for (int i = 2; i < ret.size() && (std::isupper(ret[i]) || std::isdigit(ret[i])); ++i) ret[i - 1] = std::tolower(ret[i - 1]); ret.back() = std::tolower(ret.back()); return ret == "eanupc" ? "eanUPC" : ret == "upca" ? "upcA" : ret == "upce" ? "upcE" : ret; }; PrintBFs(" public static let {:15} = BarcodeFormat(rawValue: 0x{:04X})", swiftName); } else if (is("Android")) { auto androidName = [](const char* name) { std::string sv(name); std::string ret = std::string(1, (char)std::toupper(sv[0])); for (size_t i = 1; i < sv.size(); ++i) { const int c = sv[i]; const int prev = sv[i - 1]; const int next = i + 1 < sv.size() ? sv[i + 1] : 0; if ((std::isdigit(c) != std::isdigit(prev)) || (std::isupper(c) && std::islower(prev)) || (std::isupper(c) && std::isupper(prev) && next != 0 && std::islower(next))) ret.push_back('_'); ret.push_back(static_cast(std::toupper(c))); } return ret == "EANUPC" ? "EAN_UPC" : ret == "UPCA" ? "UPC_A" : ret == "UPCE" ? "UPC_E" : ret == "ALL_GS_1" ? "ALL_GS1" : ret; }; PrintBFs("\t\t{:20}(0x{:04X}),", androidName); } else { PrintUsage(argv[0]); return -1; } return 0; } #else #include int main() { printf("This tool requires C++20 support with std::format. Please use a compatible compiler.\n"); return -1; } #endif