-
-
Notifications
You must be signed in to change notification settings - Fork 547
Expand file tree
/
Copy pathZXingBarcodeFormat.cpp
More file actions
106 lines (91 loc) · 3.31 KB
/
Copy pathZXingBarcodeFormat.cpp
File metadata and controls
106 lines (91 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
* Copyright 2026 Axel Waggershauser
*/
// SPDX-License-Identifier: Apache-2.0
#include "BarcodeFormat.h"
#include <version>
#ifdef __cpp_lib_format
#include "StdPrint.h"
#include <cctype>
#include <cstring>
#include <format>
#include <functional>
#include <string>
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: {} <Android|C#|Go|K/N|Rust|Swift>", exePath);
}
static void PrintBFs(
std::format_string<std::string, int> fmt,
std::function<std::string(const char*)> 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<char>(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 <cstdio>
int main()
{
printf("This tool requires C++20 support with std::format. Please use a compatible compiler.\n");
return -1;
}
#endif