diff --git a/src/data/automake.mk b/src/data/automake.mk index f7ee43f..92e2f55 100644 --- a/src/data/automake.mk +++ b/src/data/automake.mk @@ -67,6 +67,8 @@ src_data_libdata_la_SOURCES = \ src/data/format.def \ src/data/gnumeric-reader.c \ src/data/gnumeric-reader.h \ + src/data/xls-reader.c \ + src/data/xls-reader.h \ src/data/identifier.c \ src/data/identifier2.c \ src/data/identifier.h \ diff --git a/src/language/data-io/get-data.c b/src/language/data-io/get-data.c index dd55752..6e6fe9b 100644 --- a/src/language/data-io/get-data.c +++ b/src/language/data-io/get-data.c @@ -22,6 +22,7 @@ #include "data/dictionary.h" #include "data/format.h" #include "data/gnumeric-reader.h" +#include "data/xls-reader.h" #include "data/psql-reader.h" #include "data/settings.h" #include "language/command.h" @@ -43,6 +44,7 @@ static int parse_get_gnm (struct lexer *lexer, struct dataset *); static int parse_get_txt (struct lexer *lexer, struct dataset *); static int parse_get_psql (struct lexer *lexer, struct dataset *); +static int parse_get_xls (struct lexer *lexer, struct dataset *); int cmd_get_data (struct lexer *lexer, struct dataset *ds) @@ -60,6 +62,8 @@ cmd_get_data (struct lexer *lexer, struct dataset *ds) return parse_get_txt (lexer, ds); else if (lex_match_id (lexer, "PSQL")) return parse_get_psql (lexer, ds); + else if (lex_match_id (lexer, "XLS")) + return parse_get_xls (lexer, ds); msg (SE, _("Unsupported TYPE %s."), lex_tokcstr (lexer)); return CMD_FAILURE; @@ -569,3 +573,117 @@ parse_get_txt (struct lexer *lexer, struct dataset *ds) free (name); return CMD_CASCADING_FAILURE; } + +static int +parse_get_xls (struct lexer *lexer, struct dataset *ds) +{ + struct xls_read_info xls = {NULL, NULL, NULL, 1, true, -1}; + + lex_force_match (lexer, T_SLASH); + + if (!lex_force_match_id (lexer, "FILE")) + goto error; + + lex_force_match (lexer, T_EQUALS); + + if (!lex_force_string (lexer)) + goto error; + + xls.file_name = utf8_to_filename (lex_tokcstr (lexer)); + + lex_get (lexer); + + while (lex_match (lexer, T_SLASH) ) + { + if ( lex_match_id (lexer, "ASSUMEDSTRWIDTH")) + { + lex_match (lexer, T_EQUALS); + xls.asw = lex_integer (lexer); + lex_get (lexer); + } + else if (lex_match_id (lexer, "SHEET")) + { + lex_match (lexer, T_EQUALS); + if (lex_match_id (lexer, "NAME")) + { + if ( ! lex_force_string (lexer) ) + goto error; + + xls.sheet_name = ss_xstrdup (lex_tokss (lexer)); + xls.sheet_index = -1; //TODO why? + + lex_get (lexer); + } + else if (lex_match_id (lexer, "INDEX")) + { + xls.sheet_index = lex_integer (lexer); + lex_get (lexer); + } + else + goto error; + } + else if (lex_match_id (lexer, "CELLRANGE")) + { + lex_match (lexer, T_EQUALS); + + if (lex_match_id (lexer, "FULL")) + { + xls.cell_range = NULL; + } + else if (lex_match_id (lexer, "RANGE")) + { + if ( ! lex_force_string (lexer) ) + goto error; + + xls.cell_range = ss_xstrdup (lex_tokss (lexer)); + lex_get (lexer); + } + else + goto error; + } + else if (lex_match_id (lexer, "READNAMES")) + { + lex_match (lexer, T_EQUALS); + + if ( lex_match_id (lexer, "ON")) + { + xls.read_names = true; + } + else if (lex_match_id (lexer, "OFF")) + { + xls.read_names = false; + } + else + goto error; + } + else + { + lex_error (lexer, NULL); + goto error; + } + } + + { + struct dictionary *dict = NULL; + struct casereader *reader = xls_open_reader (&xls, &dict); + + if ( reader ) + { + dataset_set_dict (ds, dict); + dataset_set_source (ds, reader); + } + } + + free (xls.file_name); + free (xls.sheet_name); + free (xls.cell_range); + return CMD_SUCCESS; + + error: + + free (xls.file_name); + free (xls.sheet_name); + free (xls.cell_range); + return CMD_FAILURE; +} +