Skip to content

Commit eff4b24

Browse files
committed
Merge branch 'testing'
2 parents 02b7924 + 1ea95ff commit eff4b24

280 files changed

Lines changed: 16188 additions & 18377 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/CMakeLists.txt

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ add_subdirectory(amplp/examples/modhide)
5050
add_subdirectory(amplp/examples/heuristic)
5151
add_subdirectory(amplp/examples/ampljson)
5252

53+
# amplxl
54+
add_subdirectory(amplxl)
55+
5356
# simpbit
5457
add_ampl_library(simpbit tables/simpbit.c)
5558
target_link_libraries(simpbit PUBLIC asl)
@@ -77,42 +80,6 @@ target_link_libraries(ampltabl asl)
7780
# add_test(NAME sqlite3-test COMMAND ${PYTHON_PROGRAM}
7881
# ${CMAKE_CURRENT_BINARY_DIR}/sqlite3/tests/test.py ${AMPL_PROGRAM} $<TARGET_FILE:sqlite3th>)
7982
# endif (SQLite3_FOUND)
80-
81-
# Build zlib from the included sources, it generates the target
82-
# zlibstatic that we can link statically to
83-
set(SKIP_INSTALL_ALL ON) # skip install targets of zlib
84-
add_subdirectory(amplxl/zlib-1.2.11)
85-
addToTablesFolder(support zlib zlibstatic minigzip)
86-
set(ZLIB_INCLUDE_DIRS amplxl/zlib-1.2.11 ${CMAKE_CURRENT_BINARY_DIR}/amplxl/zlib-1.2.11 amplxl/zlib-1.2.11/contrib/minizip)
87-
set(ZLIB_LIBRARIES zlibstatic)
88-
89-
set(AMPLXL_SOURCES
90-
amplxl/src/ampl_xl.cpp
91-
amplxl/src/ioapi.c
92-
amplxl/src/myunz.cpp
93-
amplxl/src/myzip.cpp
94-
amplxl/src/copyzip.cpp
95-
amplxl/src/pugixml.cpp
96-
amplxl/src/oxmlutils.cpp
97-
amplxl/src/logger.cpp
98-
amplxl/src/utils.cpp
99-
amplxl/src/unzip.c
100-
amplxl/src/zip.c)
101-
if (WIN32)
102-
set(AMPLXL_SOURCES ${AMPLXL_SOURCES} amplxl/src/iowin32.c)
103-
endif()
104-
105-
add_ampl_library(amplxl ${AMPLXL_SOURCES}
106-
COMPONENT ${DISTRO_COMPONENT})
107-
108-
set_target_properties(amplxl PROPERTIES LINKER_LANGUAGE CXX)
109-
target_link_libraries(amplxl PRIVATE asl2 ${ZLIB_LIBRARIES})
110-
target_include_directories(amplxl PRIVATE ${ZLIB_INCLUDE_DIRS})
111-
112-
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/amplxl/tests DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/amplxl)
113-
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test_utils.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/amplxl/tests)
114-
add_test(NAME amplxl-test COMMAND ${PYTHON_PROGRAM}
115-
${CMAKE_CURRENT_BINARY_DIR}/amplxl/tests/test.py ${AMPL_PROGRAM} $<TARGET_FILE:amplxl>)
11683

11784
find_package(ODBC)
11885
if (ODBC_FOUND)

