mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
CLI: For Windows, only convert data args to UTF-8, so as to avoid
code page issues with filename args, ticket #288, props Marcel
This commit is contained in:
parent
d5235a914b
commit
fae3e6d9d5
286
frontend/main.c
286
frontend/main.c
@ -1058,132 +1058,6 @@ static int batch_process(struct zint_symbol *symbol, const char *filename, const
|
|||||||
return error_number;
|
return error_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stuff to convert args on Windows command line to UTF-8 */
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#include <shellapi.h>
|
|
||||||
|
|
||||||
#ifndef WC_ERR_INVALID_CHARS
|
|
||||||
#define WC_ERR_INVALID_CHARS 0x00000080
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int win_argc = 0;
|
|
||||||
static char **win_argv = NULL;
|
|
||||||
|
|
||||||
/* Free Windows args */
|
|
||||||
static void win_free_args(void) {
|
|
||||||
int i;
|
|
||||||
if (!win_argv) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (i = 0; i < win_argc; i++) {
|
|
||||||
if (!win_argv[i]) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(win_argv[i]);
|
|
||||||
win_argv[i] = NULL;
|
|
||||||
}
|
|
||||||
free(win_argv);
|
|
||||||
win_argv = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For Windows replace args with UTF-8 versions */
|
|
||||||
/* TODO: using `CommandLineToArgvW()` causes shell32.dll to be loaded - replace with own version, see
|
|
||||||
https://news.ycombinator.com/item?id=18596841 */
|
|
||||||
static void win_args(int *p_argc, char ***p_argv) {
|
|
||||||
int i;
|
|
||||||
LPWSTR *szArgList = CommandLineToArgvW(GetCommandLineW(), &win_argc);
|
|
||||||
if (szArgList) {
|
|
||||||
if (!(win_argv = (char **) calloc(win_argc + 1, sizeof(char *)))) {
|
|
||||||
LocalFree(szArgList);
|
|
||||||
} else {
|
|
||||||
for (i = 0; i < win_argc; i++) {
|
|
||||||
const int len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, szArgList[i], -1, NULL, 0,
|
|
||||||
NULL /*lpDefaultChar*/, NULL /*lpUsedDefaultChar*/);
|
|
||||||
if (len == 0 || !(win_argv[i] = malloc(len + 1))) {
|
|
||||||
win_free_args();
|
|
||||||
LocalFree(szArgList);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, szArgList[i], -1, win_argv[i], len,
|
|
||||||
NULL /*lpDefaultChar*/, NULL /*lpUsedDefaultChar*/) == 0) {
|
|
||||||
win_free_args();
|
|
||||||
LocalFree(szArgList);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i = 0; i < win_argc; i++) {
|
|
||||||
(*p_argv)[i] = win_argv[i];
|
|
||||||
}
|
|
||||||
*p_argc = win_argc;
|
|
||||||
LocalFree(szArgList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
/* Helper to free Windows args on exit */
|
|
||||||
static int do_exit(int error_number) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
win_free_args();
|
|
||||||
#endif
|
|
||||||
exit(error_number);
|
|
||||||
return error_number; /* Not reached */
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct { char *arg; int opt; } arg_opt;
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
struct zint_symbol *my_symbol;
|
|
||||||
struct zint_seg segs[10] = {{0}};
|
|
||||||
int error_number = 0;
|
|
||||||
int warn_number = 0;
|
|
||||||
int rotate_angle = 0;
|
|
||||||
int help = 0;
|
|
||||||
int data_cnt = 0;
|
|
||||||
int input_cnt = 0;
|
|
||||||
int batch_mode = 0;
|
|
||||||
int mirror_mode = 0;
|
|
||||||
int fullmultibyte = 0;
|
|
||||||
int mask = 0;
|
|
||||||
int separator = 0;
|
|
||||||
int addon_gap = 0;
|
|
||||||
int rows = 0;
|
|
||||||
char filetype[4] = {0};
|
|
||||||
int output_given = 0;
|
|
||||||
int png_refused;
|
|
||||||
int val;
|
|
||||||
int i;
|
|
||||||
int ret;
|
|
||||||
char *outfile_extension;
|
|
||||||
int data_arg_num = 0;
|
|
||||||
int seg_count = 0;
|
|
||||||
float x_dim_mm = 0.0f, dpmm = 0.0f;
|
|
||||||
float float_opt;
|
|
||||||
char errbuf[64]; /* For `validate_float()` */
|
|
||||||
arg_opt *arg_opts = (arg_opt *) z_alloca(sizeof(arg_opt) * argc);
|
|
||||||
int no_getopt_error = 1;
|
|
||||||
|
|
||||||
const int no_png = ZBarcode_NoPng();
|
|
||||||
|
|
||||||
if (argc == 1) {
|
|
||||||
usage(no_png);
|
|
||||||
exit(ZINT_ERROR_INVALID_DATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
my_symbol = ZBarcode_Create();
|
|
||||||
if (!my_symbol) {
|
|
||||||
fprintf(stderr, "Error 151: Memory failure\n");
|
|
||||||
exit(ZINT_ERROR_MEMORY);
|
|
||||||
}
|
|
||||||
my_symbol->input_mode = UNICODE_MODE;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
win_args(&argc, &argv);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
opterr = 0; /* Disable `getopt_long_only()` printing errors */
|
|
||||||
while (no_getopt_error) {
|
|
||||||
enum options {
|
enum options {
|
||||||
OPT_ADDONGAP = 128, OPT_BATCH, OPT_BINARY, OPT_BG, OPT_BIND, OPT_BIND_TOP, OPT_BOLD, OPT_BORDER, OPT_BOX,
|
OPT_ADDONGAP = 128, OPT_BATCH, OPT_BINARY, OPT_BG, OPT_BIND, OPT_BIND_TOP, OPT_BOLD, OPT_BORDER, OPT_BOX,
|
||||||
OPT_CMYK, OPT_COLS, OPT_COMPLIANTHEIGHT, OPT_DIRECT, OPT_DMRE, OPT_DOTSIZE, OPT_DOTTY, OPT_DUMP,
|
OPT_CMYK, OPT_COLS, OPT_COMPLIANTHEIGHT, OPT_DIRECT, OPT_DMRE, OPT_DOTSIZE, OPT_DOTTY, OPT_DUMP,
|
||||||
@ -1196,8 +1070,8 @@ int main(int argc, char **argv) {
|
|||||||
OPT_SEPARATOR, OPT_SMALL, OPT_SQUARE, OPT_STRUCTAPP, OPT_TEXTGAP,
|
OPT_SEPARATOR, OPT_SMALL, OPT_SQUARE, OPT_STRUCTAPP, OPT_TEXTGAP,
|
||||||
OPT_VERBOSE, OPT_VERS, OPT_VWHITESP, OPT_WERROR
|
OPT_VERBOSE, OPT_VERS, OPT_VWHITESP, OPT_WERROR
|
||||||
};
|
};
|
||||||
int option_index = 0;
|
|
||||||
static const struct option long_options[] = {
|
static const struct option longopts[] = {
|
||||||
{"addongap", 1, NULL, OPT_ADDONGAP},
|
{"addongap", 1, NULL, OPT_ADDONGAP},
|
||||||
{"barcode", 1, NULL, 'b'},
|
{"barcode", 1, NULL, 'b'},
|
||||||
{"batch", 0, NULL, OPT_BATCH},
|
{"batch", 0, NULL, OPT_BATCH},
|
||||||
@ -1279,7 +1153,161 @@ int main(int argc, char **argv) {
|
|||||||
{"whitesp", 1, NULL, 'w'},
|
{"whitesp", 1, NULL, 'w'},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
const int c = getopt_long_only(argc, argv, "b:d:ehi:o:rtvw:", long_options, &option_index);
|
|
||||||
|
static const char optstring[] = "b:d:ehi:o:rtvw:";
|
||||||
|
|
||||||
|
/* Stuff to convert args on Windows command line to UTF-8 */
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#include <shellapi.h>
|
||||||
|
|
||||||
|
#ifndef WC_ERR_INVALID_CHARS
|
||||||
|
#define WC_ERR_INVALID_CHARS 0x00000080
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int win_argc = 0;
|
||||||
|
static char **win_argv = NULL;
|
||||||
|
|
||||||
|
/* Free Windows args */
|
||||||
|
static void win_free_args(void) {
|
||||||
|
int i;
|
||||||
|
if (!win_argv) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (i = 0; i < win_argc; i++) {
|
||||||
|
if (!win_argv[i]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(win_argv[i]);
|
||||||
|
win_argv[i] = NULL;
|
||||||
|
}
|
||||||
|
free(win_argv);
|
||||||
|
win_argv = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For Windows replace args with UTF-8 versions */
|
||||||
|
/* TODO: using `CommandLineToArgvW()` causes shell32.dll to be loaded - replace with own version, see
|
||||||
|
https://news.ycombinator.com/item?id=18596841 */
|
||||||
|
static void win_args(const int argc, char ***p_argv) {
|
||||||
|
int i;
|
||||||
|
int no_getopt_error = 1;
|
||||||
|
LPWSTR *szArgList;
|
||||||
|
char *utf8_args = (char *) z_alloca(argc);
|
||||||
|
|
||||||
|
/* Only convert data options to UTF-8 - avoids code page issues with filename args, ticket #288, props Marcel */
|
||||||
|
memset(utf8_args, 0, argc);
|
||||||
|
while (no_getopt_error) {
|
||||||
|
const int c = getopt_long_only(argc, *p_argv, optstring, longopts, NULL /*longindex*/);
|
||||||
|
if (c == -1) break;
|
||||||
|
switch (c) {
|
||||||
|
case 'd':
|
||||||
|
case OPT_SEG1: case OPT_SEG2: case OPT_SEG3: case OPT_SEG4: case OPT_SEG5:
|
||||||
|
case OPT_SEG6: case OPT_SEG7: case OPT_SEG8: case OPT_SEG9:
|
||||||
|
utf8_args[optind - 1] = 1;
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
no_getopt_error = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
szArgList = CommandLineToArgvW(GetCommandLineW(), &win_argc);
|
||||||
|
if (szArgList) {
|
||||||
|
if (win_argc != argc || !(win_argv = (char **) calloc(win_argc + 1, sizeof(char *)))) {
|
||||||
|
LocalFree(szArgList);
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < win_argc; i++) {
|
||||||
|
const int len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, szArgList[i], -1, NULL, 0,
|
||||||
|
NULL /*lpDefaultChar*/, NULL /*lpUsedDefaultChar*/);
|
||||||
|
if (len == 0 || !(win_argv[i] = malloc(len + 1))) {
|
||||||
|
win_free_args();
|
||||||
|
LocalFree(szArgList);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, szArgList[i], -1, win_argv[i], len,
|
||||||
|
NULL /*lpDefaultChar*/, NULL /*lpUsedDefaultChar*/) == 0) {
|
||||||
|
win_free_args();
|
||||||
|
LocalFree(szArgList);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < win_argc; i++) {
|
||||||
|
if (utf8_args[i]) {
|
||||||
|
(*p_argv)[i] = win_argv[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LocalFree(szArgList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
/* Helper to free Windows args on exit */
|
||||||
|
static int do_exit(int error_number) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
win_free_args();
|
||||||
|
#endif
|
||||||
|
exit(error_number);
|
||||||
|
return error_number; /* Not reached */
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct { char *arg; int opt; } arg_opt;
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
struct zint_symbol *my_symbol;
|
||||||
|
struct zint_seg segs[10] = {{0}};
|
||||||
|
int error_number = 0;
|
||||||
|
int warn_number = 0;
|
||||||
|
int rotate_angle = 0;
|
||||||
|
int help = 0;
|
||||||
|
int data_cnt = 0;
|
||||||
|
int input_cnt = 0;
|
||||||
|
int batch_mode = 0;
|
||||||
|
int mirror_mode = 0;
|
||||||
|
int fullmultibyte = 0;
|
||||||
|
int mask = 0;
|
||||||
|
int separator = 0;
|
||||||
|
int addon_gap = 0;
|
||||||
|
int rows = 0;
|
||||||
|
char filetype[4] = {0};
|
||||||
|
int output_given = 0;
|
||||||
|
int png_refused;
|
||||||
|
int val;
|
||||||
|
int i;
|
||||||
|
int ret;
|
||||||
|
char *outfile_extension;
|
||||||
|
int data_arg_num = 0;
|
||||||
|
int seg_count = 0;
|
||||||
|
float x_dim_mm = 0.0f, dpmm = 0.0f;
|
||||||
|
float float_opt;
|
||||||
|
char errbuf[64]; /* For `validate_float()` */
|
||||||
|
arg_opt *arg_opts = (arg_opt *) z_alloca(sizeof(arg_opt) * argc);
|
||||||
|
|
||||||
|
const int no_png = ZBarcode_NoPng();
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
usage(no_png);
|
||||||
|
exit(ZINT_ERROR_INVALID_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
my_symbol = ZBarcode_Create();
|
||||||
|
if (!my_symbol) {
|
||||||
|
fprintf(stderr, "Error 151: Memory failure\n");
|
||||||
|
exit(ZINT_ERROR_MEMORY);
|
||||||
|
}
|
||||||
|
my_symbol->input_mode = UNICODE_MODE;
|
||||||
|
|
||||||
|
opterr = 0; /* Disable `getopt_long_only()` printing errors */
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
win_args(argc, &argv);
|
||||||
|
optind = 1; /* Reset after scanning in `win_args()` */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
const int c = getopt_long_only(argc, argv, optstring, longopts, NULL /*longindex*/);
|
||||||
if (c == -1) break;
|
if (c == -1) break;
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
Loading…
Reference in New Issue
Block a user