mirror of
https://github.com/mdbtools/mdbtools.git
synced 2026-01-02 12:27:09 +08:00
Make command-line arguments locale-aware (#237)
GLib will automatically convert command line options to UTF-8 provided that setlocale(LC_TYPE, "") is called first, and the argument type is STRING (but not FILENAME). Update the CLI tools to take advantage of this behavior, and likewise implement it in fakeglib. GLib does not automatically convert non-option arguments (i.e. everything remaining in argv after option processing), so manually call g_locale_to_utf8 on these arguments when they represent table names. This should fix the CLI tools when processing non-ASCII table names in non-UTF-8 locales. Also update fakeglib to implement a fast and loose version of g_locale_to_utf8, and factor out some of the code page => iconv name logic in iconv.c so it can be used in our fake g_locale_to_utf8. This adds a new symbol mdb_iconv_name_from_code_page that is not advertised in the main header file. I did not want to include mdbtools.h from fakeglib.c, but maybe that's not important.
This commit is contained in:
@@ -25,6 +25,9 @@ int main(int argc, char **argv) {
|
||||
MdbCatalogEntry *entry;
|
||||
MdbTableDef *table;
|
||||
int found = 0;
|
||||
char *locale = NULL;
|
||||
char *table_name = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: %s <file> <table>\n", argv[0]);
|
||||
@@ -39,9 +42,16 @@ int main(int argc, char **argv) {
|
||||
if (!mdb_read_catalog(mdb, MDB_TABLE)) {
|
||||
return 1;
|
||||
}
|
||||
locale = setlocale(LC_CTYPE, "");
|
||||
table_name = g_locale_to_utf8(argv[2], -1, NULL, NULL, &error);
|
||||
setlocale(LC_CTYPE, locale);
|
||||
if (!table_name) {
|
||||
fprintf(stderr, "Error converting table argument: %s\n", error->message);
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; i < mdb->num_catalog; i++) {
|
||||
entry = g_ptr_array_index(mdb->catalog, i);
|
||||
if (entry->object_type == MDB_TABLE && !g_ascii_strcasecmp(entry->object_name, argv[2])) {
|
||||
if (entry->object_type == MDB_TABLE && !g_ascii_strcasecmp(entry->object_name, table_name)) {
|
||||
table = mdb_read_table(entry);
|
||||
fprintf(stdout, "%d\n", table->num_rows);
|
||||
found = 1;
|
||||
@@ -51,7 +61,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
// check was found:
|
||||
if (!found) {
|
||||
fprintf(stderr, "No table named %s found (among %d tables in file).\n", argv[2], mdb->num_catalog);
|
||||
fprintf(stderr, "No table named %s found (among %d tables in file).\n", table_name, mdb->num_catalog);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -113,6 +113,8 @@ main(int argc, char **argv)
|
||||
char *value;
|
||||
size_t length;
|
||||
int ret;
|
||||
char *table_name = NULL;
|
||||
char *locale = NULL;
|
||||
|
||||
GOptionEntry entries[] = {
|
||||
{"date-format", 'D', 0, G_OPTION_ARG_STRING, &shortdate_fmt, "Set the date format (see strftime(3) for details)", "format"},
|
||||
@@ -126,20 +128,28 @@ main(int argc, char **argv)
|
||||
|
||||
opt_context = g_option_context_new("<file> <table> - export data from Access file to JSON");
|
||||
g_option_context_add_main_entries(opt_context, entries, NULL /*i18n*/);
|
||||
locale = setlocale(LC_CTYPE, "");
|
||||
if (!g_option_context_parse (opt_context, &argc, &argv, &error))
|
||||
{
|
||||
fprintf(stderr, "option parsing failed: %s\n", error->message);
|
||||
fputs(g_option_context_get_help(opt_context, TRUE, NULL), stderr);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (argc != 3) {
|
||||
fputs("Wrong number of arguments.\n\n", stderr);
|
||||
fputs(g_option_context_get_help(opt_context, TRUE, NULL), stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
table_name = g_locale_to_utf8(argv[2], -1, NULL, NULL, &error);
|
||||
if (!table_name) {
|
||||
fprintf(stderr, "argument parsing failed: %s\n", error->message);
|
||||
exit(1);
|
||||
}
|
||||
setlocale(LC_CTYPE, locale);
|
||||
|
||||
if (!(mdb = mdb_open(argv[1], MDB_NOFLAGS))) {
|
||||
g_free(table_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -151,9 +161,9 @@ main(int argc, char **argv)
|
||||
|
||||
mdb_set_bind_size(mdb, EXPORT_BIND_SIZE);
|
||||
|
||||
table = mdb_read_table_by_name(mdb, argv[2], MDB_TABLE);
|
||||
table = mdb_read_table_by_name(mdb, table_name, MDB_TABLE);
|
||||
if (!table) {
|
||||
fprintf(stderr, "Error: Table %s does not exist in this database.\n", argv[argc-1]);
|
||||
fprintf(stderr, "Error: Table %s does not exist in this database.\n", table_name);
|
||||
mdb_close(mdb);
|
||||
exit(1);
|
||||
}
|
||||
@@ -170,6 +180,7 @@ main(int argc, char **argv)
|
||||
ret = mdb_bind_column(table, i+1, bound_values[i], &bound_lens[i]);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "Failed to bind column %d\n", i + 1);
|
||||
mdb_close(mdb);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -207,6 +218,7 @@ main(int argc, char **argv)
|
||||
g_free(bound_values);
|
||||
g_free(bound_lens);
|
||||
mdb_free_tabledef(table);
|
||||
g_free(table_name);
|
||||
|
||||
mdb_close(mdb);
|
||||
return 0;
|
||||
|
||||
@@ -25,6 +25,8 @@ main(int argc, char **argv)
|
||||
{
|
||||
MdbHandle *mdb;
|
||||
MdbTableDef *table;
|
||||
char *table_name = NULL;
|
||||
char *locale = NULL;
|
||||
char *name;
|
||||
gchar *propColName;
|
||||
void *buf;
|
||||
@@ -46,8 +48,16 @@ main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
locale = setlocale(LC_CTYPE, "");
|
||||
table_name = g_locale_to_utf8(argv[2], -1, NULL, NULL, NULL);
|
||||
setlocale(LC_CTYPE, locale);
|
||||
if (!table_name) {
|
||||
mdb_close(mdb);
|
||||
return 1;
|
||||
}
|
||||
table = mdb_read_table_by_name(mdb, "MSysObjects", MDB_ANY);
|
||||
if (!table) {
|
||||
g_free(table_name);
|
||||
mdb_close(mdb);
|
||||
return 1;
|
||||
}
|
||||
@@ -62,13 +72,14 @@ main(int argc, char **argv)
|
||||
g_free(name);
|
||||
g_free(buf);
|
||||
mdb_free_tabledef(table);
|
||||
g_free(table_name);
|
||||
mdb_close(mdb);
|
||||
printf("Column %s not found in MSysObjects!\n", argv[3]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while(mdb_fetch_row(table)) {
|
||||
if (!strcmp(name, argv[2])) {
|
||||
if (!strcmp(name, table_name)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
@@ -89,6 +100,12 @@ main(int argc, char **argv)
|
||||
g_free(buf);
|
||||
mdb_free_tabledef(table);
|
||||
mdb_close(mdb);
|
||||
g_free(table_name);
|
||||
|
||||
if (!found) {
|
||||
printf("Object %s not found in database file!\n", argv[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ main (int argc, char **argv)
|
||||
};
|
||||
GError *error = NULL;
|
||||
GOptionContext *opt_context;
|
||||
char *old_locale = setlocale(LC_CTYPE, "");
|
||||
|
||||
opt_context = g_option_context_new("<file> [<backend>] - Dump schema");
|
||||
g_option_context_add_main_entries(opt_context, entries, NULL /*i18n*/);
|
||||
@@ -67,6 +68,8 @@ main (int argc, char **argv)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
setlocale(LC_CTYPE, old_locale);
|
||||
|
||||
if (argc < 2 || argc > 3) {
|
||||
fputs("Wrong number of arguments.\n\n", stderr);
|
||||
fputs(g_option_context_get_help(opt_context, TRUE, NULL), stderr);
|
||||
|
||||
@@ -340,8 +340,8 @@ main(int argc, char **argv)
|
||||
{ "no-pretty-print", 'P', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &pretty_print, "Don't pretty print", NULL},
|
||||
{ "no-header", 'H', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &headers, "Don't print header", NULL},
|
||||
{ "no-footer", 'F', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &footers, "Don't print footer", NULL},
|
||||
{ "input", 'i', 0, G_OPTION_ARG_STRING, &filename_in, "Read SQL from specified file", "file"},
|
||||
{ "output", 'o', 0, G_OPTION_ARG_STRING, &filename_out, "Write result to specified file", "file"},
|
||||
{ "input", 'i', 0, G_OPTION_ARG_FILENAME, &filename_in, "Read SQL from specified file", "file"},
|
||||
{ "output", 'o', 0, G_OPTION_ARG_FILENAME, &filename_out, "Write result to specified file", "file"},
|
||||
{ NULL },
|
||||
};
|
||||
GError *error = NULL;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <locale.h>
|
||||
#include "mdbtools.h"
|
||||
#include "mdbver.h"
|
||||
#include "mdbprivate.h"
|
||||
|
||||
Reference in New Issue
Block a user