src/amplp/examples/amplcsv/src/handler.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ public TableConnector{
3131
// character used to quote strings
3232
std::string quotechar;
3333

34-
// weather or not to read/write the header
34+
// whether or not to read/write the header
3535
bool has_header;
3636

37-
// Whether or not to quote/unquote strings when writing/reading, defaults to false
37+
// whether or not to quote/unquote strings when writing/reading, defaults to false
3838
bool quotestrings;
3939

40-
// Whether or not to use the existing csv header (OUT only)
40+
// whether or not to use the existing csv header (OUT only)
4141
bool use_header;
4242

4343
// override functions

src/amplxl/CMakeLists.txt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Build zlib from the included sources, it generates the target
2+
# zlibstatic that we can link statically to
3+
set(SKIP_INSTALL_ALL ON) # skip install targets of zlib
4+
5+
set(Z_DIR zlib-1.3)
6+
set(MZ_DIR ${Z_DIR}/contrib/minizip)
7+
8+
add_subdirectory(${Z_DIR} EXCLUDE_FROM_ALL)
9+
set_property(TARGET zlibstatic PROPERTY POSITION_INDEPENDENT_CODE ON)
10+
11+
set(ZLIB_INCLUDE_DIRS ./${Z_DIR} ${CMAKE_CURRENT_BINARY_DIR}/${Z_DIR} ./${MZ_DIR})
12+
13+
set(AMPLXL_SOURCES
14+
./src/ampl_xl.cpp
15+
./src/myunz.cpp
16+
./src/myzip.cpp
17+
./src/copyzip.cpp
18+
./src/pugixml.cpp
19+
./src/oxmlutils.cpp
20+
./src/logger.cpp
21+
./src/utils.cpp
22+
./${MZ_DIR}/ioapi.c
23+
./${MZ_DIR}/zip.c
24+
./${MZ_DIR}/unzip.c)
25+
26+
if (WIN32)
27+
set(AMPLXL_SOURCES ${AMPLXL_SOURCES} ./${MZ_DIR}//iowin32.c)
28+
endif()
29+
30+
add_ampl_library(amplxl ${AMPLXL_SOURCES}
31+
COMPONENT ${DISTRO_COMPONENT})
32+
33+
set_target_properties(amplxl PROPERTIES LINKER_LANGUAGE CXX)
34+
target_link_libraries(amplxl PRIVATE asl2 zlibstatic)
35+
target_include_directories(amplxl PRIVATE ${ZLIB_INCLUDE_DIRS})
36+
37+
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/tests DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/amplxl)
38+
file(COPY ../test_utils.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/amplxl/tests)
39+
add_test(NAME amplxl-test COMMAND ${PYTHON_PROGRAM}
40+
${CMAKE_CURRENT_BINARY_DIR}/amplxl/tests/test.py ${AMPL_PROGRAM} $<TARGET_FILE:amplxl>)

src/amplxl/doc.txt

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
A table handler for spreadsheet files (.xlsx).
2+
3+
General information on table handlers and data correspondence between AMPL and
4+
an external table is available at chapter 10 of the AMPL book:
5+
6+
https://ampl.com/learn/ampl-book/
7+
8+
The available options for amplxl are:
9+
10+
2D
11+
Keyword to to specify that data indexed over two sets will be represented in
12+
a two-dimensional table, with keys from one set labeling the rows, and keys
13+
from the other set labeling the columns.
14+
15+
Example:
16+
table foo IN "amplxl" "2D": [keycol1, keycol2], valcol;
17+
18+
alias:
19+
Instead of writing the data to a specific .xlsx file it is possible to
20+
define an alias. In the following example the table handler will search for
21+
the file bar.xlsx to write the data. If the file does not exist it will be
22+
created.
23+
24+
Example:
25+
table foo OUT "amplxl" "bar": [A], B;
26+
27+
backup=option
28+
Whether or not to backup the existing .xlsx file before writing to it.
29+
The backup will create a file with the same name as the provided .xlsx file
30+
but with an .amplback extension. To use the backup file rename the .amplback
31+
extension to .xlsx.
32+
Options: true (default), false.
33+
34+
Example:
35+
table foo OUT "amplxl" "backup=false": [keycol1, keycol2], valcol;
36+
37+
external-table-spec:
38+
Specifies the path to the .xlsx file to be read or written with the read
39+
table and write table commands. If no file is specified, amplxl will search
40+
for a file with the table name and the .xlsx file extension in the current
41+
directory. If the table is to be written and the file does not exist it will
42+
be created.
43+
44+
Example:
45+
table foo OUT "amplxl" "bar.xlsx": [keycol], valcol;
46+
47+
verbose:
48+
Display warnings during the execution of the read table and write table
49+
commands.
50+
51+
Example:
52+
table foo OUT "amplxl" "verbose": [keycol], valcol;
53+
54+
verbose=option:
55+
Display information according to the specified option. Available options:
56+
0 (default) - display information only on error,
57+
1 - display warnings,
58+
2 - display general information
59+
3 - display debug information.
60+
61+
Example:
62+
table foo OUT "amplxl" "verbose=2": [keycol], valcol;
63+
64+
write=option
65+
Define how the data is written in OUT mode. Available options:
66+
delete (default) - deletes all the rows of the current table (if it
67+
exists) before writing the data from AMPL.
68+
append - append the rows in AMPL to the external representation of the
69+
table.

src/amplxl/src/ampl_xl.cpp

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,9 @@ Write_ampl_xl(AmplExports *ae, TableInfo *TI){
2323
void
2424
funcadd(AmplExports *ae){
2525

26-
/* description of handlers */
27-
28-
static char info[] = "amplxl\n"
29-
"Table handler for .xlsx and .xlsm files:\n"
30-
"one or two strings (an optional 'amplxl' and the file name,\n"
31-
"ending in \".xlsx\" or \".xlsm\") expected before \":[...]\".";
32-
3326
/* Inform AMPL about the .example handlers */
3427

35-
add_table_handler(Read_ampl_xl, Write_ampl_xl, info, 0, 0);
36-
37-
28+
add_table_handler(Read_ampl_xl, Write_ampl_xl, const_cast<char *>(doc.c_str()), 0, 0);
3829
};
3930

4031

@@ -86,7 +77,7 @@ ExcelManager::ExcelManager(){
8677
has_range = false;
8778
break_mode = false;
8879
verbose = 0;
89-
write = "drop";
80+
write = "delete";
9081
backup = true;
9182
is2D = false;
9283
isReader = true;
@@ -330,8 +321,8 @@ ExcelManager::prepare(){
330321

331322
option_string = arg_string.substr(write_op.size());
332323

333-
if (option_string == "drop"){
334-
write = "drop";
324+
if (option_string == "delete"){
325+
write = "delete";
335326
}
336327
else if (option_string == "append"){
337328
write = "append";
@@ -403,7 +394,7 @@ ExcelManager::prepare(){
403394
// we create the non existing file with the declared name
404395
if (inout == "OUT"){
405396

406-
write = "drop";
397+
write = "delete";
407398
msg = "Declared file does not exist. Creating file ";
408399
msg += excel_path;
409400
msg += " with sheet ";
@@ -471,7 +462,7 @@ ExcelManager::manage_workbook(){
471462
result = myunzip(excel_path, excel_iner_file, temp_folder);
472463

473464
if (result){
474-
msg = "cannot extract workbook";
465+
msg = "Cannot extract workbook. Is the file open in another application?";
475466
logger.log(msg, LOG_ERROR);
476467
return 1;
477468
}
@@ -482,7 +473,7 @@ ExcelManager::manage_workbook(){
482473
result = parse_workbook();
483474

484475
if (result){
485-
msg = "cannot parse workbook";
476+
msg = "Cannot parse workbook";
486477
logger.log(msg, LOG_ERROR);
487478
return 1;
488479
}
@@ -501,13 +492,13 @@ ExcelManager::manage_workbook(){
501492
}
502493

503494
if (result){
504-
msg = "cannot parse range";
495+
msg = "Cannot parse range";
505496
logger.log(msg, LOG_ERROR);
506497
return 1;
507498
}
508499
}
509500

510-
msg = "Table type: " + tableType;
501+
msg = "Table type: " + numeric_to_string(tableType);
511502
logger.log(msg, LOG_DEBUG);
512503

513504
//~ sheet_rel = sheet_rel_map[range_sheet];
@@ -1463,7 +1454,7 @@ ExcelWriteManager::manage_data(){
14631454

14641455
if (inout == "OUT"){
14651456

1466-
if (write == "drop"){
1457+
if (write == "delete"){
14671458

14681459
// At this point we have an estimate of the table dimensions.
14691460
// However, due to the dynamic nature of data, this estimate may not be correct.
@@ -2567,7 +2558,7 @@ int
25672558
ExcelWriteManager::delete_data(pugi::xml_node parent){
25682559

25692560
int include_header = 0;
2570-
if (write == std::string("drop")){
2561+
if (write == std::string("delete")){
25712562
include_header = 1;
25722563
}
25732564

@@ -4138,7 +4129,7 @@ ExcelWriteManager::manage_data2D(){
41384129

41394130
if (inout == "OUT"){
41404131

4141-
if (write == "drop"){
4132+
if (write == "delete"){
41424133

41434134
result = write_data_out_2D(node, first_row, last_row, first_col, last_col);
41444135
}
@@ -4149,7 +4140,7 @@ ExcelWriteManager::manage_data2D(){
41494140
}
41504141
}
41514142
else if (inout == "INOUT"){
4152-
if (write == "drop"){
4143+
if (write == "delete"){
41534144

41544145
result = write_data_inout_2D(node, first_row, last_row, first_col, last_col);
41554146
}
@@ -4420,7 +4411,7 @@ ExcelManager::parse_header_2D_reader(
44204411
xl_col_map[xl_col_name] = iter_col;
44214412
header.push_back(xl_col_name);
44224413

4423-
msg = "Found column header " + xl_col_name;
4414+
msg = "Found column header '" + xl_col_name + "'";
44244415
logger.log(msg, LOG_DEBUG);
44254416
}
44264417
else if (tableType != TABLE_SHEET){
@@ -4504,7 +4495,7 @@ ExcelManager::parse_data2D(
45044495
if (found){
45054496
// more than 1 column not mapped
45064497
msg = "Found more than one candidate for key row in 2D table. At least "
4507-
+ h_set + " and " + ampl_col_name + " are not found.";
4498+
+ h_set + " and " + ampl_col_name + " are not key columns.";
45084499
logger.log(msg, LOG_ERROR);
45094500
return 1;
45104501
}

0 commit comments

Comments
 (0)