diff options
Diffstat (limited to 'src/liborcus')
208 files changed, 59641 insertions, 0 deletions
diff --git a/src/liborcus/Makefile.am b/src/liborcus/Makefile.am new file mode 100644 index 0000000..4f42193 --- /dev/null +++ b/src/liborcus/Makefile.am @@ -0,0 +1,590 @@ + +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/include \ + -I./include $(BOOST_CPPFLAGS) + +EXTRA_PROGRAMS = \ + css-document-tree-test \ + json-document-tree-test \ + yaml-document-tree-test \ + xml-map-tree-test \ + common-test \ + dom-tree-test \ + json-structure-tree-test \ + json-map-tree-test \ + xml-structure-tree-test \ + xpath-parser-test + +TESTS = + +EXTRA_DIST = \ + xml_element_types.hpp + +if HAVE_STATIC_LIB +AM_CPPFLAGS += -D__ORCUS_STATIC_LIB=1 +else +AM_CPPFLAGS += -D__ORCUS_BUILDING_DLL=1 +endif + +if HAVE_FILESYSTEM +AM_CPPFLAGS += "-DHAVE_FILESYSTEM=1" +endif + +if HAVE_EXPERIMENTAL_FILESYSTEM +AM_CPPFLAGS += "-DHAVE_EXPERIMENTAL_FILESYSTEM=1" +endif + +liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS = \ + $(ZLIB_CFLAGS) + +liborcus_@ORCUS_API_VERSION@_la_LDFLAGS = \ + -no-undefined $(BOOST_SYSTEM_LDFLAGS) + +liborcus_@ORCUS_API_VERSION@_la_LIBADD = \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(BOOST_SYSTEM_LIBS) $(ZLIB_LIBS) + +if !HAVE_FILESYSTEM +if HAVE_EXPERIMENTAL_FILESYSTEM +liborcus_@ORCUS_API_VERSION@_la_LDFLAGS += -lstdc++fs +else +liborcus_@ORCUS_API_VERSION@_la_LDFLAGS += $(BOOST_FILESYSTEM_LDFLAGS) +liborcus_@ORCUS_API_VERSION@_la_LIBADD += $(BOOST_FILESYSTEM_LIBS) +endif +endif + +AM_CPPFLAGS += -DSRCDIR=\""$(top_srcdir)"\" + +lib_LTLIBRARIES = liborcus-@ORCUS_API_VERSION@.la +liborcus_@ORCUS_API_VERSION@_la_SOURCES = \ + config.cpp \ + css_document_tree.cpp \ + css_selector.cpp \ + detection_result.hpp \ + detection_result.cpp \ + dom_tree.cpp \ + format_detection.cpp \ + formula_result.hpp \ + formula_result.cpp \ + impl_utils.hpp \ + info.cpp \ + interface.cpp \ + json_document_tree.cpp \ + json_map_tree.hpp \ + json_map_tree.cpp \ + json_structure_mapper.hpp \ + json_structure_mapper.cpp \ + json_structure_tree.cpp \ + json_util.hpp \ + json_util.cpp \ + spreadsheet_interface.cpp \ + orcus_csv.cpp \ + orcus_json.cpp \ + orcus_xml.cpp \ + orcus_xml_impl.hpp \ + orcus_xml_impl.cpp \ + orcus_xml_map_def.cpp \ + measurement.cpp \ + number_utils.cpp \ + number_utils.hpp \ + xml_context_base.hpp \ + xml_context_base.cpp \ + xml_context_global.hpp \ + xml_context_global.cpp \ + xml_element_types.cpp \ + xml_element_validator.hpp \ + xml_element_validator.cpp \ + xml_empty_context.hpp \ + xml_empty_context.cpp \ + xml_map_tree.hpp \ + xml_map_tree.cpp \ + xml_stream_handler.hpp \ + xml_stream_handler.cpp \ + xml_stream_parser.hpp \ + xml_stream_parser.cpp \ + xml_simple_stream_handler.hpp \ + xml_simple_stream_handler.cpp \ + xml_structure_mapper.hpp \ + xml_structure_mapper.cpp \ + xml_structure_tree.cpp \ + xml_util.hpp \ + xml_util.cpp \ + xpath_parser.cpp \ + yaml_document_tree.cpp \ + ooxml_namespace_types.cpp \ + ooxml_namespace_types.hpp \ + odf_namespace_types.hpp \ + odf_namespace_types_hpp.inl \ + odf_namespace_types.cpp \ + odf_namespace_types_cpp.inl \ + gnumeric_namespace_types.hpp \ + gnumeric_namespace_types.cpp \ + xls_xml_namespace_types.hpp \ + xls_xml_namespace_types.cpp \ + session_context.hpp \ + session_context.cpp \ + spreadsheet_impl_types.hpp \ + spreadsheet_impl_types.cpp \ + spreadsheet_types.cpp \ + spreadsheet_iface_util.hpp \ + spreadsheet_iface_util.cpp \ + string_helper.hpp \ + string_helper.cpp + +if WITH_XLSX_FILTER + +EXTRA_PROGRAMS += \ + xlsx-sheet-context-test + +liborcus_@ORCUS_API_VERSION@_la_SOURCES += \ + ooxml_content_types.cpp \ + ooxml_content_types.hpp \ + ooxml_global.cpp \ + ooxml_global.hpp \ + ooxml_schemas.cpp \ + ooxml_schemas.hpp \ + ooxml_token_constants.hpp \ + ooxml_token_constants.inl \ + ooxml_tokens.cpp \ + ooxml_tokens.hpp \ + ooxml_tokens.inl \ + ooxml_types.hpp \ + ooxml_types.cpp \ + opc_context.cpp \ + opc_context.hpp \ + opc_reader.cpp \ + opc_reader.hpp \ + opc_reader.hpp \ + opc_token_constants.hpp \ + opc_token_constants.inl \ + opc_tokens.inl \ + orcus_xlsx.cpp \ + orcus_import_xlsx.cpp \ + xlsx_shared_strings_context.cpp \ + xlsx_shared_strings_context.hpp \ + xlsx_drawing_context.hpp \ + xlsx_drawing_context.cpp \ + xlsx_handler.cpp \ + xlsx_handler.hpp \ + xlsx_helper.cpp \ + xlsx_helper.hpp \ + xlsx_session_data.hpp \ + xlsx_session_data.cpp \ + xlsx_revision_context.cpp \ + xlsx_revision_context.hpp \ + xlsx_pivot_context.cpp \ + xlsx_pivot_context.hpp \ + xlsx_sheet_context.cpp \ + xlsx_sheet_context.hpp \ + xlsx_styles_context.cpp \ + xlsx_styles_context.hpp \ + xlsx_conditional_format_context.cpp \ + xlsx_conditional_format_context.hpp \ + xlsx_table_context.cpp \ + xlsx_table_context.hpp \ + xlsx_autofilter_context.cpp \ + xlsx_autofilter_context.hpp \ + xlsx_types.hpp \ + xlsx_types.cpp \ + xlsx_workbook_context.cpp \ + xlsx_workbook_context.hpp + +# xlsx-sheet-context-test + +xlsx_sheet_context_test_SOURCES = \ + formula_result.cpp \ + ooxml_global.cpp \ + ooxml_namespace_types.cpp \ + ooxml_schemas.cpp \ + ooxml_tokens.cpp \ + ooxml_types.cpp \ + session_context.cpp \ + spreadsheet_interface.cpp \ + xlsx_autofilter_context.cpp \ + xlsx_conditional_format_context.cpp \ + xlsx_helper.cpp \ + xlsx_session_data.cpp \ + xlsx_sheet_context.cpp \ + xlsx_sheet_context_test.cpp \ + xlsx_types.cpp \ + xml_context_base.cpp \ + xml_context_global.cpp \ + xml_element_types.cpp \ + xml_element_validator.cpp \ + xml_empty_context.cpp \ + xml_util.cpp + +xlsx_sheet_context_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + ../test/liborcus-test.a + +xlsx_sheet_context_test_CPPFLAGS = -I$(top_builddir)/lib/liborcus/liborcus.la $(AM_CPPFLAGS) + +TESTS += \ + xlsx-sheet-context-test + +endif # WITH_XLSX_FILTER + +if WITH_XLS_XML_FILTER + +liborcus_@ORCUS_API_VERSION@_la_SOURCES += \ + xls_xml_tokens.hpp \ + xls_xml_tokens.inl \ + xls_xml_tokens.cpp \ + xls_xml_token_constants.hpp \ + xls_xml_token_constants.inl \ + orcus_xls_xml.cpp \ + xls_xml_detection_handler.hpp \ + xls_xml_detection_handler.cpp \ + xls_xml_handler.hpp \ + xls_xml_handler.cpp \ + xls_xml_context.hpp \ + xls_xml_context.cpp + +endif # WITH_XLS_XML_FILTER + +if WITH_ODS_FILTER + +liborcus_@ORCUS_API_VERSION@_la_SOURCES += \ + odf_document_styles_context.hpp \ + odf_document_styles_context.cpp \ + odf_para_context.hpp \ + odf_para_context.cpp \ + odf_styles.hpp \ + odf_styles.cpp \ + odf_styles_context.hpp \ + odf_styles_context.cpp \ + odf_style_context.hpp \ + odf_style_context.cpp \ + odf_number_format_context.hpp \ + odf_number_format_context.cpp \ + odf_token_constants.hpp \ + odf_token_constants.inl \ + odf_tokens.hpp \ + odf_tokens.inl \ + odf_tokens.cpp \ + ods_content_xml_context.hpp \ + ods_content_xml_context.cpp \ + ods_dde_links_context.hpp \ + ods_dde_links_context.cpp \ + ods_session_data.hpp \ + ods_session_data.cpp \ + odf_helper.hpp \ + odf_helper.cpp \ + orcus_ods.cpp \ + orcus_import_ods.cpp + +# odf-helper-test + +EXTRA_PROGRAMS += \ + odf-helper-test + +odf_helper_test_SOURCES = \ + odf_helper.cpp \ + string_helper.cpp \ + odf_helper_test.cpp + +odf_helper_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la + +odf_helper_test_CPPFLAGS = -I$(top_builddir)/lib/liborcus/liborcus.la $(AM_CPPFLAGS) + +TESTS += \ + odf-helper-test + +endif # WITH_ODS_FILTER + +if WITH_GNUMERIC_FILTER + +liborcus_@ORCUS_API_VERSION@_la_SOURCES += \ + gnumeric_cell_context.cpp \ + gnumeric_cell_context.hpp \ + gnumeric_context.cpp \ + gnumeric_context.hpp \ + gnumeric_detection_handler.cpp \ + gnumeric_detection_handler.hpp \ + gnumeric_filter_context.cpp \ + gnumeric_filter_context.hpp \ + gnumeric_handler.cpp \ + gnumeric_handler.hpp \ + gnumeric_names_context.cpp \ + gnumeric_names_context.hpp \ + gnumeric_sheet_context.cpp \ + gnumeric_sheet_context.hpp \ + gnumeric_styles_context.cpp \ + gnumeric_styles_context.hpp \ + gnumeric_token_constants.hpp \ + gnumeric_token_constants.inl \ + gnumeric_tokens.cpp \ + gnumeric_tokens.hpp \ + gnumeric_tokens.inl \ + gnumeric_types.cpp \ + gnumeric_types.hpp \ + gnumeric_value_format_parser.cpp \ + gnumeric_value_format_parser.hpp \ + orcus_gnumeric.cpp + +liborcus_@ORCUS_API_VERSION@_la_LDFLAGS += \ + $(BOOST_IOSTREAMS_LDFLAGS) + +liborcus_@ORCUS_API_VERSION@_la_LIBADD += \ + $(BOOST_IOSTREAMS_LIBS) + +# gnumeric-cell-context-test + +EXTRA_PROGRAMS += \ + gnumeric-cell-context-test \ + gnumeric-sheet-context-test + +gnumeric_cell_context_test_SOURCES = \ + number_utils.cpp \ + session_context.cpp \ + gnumeric_cell_context_test.cpp \ + gnumeric_cell_context.cpp \ + gnumeric_value_format_parser.cpp \ + xml_context_base.cpp \ + xml_element_types.cpp \ + xml_element_validator.cpp \ + xml_empty_context.cpp \ + xml_util.cpp \ + gnumeric_namespace_types.cpp \ + gnumeric_tokens.cpp \ + gnumeric_types.cpp \ + odf_namespace_types.cpp \ + spreadsheet_interface.cpp + +gnumeric_cell_context_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + ../test/liborcus-test.a + +orcus_gnumeric_cell_context_test_CPPFLAGS = -I$(top_builddir)/lib/liborcus/liborcus.la $(AM_CPPFLAGS) + +TESTS += gnumeric-cell-context-test + +# gnumeric-sheet-context-test + +gnumeric_sheet_context_test_SOURCES = \ + session_context.cpp \ + gnumeric_sheet_context_test.cpp \ + gnumeric_sheet_context.cpp \ + gnumeric_names_context.cpp \ + gnumeric_cell_context.cpp \ + gnumeric_filter_context.cpp \ + gnumeric_styles_context.cpp \ + gnumeric_value_format_parser.cpp \ + gnumeric_types.cpp \ + number_utils.cpp \ + xml_context_base.cpp \ + xml_element_types.cpp \ + xml_element_validator.cpp \ + xml_empty_context.cpp \ + xml_util.cpp \ + gnumeric_namespace_types.cpp \ + gnumeric_tokens.cpp \ + odf_namespace_types.cpp \ + spreadsheet_interface.cpp \ + string_helper.cpp + +gnumeric_sheet_context_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + ../test/liborcus-test.a + +gnumeric_sheet_context_test_CPPFLAGS = -I$(top_builddir)/lib/liborcus/liborcus.la $(AM_CPPFLAGS) + +TESTS += gnumeric-sheet-context-test + +endif # WITH_GNUMERIC_FILTER + +if WITH_PARQUET_FILTER + +liborcus_@ORCUS_API_VERSION@_la_SOURCES += \ + orcus_parquet.cpp + +liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS += \ + $(PARQUET_CFLAGS) + +liborcus_@ORCUS_API_VERSION@_la_LDFLAGS += \ + $(PARQUET_LDFLAGS) + +liborcus_@ORCUS_API_VERSION@_la_LIBADD += \ + $(PARQUET_LIBS) + +endif # WITH_PARQUET_FILTER + +# css-document-tree-test + +css_document_tree_test_SOURCES = \ + css_document_tree.cpp \ + css_document_tree_test.cpp + +css_document_tree_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(BOOST_SYSTEM_LIBS) + +if !HAVE_FILESYSTEM +if HAVE_EXPERIMENTAL_FILESYSTEM +css_document_tree_test_LDADD += -lstdc++fs +else +css_document_tree_test_LDADD += $(BOOST_FILESYSTEM_LIBS) +endif +endif + +# json-document-tree-test + +json_document_tree_test_SOURCES = \ + json_document_tree.cpp \ + json_util.cpp \ + json_document_tree_test.cpp + +json_document_tree_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + ../test/liborcus-test.a \ + $(BOOST_SYSTEM_LIBS) + +if !HAVE_FILESYSTEM +if HAVE_EXPERIMENTAL_FILESYSTEM +json_document_tree_test_LDADD += -lstdc++fs +else +json_document_tree_test_LDADD += $(BOOST_FILESYSTEM_LIBS) +endif +endif + +json_document_tree_test_CPPFLAGS = -I$(top_builddir)/lib/liborcus/liborcus.la $(AM_CPPFLAGS) + +# yaml-document-tree-test + +yaml_document_tree_test_SOURCES = \ + yaml_document_tree.cpp \ + json_util.cpp \ + yaml_document_tree_test.cpp + +yaml_document_tree_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(BOOST_SYSTEM_LIBS) + +if !HAVE_FILESYSTEM +if HAVE_EXPERIMENTAL_FILESYSTEM +yaml_document_tree_test_LDADD += -lstdc++fs +else +yaml_document_tree_test_LDADD += $(BOOST_FILESYSTEM_LIBS) +endif +endif + +yaml_document_tree_test_CPPFLAGS = -I$(top_builddir)/lib/liborcus/liborcus.la $(AM_CPPFLAGS) + +# xml-map-tree-test + +xml_map_tree_test_SOURCES = \ + xml_map_tree.cpp \ + xml_map_tree.hpp \ + xpath_parser.hpp \ + xpath_parser.cpp \ + spreadsheet_impl_types.hpp \ + spreadsheet_impl_types.cpp \ + xml_map_tree_test.cpp + +xml_map_tree_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + ../test/liborcus-test.a \ + $(BOOST_SYSTEM_LIBS) + +# xml-structure-tree-test + +xml_structure_tree_test_SOURCES = \ + string_helper.cpp \ + xml_structure_tree.cpp \ + xml_structure_mapper.cpp \ + xml_structure_tree_test.cpp + +xml_structure_tree_test_CPPFLAGS = -I$(top_builddir)/lib/liborcus/liborcus.la $(AM_CPPFLAGS) + +xml_structure_tree_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(BOOST_SYSTEM_LIBS) + +if !HAVE_FILESYSTEM +if HAVE_EXPERIMENTAL_FILESYSTEM +xml_structure_tree_test_LDADD += -lstdc++fs +else +xml_structure_tree_test_LDADD += $(BOOST_FILESYSTEM_LIBS) +endif +endif + +# common-test + +common_test_SOURCES = \ + common_test.cpp + +common_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la + +# dom-tree-test + +dom_tree_test_SOURCES = dom_tree_test.cpp +dom_tree_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la + +# json-structure-tree-test + +json_structure_tree_test_SOURCES = json_structure_tree_test.cpp +json_structure_tree_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(BOOST_SYSTEM_LIBS) + +if !HAVE_FILESYSTEM +if HAVE_EXPERIMENTAL_FILESYSTEM +json_structure_tree_test_LDADD += -lstdc++fs +else +json_structure_tree_test_LDADD += $(BOOST_FILESYSTEM_LIBS) +endif +endif + +# json-map-tree-test + +json_map_tree_test_SOURCES = json_map_tree_test.cpp \ + json_map_tree.cpp \ + spreadsheet_impl_types.cpp +json_map_tree_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(BOOST_SYSTEM_LIBS) + +# xpath-parser-test + +xpath_parser_test_SOURCES = \ + xpath_parser_test.cpp \ + xpath_parser.cpp +xpath_parser_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(BOOST_SYSTEM_LIBS) + +TESTS += \ + css-document-tree-test \ + json-document-tree-test \ + yaml-document-tree-test \ + xml-map-tree-test \ + common-test \ + dom-tree-test \ + json-structure-tree-test \ + json-map-tree-test \ + xml-structure-tree-test \ + xpath-parser-test + +distclean-local: + rm -rf $(TESTS) + +@VALGRIND_CHECK_RULES@ diff --git a/src/liborcus/Makefile.in b/src/liborcus/Makefile.in new file mode 100644 index 0000000..2b75863 --- /dev/null +++ b/src/liborcus/Makefile.in @@ -0,0 +1,4283 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +EXTRA_PROGRAMS = css-document-tree-test$(EXEEXT) \ + json-document-tree-test$(EXEEXT) \ + yaml-document-tree-test$(EXEEXT) xml-map-tree-test$(EXEEXT) \ + common-test$(EXEEXT) dom-tree-test$(EXEEXT) \ + json-structure-tree-test$(EXEEXT) json-map-tree-test$(EXEEXT) \ + xml-structure-tree-test$(EXEEXT) xpath-parser-test$(EXEEXT) \ + $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) +TESTS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ + css-document-tree-test$(EXEEXT) \ + json-document-tree-test$(EXEEXT) \ + yaml-document-tree-test$(EXEEXT) xml-map-tree-test$(EXEEXT) \ + common-test$(EXEEXT) dom-tree-test$(EXEEXT) \ + json-structure-tree-test$(EXEEXT) json-map-tree-test$(EXEEXT) \ + xml-structure-tree-test$(EXEEXT) xpath-parser-test$(EXEEXT) +@HAVE_STATIC_LIB_TRUE@am__append_1 = -D__ORCUS_STATIC_LIB=1 +@HAVE_STATIC_LIB_FALSE@am__append_2 = -D__ORCUS_BUILDING_DLL=1 +@HAVE_FILESYSTEM_TRUE@am__append_3 = "-DHAVE_FILESYSTEM=1" +@HAVE_EXPERIMENTAL_FILESYSTEM_TRUE@am__append_4 = "-DHAVE_EXPERIMENTAL_FILESYSTEM=1" +@HAVE_EXPERIMENTAL_FILESYSTEM_TRUE@@HAVE_FILESYSTEM_FALSE@am__append_5 = -lstdc++fs +@HAVE_EXPERIMENTAL_FILESYSTEM_FALSE@@HAVE_FILESYSTEM_FALSE@am__append_6 = $(BOOST_FILESYSTEM_LDFLAGS) +@HAVE_EXPERIMENTAL_FILESYSTEM_FALSE@@HAVE_FILESYSTEM_FALSE@am__append_7 = $(BOOST_FILESYSTEM_LIBS) +@WITH_XLSX_FILTER_TRUE@am__append_8 = \ +@WITH_XLSX_FILTER_TRUE@ xlsx-sheet-context-test + +@WITH_XLSX_FILTER_TRUE@am__append_9 = \ +@WITH_XLSX_FILTER_TRUE@ ooxml_content_types.cpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_content_types.hpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_global.cpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_global.hpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_schemas.cpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_schemas.hpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_token_constants.hpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_token_constants.inl \ +@WITH_XLSX_FILTER_TRUE@ ooxml_tokens.cpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_tokens.hpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_tokens.inl \ +@WITH_XLSX_FILTER_TRUE@ ooxml_types.hpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_types.cpp \ +@WITH_XLSX_FILTER_TRUE@ opc_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ opc_context.hpp \ +@WITH_XLSX_FILTER_TRUE@ opc_reader.cpp \ +@WITH_XLSX_FILTER_TRUE@ opc_reader.hpp \ +@WITH_XLSX_FILTER_TRUE@ opc_reader.hpp \ +@WITH_XLSX_FILTER_TRUE@ opc_token_constants.hpp \ +@WITH_XLSX_FILTER_TRUE@ opc_token_constants.inl \ +@WITH_XLSX_FILTER_TRUE@ opc_tokens.inl \ +@WITH_XLSX_FILTER_TRUE@ orcus_xlsx.cpp \ +@WITH_XLSX_FILTER_TRUE@ orcus_import_xlsx.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_shared_strings_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_shared_strings_context.hpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_drawing_context.hpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_drawing_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_handler.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_handler.hpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_helper.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_helper.hpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_session_data.hpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_session_data.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_revision_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_revision_context.hpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_pivot_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_pivot_context.hpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context.hpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_styles_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_styles_context.hpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_conditional_format_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_conditional_format_context.hpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_table_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_table_context.hpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_autofilter_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_autofilter_context.hpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_types.hpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_types.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_workbook_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_workbook_context.hpp + +@WITH_XLSX_FILTER_TRUE@am__append_10 = \ +@WITH_XLSX_FILTER_TRUE@ xlsx-sheet-context-test + +@WITH_XLS_XML_FILTER_TRUE@am__append_11 = \ +@WITH_XLS_XML_FILTER_TRUE@ xls_xml_tokens.hpp \ +@WITH_XLS_XML_FILTER_TRUE@ xls_xml_tokens.inl \ +@WITH_XLS_XML_FILTER_TRUE@ xls_xml_tokens.cpp \ +@WITH_XLS_XML_FILTER_TRUE@ xls_xml_token_constants.hpp \ +@WITH_XLS_XML_FILTER_TRUE@ xls_xml_token_constants.inl \ +@WITH_XLS_XML_FILTER_TRUE@ orcus_xls_xml.cpp \ +@WITH_XLS_XML_FILTER_TRUE@ xls_xml_detection_handler.hpp \ +@WITH_XLS_XML_FILTER_TRUE@ xls_xml_detection_handler.cpp \ +@WITH_XLS_XML_FILTER_TRUE@ xls_xml_handler.hpp \ +@WITH_XLS_XML_FILTER_TRUE@ xls_xml_handler.cpp \ +@WITH_XLS_XML_FILTER_TRUE@ xls_xml_context.hpp \ +@WITH_XLS_XML_FILTER_TRUE@ xls_xml_context.cpp + +@WITH_ODS_FILTER_TRUE@am__append_12 = \ +@WITH_ODS_FILTER_TRUE@ odf_document_styles_context.hpp \ +@WITH_ODS_FILTER_TRUE@ odf_document_styles_context.cpp \ +@WITH_ODS_FILTER_TRUE@ odf_para_context.hpp \ +@WITH_ODS_FILTER_TRUE@ odf_para_context.cpp \ +@WITH_ODS_FILTER_TRUE@ odf_styles.hpp \ +@WITH_ODS_FILTER_TRUE@ odf_styles.cpp \ +@WITH_ODS_FILTER_TRUE@ odf_styles_context.hpp \ +@WITH_ODS_FILTER_TRUE@ odf_styles_context.cpp \ +@WITH_ODS_FILTER_TRUE@ odf_style_context.hpp \ +@WITH_ODS_FILTER_TRUE@ odf_style_context.cpp \ +@WITH_ODS_FILTER_TRUE@ odf_number_format_context.hpp \ +@WITH_ODS_FILTER_TRUE@ odf_number_format_context.cpp \ +@WITH_ODS_FILTER_TRUE@ odf_token_constants.hpp \ +@WITH_ODS_FILTER_TRUE@ odf_token_constants.inl \ +@WITH_ODS_FILTER_TRUE@ odf_tokens.hpp \ +@WITH_ODS_FILTER_TRUE@ odf_tokens.inl \ +@WITH_ODS_FILTER_TRUE@ odf_tokens.cpp \ +@WITH_ODS_FILTER_TRUE@ ods_content_xml_context.hpp \ +@WITH_ODS_FILTER_TRUE@ ods_content_xml_context.cpp \ +@WITH_ODS_FILTER_TRUE@ ods_dde_links_context.hpp \ +@WITH_ODS_FILTER_TRUE@ ods_dde_links_context.cpp \ +@WITH_ODS_FILTER_TRUE@ ods_session_data.hpp \ +@WITH_ODS_FILTER_TRUE@ ods_session_data.cpp \ +@WITH_ODS_FILTER_TRUE@ odf_helper.hpp \ +@WITH_ODS_FILTER_TRUE@ odf_helper.cpp \ +@WITH_ODS_FILTER_TRUE@ orcus_ods.cpp \ +@WITH_ODS_FILTER_TRUE@ orcus_import_ods.cpp + + +# odf-helper-test +@WITH_ODS_FILTER_TRUE@am__append_13 = \ +@WITH_ODS_FILTER_TRUE@ odf-helper-test + +@WITH_ODS_FILTER_TRUE@am__append_14 = \ +@WITH_ODS_FILTER_TRUE@ odf-helper-test + +@WITH_GNUMERIC_FILTER_TRUE@am__append_15 = \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_cell_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_cell_context.hpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_context.hpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_detection_handler.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_detection_handler.hpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_filter_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_filter_context.hpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_handler.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_handler.hpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_names_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_names_context.hpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context.hpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_styles_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_styles_context.hpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_token_constants.hpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_token_constants.inl \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_tokens.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_tokens.hpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_tokens.inl \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_types.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_types.hpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_value_format_parser.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_value_format_parser.hpp \ +@WITH_GNUMERIC_FILTER_TRUE@ orcus_gnumeric.cpp + +@WITH_GNUMERIC_FILTER_TRUE@am__append_16 = \ +@WITH_GNUMERIC_FILTER_TRUE@ $(BOOST_IOSTREAMS_LDFLAGS) + +@WITH_GNUMERIC_FILTER_TRUE@am__append_17 = \ +@WITH_GNUMERIC_FILTER_TRUE@ $(BOOST_IOSTREAMS_LIBS) + + +# gnumeric-cell-context-test +@WITH_GNUMERIC_FILTER_TRUE@am__append_18 = \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric-cell-context-test \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric-sheet-context-test + +@WITH_GNUMERIC_FILTER_TRUE@am__append_19 = gnumeric-cell-context-test \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric-sheet-context-test +@WITH_PARQUET_FILTER_TRUE@am__append_20 = \ +@WITH_PARQUET_FILTER_TRUE@ orcus_parquet.cpp + +@WITH_PARQUET_FILTER_TRUE@am__append_21 = \ +@WITH_PARQUET_FILTER_TRUE@ $(PARQUET_CFLAGS) + +@WITH_PARQUET_FILTER_TRUE@am__append_22 = \ +@WITH_PARQUET_FILTER_TRUE@ $(PARQUET_LDFLAGS) + +@WITH_PARQUET_FILTER_TRUE@am__append_23 = \ +@WITH_PARQUET_FILTER_TRUE@ $(PARQUET_LIBS) + +@HAVE_EXPERIMENTAL_FILESYSTEM_TRUE@@HAVE_FILESYSTEM_FALSE@am__append_24 = -lstdc++fs +@HAVE_EXPERIMENTAL_FILESYSTEM_FALSE@@HAVE_FILESYSTEM_FALSE@am__append_25 = $(BOOST_FILESYSTEM_LIBS) +@HAVE_EXPERIMENTAL_FILESYSTEM_TRUE@@HAVE_FILESYSTEM_FALSE@am__append_26 = -lstdc++fs +@HAVE_EXPERIMENTAL_FILESYSTEM_FALSE@@HAVE_FILESYSTEM_FALSE@am__append_27 = $(BOOST_FILESYSTEM_LIBS) +@HAVE_EXPERIMENTAL_FILESYSTEM_TRUE@@HAVE_FILESYSTEM_FALSE@am__append_28 = -lstdc++fs +@HAVE_EXPERIMENTAL_FILESYSTEM_FALSE@@HAVE_FILESYSTEM_FALSE@am__append_29 = $(BOOST_FILESYSTEM_LIBS) +@HAVE_EXPERIMENTAL_FILESYSTEM_TRUE@@HAVE_FILESYSTEM_FALSE@am__append_30 = -lstdc++fs +@HAVE_EXPERIMENTAL_FILESYSTEM_FALSE@@HAVE_FILESYSTEM_FALSE@am__append_31 = $(BOOST_FILESYSTEM_LIBS) +@HAVE_EXPERIMENTAL_FILESYSTEM_TRUE@@HAVE_FILESYSTEM_FALSE@am__append_32 = -lstdc++fs +@HAVE_EXPERIMENTAL_FILESYSTEM_FALSE@@HAVE_FILESYSTEM_FALSE@am__append_33 = $(BOOST_FILESYSTEM_LIBS) +subdir = src/liborcus +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/ax_cxx_compile_stdcxx_17.m4 \ + $(top_srcdir)/m4/boost.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/m4_ax_valgrind_check.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = constants.inl +CONFIG_CLEAN_VPATH_FILES = +@WITH_XLSX_FILTER_TRUE@am__EXEEXT_1 = \ +@WITH_XLSX_FILTER_TRUE@ xlsx-sheet-context-test$(EXEEXT) +@WITH_ODS_FILTER_TRUE@am__EXEEXT_2 = odf-helper-test$(EXEEXT) +@WITH_GNUMERIC_FILTER_TRUE@am__EXEEXT_3 = gnumeric-cell-context-test$(EXEEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric-sheet-context-test$(EXEEXT) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +@HAVE_EXPERIMENTAL_FILESYSTEM_FALSE@@HAVE_FILESYSTEM_FALSE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +@WITH_GNUMERIC_FILTER_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) +@WITH_PARQUET_FILTER_TRUE@am__DEPENDENCIES_4 = $(am__DEPENDENCIES_1) +liborcus_@ORCUS_API_VERSION@_la_DEPENDENCIES = \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) \ + $(am__DEPENDENCIES_4) +am__liborcus_@ORCUS_API_VERSION@_la_SOURCES_DIST = config.cpp \ + css_document_tree.cpp css_selector.cpp detection_result.hpp \ + detection_result.cpp dom_tree.cpp format_detection.cpp \ + formula_result.hpp formula_result.cpp impl_utils.hpp info.cpp \ + interface.cpp json_document_tree.cpp json_map_tree.hpp \ + json_map_tree.cpp json_structure_mapper.hpp \ + json_structure_mapper.cpp json_structure_tree.cpp \ + json_util.hpp json_util.cpp spreadsheet_interface.cpp \ + orcus_csv.cpp orcus_json.cpp orcus_xml.cpp orcus_xml_impl.hpp \ + orcus_xml_impl.cpp orcus_xml_map_def.cpp measurement.cpp \ + number_utils.cpp number_utils.hpp xml_context_base.hpp \ + xml_context_base.cpp xml_context_global.hpp \ + xml_context_global.cpp xml_element_types.cpp \ + xml_element_validator.hpp xml_element_validator.cpp \ + xml_empty_context.hpp xml_empty_context.cpp xml_map_tree.hpp \ + xml_map_tree.cpp xml_stream_handler.hpp xml_stream_handler.cpp \ + xml_stream_parser.hpp xml_stream_parser.cpp \ + xml_simple_stream_handler.hpp xml_simple_stream_handler.cpp \ + xml_structure_mapper.hpp xml_structure_mapper.cpp \ + xml_structure_tree.cpp xml_util.hpp xml_util.cpp \ + xpath_parser.cpp yaml_document_tree.cpp \ + ooxml_namespace_types.cpp ooxml_namespace_types.hpp \ + odf_namespace_types.hpp odf_namespace_types_hpp.inl \ + odf_namespace_types.cpp odf_namespace_types_cpp.inl \ + gnumeric_namespace_types.hpp gnumeric_namespace_types.cpp \ + xls_xml_namespace_types.hpp xls_xml_namespace_types.cpp \ + session_context.hpp session_context.cpp \ + spreadsheet_impl_types.hpp spreadsheet_impl_types.cpp \ + spreadsheet_types.cpp spreadsheet_iface_util.hpp \ + spreadsheet_iface_util.cpp string_helper.hpp string_helper.cpp \ + ooxml_content_types.cpp ooxml_content_types.hpp \ + ooxml_global.cpp ooxml_global.hpp ooxml_schemas.cpp \ + ooxml_schemas.hpp ooxml_token_constants.hpp \ + ooxml_token_constants.inl ooxml_tokens.cpp ooxml_tokens.hpp \ + ooxml_tokens.inl ooxml_types.hpp ooxml_types.cpp \ + opc_context.cpp opc_context.hpp opc_reader.cpp opc_reader.hpp \ + opc_token_constants.hpp opc_token_constants.inl opc_tokens.inl \ + orcus_xlsx.cpp orcus_import_xlsx.cpp \ + xlsx_shared_strings_context.cpp \ + xlsx_shared_strings_context.hpp xlsx_drawing_context.hpp \ + xlsx_drawing_context.cpp xlsx_handler.cpp xlsx_handler.hpp \ + xlsx_helper.cpp xlsx_helper.hpp xlsx_session_data.hpp \ + xlsx_session_data.cpp xlsx_revision_context.cpp \ + xlsx_revision_context.hpp xlsx_pivot_context.cpp \ + xlsx_pivot_context.hpp xlsx_sheet_context.cpp \ + xlsx_sheet_context.hpp xlsx_styles_context.cpp \ + xlsx_styles_context.hpp xlsx_conditional_format_context.cpp \ + xlsx_conditional_format_context.hpp xlsx_table_context.cpp \ + xlsx_table_context.hpp xlsx_autofilter_context.cpp \ + xlsx_autofilter_context.hpp xlsx_types.hpp xlsx_types.cpp \ + xlsx_workbook_context.cpp xlsx_workbook_context.hpp \ + xls_xml_tokens.hpp xls_xml_tokens.inl xls_xml_tokens.cpp \ + xls_xml_token_constants.hpp xls_xml_token_constants.inl \ + orcus_xls_xml.cpp xls_xml_detection_handler.hpp \ + xls_xml_detection_handler.cpp xls_xml_handler.hpp \ + xls_xml_handler.cpp xls_xml_context.hpp xls_xml_context.cpp \ + odf_document_styles_context.hpp \ + odf_document_styles_context.cpp odf_para_context.hpp \ + odf_para_context.cpp odf_styles.hpp odf_styles.cpp \ + odf_styles_context.hpp odf_styles_context.cpp \ + odf_style_context.hpp odf_style_context.cpp \ + odf_number_format_context.hpp odf_number_format_context.cpp \ + odf_token_constants.hpp odf_token_constants.inl odf_tokens.hpp \ + odf_tokens.inl odf_tokens.cpp ods_content_xml_context.hpp \ + ods_content_xml_context.cpp ods_dde_links_context.hpp \ + ods_dde_links_context.cpp ods_session_data.hpp \ + ods_session_data.cpp odf_helper.hpp odf_helper.cpp \ + orcus_ods.cpp orcus_import_ods.cpp gnumeric_cell_context.cpp \ + gnumeric_cell_context.hpp gnumeric_context.cpp \ + gnumeric_context.hpp gnumeric_detection_handler.cpp \ + gnumeric_detection_handler.hpp gnumeric_filter_context.cpp \ + gnumeric_filter_context.hpp gnumeric_handler.cpp \ + gnumeric_handler.hpp gnumeric_names_context.cpp \ + gnumeric_names_context.hpp gnumeric_sheet_context.cpp \ + gnumeric_sheet_context.hpp gnumeric_styles_context.cpp \ + gnumeric_styles_context.hpp gnumeric_token_constants.hpp \ + gnumeric_token_constants.inl gnumeric_tokens.cpp \ + gnumeric_tokens.hpp gnumeric_tokens.inl gnumeric_types.cpp \ + gnumeric_types.hpp gnumeric_value_format_parser.cpp \ + gnumeric_value_format_parser.hpp orcus_gnumeric.cpp \ + orcus_parquet.cpp +@WITH_XLSX_FILTER_TRUE@am__objects_1 = liborcus_@ORCUS_API_VERSION@_la-ooxml_content_types.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-ooxml_global.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-ooxml_schemas.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-ooxml_tokens.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-ooxml_types.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-opc_context.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-opc_reader.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-orcus_xlsx.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-orcus_import_xlsx.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xlsx_shared_strings_context.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xlsx_drawing_context.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xlsx_handler.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xlsx_helper.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xlsx_session_data.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xlsx_revision_context.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xlsx_pivot_context.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xlsx_sheet_context.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xlsx_styles_context.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xlsx_conditional_format_context.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xlsx_table_context.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xlsx_autofilter_context.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xlsx_types.lo \ +@WITH_XLSX_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xlsx_workbook_context.lo +@WITH_XLS_XML_FILTER_TRUE@am__objects_2 = liborcus_@ORCUS_API_VERSION@_la-xls_xml_tokens.lo \ +@WITH_XLS_XML_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-orcus_xls_xml.lo \ +@WITH_XLS_XML_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xls_xml_detection_handler.lo \ +@WITH_XLS_XML_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xls_xml_handler.lo \ +@WITH_XLS_XML_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-xls_xml_context.lo +@WITH_ODS_FILTER_TRUE@am__objects_3 = liborcus_@ORCUS_API_VERSION@_la-odf_document_styles_context.lo \ +@WITH_ODS_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-odf_para_context.lo \ +@WITH_ODS_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-odf_styles.lo \ +@WITH_ODS_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-odf_styles_context.lo \ +@WITH_ODS_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-odf_style_context.lo \ +@WITH_ODS_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-odf_number_format_context.lo \ +@WITH_ODS_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-odf_tokens.lo \ +@WITH_ODS_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-ods_content_xml_context.lo \ +@WITH_ODS_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-ods_dde_links_context.lo \ +@WITH_ODS_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-ods_session_data.lo \ +@WITH_ODS_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-odf_helper.lo \ +@WITH_ODS_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-orcus_ods.lo \ +@WITH_ODS_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-orcus_import_ods.lo +@WITH_GNUMERIC_FILTER_TRUE@am__objects_4 = liborcus_@ORCUS_API_VERSION@_la-gnumeric_cell_context.lo \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-gnumeric_context.lo \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-gnumeric_detection_handler.lo \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-gnumeric_filter_context.lo \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-gnumeric_handler.lo \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-gnumeric_names_context.lo \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-gnumeric_sheet_context.lo \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-gnumeric_styles_context.lo \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-gnumeric_tokens.lo \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-gnumeric_types.lo \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-gnumeric_value_format_parser.lo \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus_@ORCUS_API_VERSION@_la-orcus_gnumeric.lo +@WITH_PARQUET_FILTER_TRUE@am__objects_5 = liborcus_@ORCUS_API_VERSION@_la-orcus_parquet.lo +am_liborcus_@ORCUS_API_VERSION@_la_OBJECTS = \ + liborcus_@ORCUS_API_VERSION@_la-config.lo \ + liborcus_@ORCUS_API_VERSION@_la-css_document_tree.lo \ + liborcus_@ORCUS_API_VERSION@_la-css_selector.lo \ + liborcus_@ORCUS_API_VERSION@_la-detection_result.lo \ + liborcus_@ORCUS_API_VERSION@_la-dom_tree.lo \ + liborcus_@ORCUS_API_VERSION@_la-format_detection.lo \ + liborcus_@ORCUS_API_VERSION@_la-formula_result.lo \ + liborcus_@ORCUS_API_VERSION@_la-info.lo \ + liborcus_@ORCUS_API_VERSION@_la-interface.lo \ + liborcus_@ORCUS_API_VERSION@_la-json_document_tree.lo \ + liborcus_@ORCUS_API_VERSION@_la-json_map_tree.lo \ + liborcus_@ORCUS_API_VERSION@_la-json_structure_mapper.lo \ + liborcus_@ORCUS_API_VERSION@_la-json_structure_tree.lo \ + liborcus_@ORCUS_API_VERSION@_la-json_util.lo \ + liborcus_@ORCUS_API_VERSION@_la-spreadsheet_interface.lo \ + liborcus_@ORCUS_API_VERSION@_la-orcus_csv.lo \ + liborcus_@ORCUS_API_VERSION@_la-orcus_json.lo \ + liborcus_@ORCUS_API_VERSION@_la-orcus_xml.lo \ + liborcus_@ORCUS_API_VERSION@_la-orcus_xml_impl.lo \ + liborcus_@ORCUS_API_VERSION@_la-orcus_xml_map_def.lo \ + liborcus_@ORCUS_API_VERSION@_la-measurement.lo \ + liborcus_@ORCUS_API_VERSION@_la-number_utils.lo \ + liborcus_@ORCUS_API_VERSION@_la-xml_context_base.lo \ + liborcus_@ORCUS_API_VERSION@_la-xml_context_global.lo \ + liborcus_@ORCUS_API_VERSION@_la-xml_element_types.lo \ + liborcus_@ORCUS_API_VERSION@_la-xml_element_validator.lo \ + liborcus_@ORCUS_API_VERSION@_la-xml_empty_context.lo \ + liborcus_@ORCUS_API_VERSION@_la-xml_map_tree.lo \ + liborcus_@ORCUS_API_VERSION@_la-xml_stream_handler.lo \ + liborcus_@ORCUS_API_VERSION@_la-xml_stream_parser.lo \ + liborcus_@ORCUS_API_VERSION@_la-xml_simple_stream_handler.lo \ + liborcus_@ORCUS_API_VERSION@_la-xml_structure_mapper.lo \ + liborcus_@ORCUS_API_VERSION@_la-xml_structure_tree.lo \ + liborcus_@ORCUS_API_VERSION@_la-xml_util.lo \ + liborcus_@ORCUS_API_VERSION@_la-xpath_parser.lo \ + liborcus_@ORCUS_API_VERSION@_la-yaml_document_tree.lo \ + liborcus_@ORCUS_API_VERSION@_la-ooxml_namespace_types.lo \ + liborcus_@ORCUS_API_VERSION@_la-odf_namespace_types.lo \ + liborcus_@ORCUS_API_VERSION@_la-gnumeric_namespace_types.lo \ + liborcus_@ORCUS_API_VERSION@_la-xls_xml_namespace_types.lo \ + liborcus_@ORCUS_API_VERSION@_la-session_context.lo \ + liborcus_@ORCUS_API_VERSION@_la-spreadsheet_impl_types.lo \ + liborcus_@ORCUS_API_VERSION@_la-spreadsheet_types.lo \ + liborcus_@ORCUS_API_VERSION@_la-spreadsheet_iface_util.lo \ + liborcus_@ORCUS_API_VERSION@_la-string_helper.lo \ + $(am__objects_1) $(am__objects_2) $(am__objects_3) \ + $(am__objects_4) $(am__objects_5) +liborcus_@ORCUS_API_VERSION@_la_OBJECTS = \ + $(am_liborcus_@ORCUS_API_VERSION@_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +liborcus_@ORCUS_API_VERSION@_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) \ + $(liborcus_@ORCUS_API_VERSION@_la_LDFLAGS) $(LDFLAGS) -o $@ +am_common_test_OBJECTS = common_test.$(OBJEXT) +common_test_OBJECTS = $(am_common_test_OBJECTS) +common_test_DEPENDENCIES = liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la +am_css_document_tree_test_OBJECTS = css_document_tree.$(OBJEXT) \ + css_document_tree_test.$(OBJEXT) +css_document_tree_test_OBJECTS = $(am_css_document_tree_test_OBJECTS) +css_document_tree_test_DEPENDENCIES = liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_2) +am_dom_tree_test_OBJECTS = dom_tree_test.$(OBJEXT) +dom_tree_test_OBJECTS = $(am_dom_tree_test_OBJECTS) +dom_tree_test_DEPENDENCIES = liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la +am__gnumeric_cell_context_test_SOURCES_DIST = number_utils.cpp \ + session_context.cpp gnumeric_cell_context_test.cpp \ + gnumeric_cell_context.cpp gnumeric_value_format_parser.cpp \ + xml_context_base.cpp xml_element_types.cpp \ + xml_element_validator.cpp xml_empty_context.cpp xml_util.cpp \ + gnumeric_namespace_types.cpp gnumeric_tokens.cpp \ + gnumeric_types.cpp odf_namespace_types.cpp \ + spreadsheet_interface.cpp +@WITH_GNUMERIC_FILTER_TRUE@am_gnumeric_cell_context_test_OBJECTS = \ +@WITH_GNUMERIC_FILTER_TRUE@ number_utils.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ session_context.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_cell_context_test.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_cell_context.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_value_format_parser.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_context_base.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_element_types.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_element_validator.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_empty_context.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_util.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_namespace_types.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_tokens.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_types.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ odf_namespace_types.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ spreadsheet_interface.$(OBJEXT) +gnumeric_cell_context_test_OBJECTS = \ + $(am_gnumeric_cell_context_test_OBJECTS) +@WITH_GNUMERIC_FILTER_TRUE@gnumeric_cell_context_test_DEPENDENCIES = \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus-@ORCUS_API_VERSION@.la \ +@WITH_GNUMERIC_FILTER_TRUE@ ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ +@WITH_GNUMERIC_FILTER_TRUE@ ../test/liborcus-test.a +am__gnumeric_sheet_context_test_SOURCES_DIST = session_context.cpp \ + gnumeric_sheet_context_test.cpp gnumeric_sheet_context.cpp \ + gnumeric_names_context.cpp gnumeric_cell_context.cpp \ + gnumeric_filter_context.cpp gnumeric_styles_context.cpp \ + gnumeric_value_format_parser.cpp gnumeric_types.cpp \ + number_utils.cpp xml_context_base.cpp xml_element_types.cpp \ + xml_element_validator.cpp xml_empty_context.cpp xml_util.cpp \ + gnumeric_namespace_types.cpp gnumeric_tokens.cpp \ + odf_namespace_types.cpp spreadsheet_interface.cpp \ + string_helper.cpp +@WITH_GNUMERIC_FILTER_TRUE@am_gnumeric_sheet_context_test_OBJECTS = gnumeric_sheet_context_test-session_context.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-gnumeric_sheet_context_test.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-gnumeric_sheet_context.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-gnumeric_names_context.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-gnumeric_cell_context.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-gnumeric_filter_context.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-gnumeric_styles_context.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-gnumeric_value_format_parser.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-gnumeric_types.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-number_utils.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-xml_context_base.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-xml_element_types.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-xml_element_validator.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-xml_empty_context.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-xml_util.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-gnumeric_namespace_types.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-gnumeric_tokens.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-odf_namespace_types.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-spreadsheet_interface.$(OBJEXT) \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test-string_helper.$(OBJEXT) +gnumeric_sheet_context_test_OBJECTS = \ + $(am_gnumeric_sheet_context_test_OBJECTS) +@WITH_GNUMERIC_FILTER_TRUE@gnumeric_sheet_context_test_DEPENDENCIES = \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus-@ORCUS_API_VERSION@.la \ +@WITH_GNUMERIC_FILTER_TRUE@ ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ +@WITH_GNUMERIC_FILTER_TRUE@ ../test/liborcus-test.a +am_json_document_tree_test_OBJECTS = \ + json_document_tree_test-json_document_tree.$(OBJEXT) \ + json_document_tree_test-json_util.$(OBJEXT) \ + json_document_tree_test-json_document_tree_test.$(OBJEXT) +json_document_tree_test_OBJECTS = \ + $(am_json_document_tree_test_OBJECTS) +json_document_tree_test_DEPENDENCIES = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + ../test/liborcus-test.a $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) +am_json_map_tree_test_OBJECTS = json_map_tree_test.$(OBJEXT) \ + json_map_tree.$(OBJEXT) spreadsheet_impl_types.$(OBJEXT) +json_map_tree_test_OBJECTS = $(am_json_map_tree_test_OBJECTS) +json_map_tree_test_DEPENDENCIES = liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(am__DEPENDENCIES_1) +am_json_structure_tree_test_OBJECTS = \ + json_structure_tree_test.$(OBJEXT) +json_structure_tree_test_OBJECTS = \ + $(am_json_structure_tree_test_OBJECTS) +json_structure_tree_test_DEPENDENCIES = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_2) +am__odf_helper_test_SOURCES_DIST = odf_helper.cpp string_helper.cpp \ + odf_helper_test.cpp +@WITH_ODS_FILTER_TRUE@am_odf_helper_test_OBJECTS = \ +@WITH_ODS_FILTER_TRUE@ odf_helper_test-odf_helper.$(OBJEXT) \ +@WITH_ODS_FILTER_TRUE@ odf_helper_test-string_helper.$(OBJEXT) \ +@WITH_ODS_FILTER_TRUE@ odf_helper_test-odf_helper_test.$(OBJEXT) +odf_helper_test_OBJECTS = $(am_odf_helper_test_OBJECTS) +@WITH_ODS_FILTER_TRUE@odf_helper_test_DEPENDENCIES = \ +@WITH_ODS_FILTER_TRUE@ liborcus-@ORCUS_API_VERSION@.la \ +@WITH_ODS_FILTER_TRUE@ ../parser/liborcus-parser-@ORCUS_API_VERSION@.la +am__xlsx_sheet_context_test_SOURCES_DIST = formula_result.cpp \ + ooxml_global.cpp ooxml_namespace_types.cpp ooxml_schemas.cpp \ + ooxml_tokens.cpp ooxml_types.cpp session_context.cpp \ + spreadsheet_interface.cpp xlsx_autofilter_context.cpp \ + xlsx_conditional_format_context.cpp xlsx_helper.cpp \ + xlsx_session_data.cpp xlsx_sheet_context.cpp \ + xlsx_sheet_context_test.cpp xlsx_types.cpp \ + xml_context_base.cpp xml_context_global.cpp \ + xml_element_types.cpp xml_element_validator.cpp \ + xml_empty_context.cpp xml_util.cpp +@WITH_XLSX_FILTER_TRUE@am_xlsx_sheet_context_test_OBJECTS = xlsx_sheet_context_test-formula_result.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-ooxml_global.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-ooxml_namespace_types.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-ooxml_schemas.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-ooxml_tokens.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-ooxml_types.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-session_context.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-spreadsheet_interface.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-xlsx_autofilter_context.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-xlsx_conditional_format_context.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-xlsx_helper.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-xlsx_session_data.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-xlsx_sheet_context.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-xlsx_sheet_context_test.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-xlsx_types.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-xml_context_base.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-xml_context_global.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-xml_element_types.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-xml_element_validator.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-xml_empty_context.$(OBJEXT) \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test-xml_util.$(OBJEXT) +xlsx_sheet_context_test_OBJECTS = \ + $(am_xlsx_sheet_context_test_OBJECTS) +@WITH_XLSX_FILTER_TRUE@xlsx_sheet_context_test_DEPENDENCIES = \ +@WITH_XLSX_FILTER_TRUE@ liborcus-@ORCUS_API_VERSION@.la \ +@WITH_XLSX_FILTER_TRUE@ ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ +@WITH_XLSX_FILTER_TRUE@ ../test/liborcus-test.a +am_xml_map_tree_test_OBJECTS = xml_map_tree.$(OBJEXT) \ + xpath_parser.$(OBJEXT) spreadsheet_impl_types.$(OBJEXT) \ + xml_map_tree_test.$(OBJEXT) +xml_map_tree_test_OBJECTS = $(am_xml_map_tree_test_OBJECTS) +xml_map_tree_test_DEPENDENCIES = liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + ../test/liborcus-test.a $(am__DEPENDENCIES_1) +am_xml_structure_tree_test_OBJECTS = \ + xml_structure_tree_test-string_helper.$(OBJEXT) \ + xml_structure_tree_test-xml_structure_tree.$(OBJEXT) \ + xml_structure_tree_test-xml_structure_mapper.$(OBJEXT) \ + xml_structure_tree_test-xml_structure_tree_test.$(OBJEXT) +xml_structure_tree_test_OBJECTS = \ + $(am_xml_structure_tree_test_OBJECTS) +xml_structure_tree_test_DEPENDENCIES = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_2) +am_xpath_parser_test_OBJECTS = xpath_parser_test.$(OBJEXT) \ + xpath_parser.$(OBJEXT) +xpath_parser_test_OBJECTS = $(am_xpath_parser_test_OBJECTS) +xpath_parser_test_DEPENDENCIES = liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(am__DEPENDENCIES_1) +am_yaml_document_tree_test_OBJECTS = \ + yaml_document_tree_test-yaml_document_tree.$(OBJEXT) \ + yaml_document_tree_test-json_util.$(OBJEXT) \ + yaml_document_tree_test-yaml_document_tree_test.$(OBJEXT) +yaml_document_tree_test_OBJECTS = \ + $(am_yaml_document_tree_test_OBJECTS) +yaml_document_tree_test_DEPENDENCIES = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_2) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/common_test.Po \ + ./$(DEPDIR)/css_document_tree.Po \ + ./$(DEPDIR)/css_document_tree_test.Po \ + ./$(DEPDIR)/dom_tree_test.Po \ + ./$(DEPDIR)/gnumeric_cell_context.Po \ + ./$(DEPDIR)/gnumeric_cell_context_test.Po \ + ./$(DEPDIR)/gnumeric_namespace_types.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_cell_context.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_filter_context.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_names_context.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_namespace_types.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context_test.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_styles_context.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_tokens.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_types.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_value_format_parser.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-number_utils.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-odf_namespace_types.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-session_context.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-spreadsheet_interface.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-string_helper.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-xml_context_base.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-xml_element_types.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-xml_element_validator.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-xml_empty_context.Po \ + ./$(DEPDIR)/gnumeric_sheet_context_test-xml_util.Po \ + ./$(DEPDIR)/gnumeric_tokens.Po ./$(DEPDIR)/gnumeric_types.Po \ + ./$(DEPDIR)/gnumeric_value_format_parser.Po \ + ./$(DEPDIR)/json_document_tree_test-json_document_tree.Po \ + ./$(DEPDIR)/json_document_tree_test-json_document_tree_test.Po \ + ./$(DEPDIR)/json_document_tree_test-json_util.Po \ + ./$(DEPDIR)/json_map_tree.Po ./$(DEPDIR)/json_map_tree_test.Po \ + ./$(DEPDIR)/json_structure_tree_test.Po \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-config.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-css_document_tree.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-css_selector.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-detection_result.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-dom_tree.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-format_detection.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-formula_result.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_cell_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_detection_handler.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_filter_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_handler.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_names_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_namespace_types.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_sheet_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_styles_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_tokens.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_types.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_value_format_parser.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-info.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-interface.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_document_tree.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_map_tree.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_structure_mapper.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_structure_tree.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_util.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-measurement.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-number_utils.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_document_styles_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_helper.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_namespace_types.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_number_format_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_para_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_style_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_styles.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_styles_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_tokens.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_content_xml_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_dde_links_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_session_data.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_content_types.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_global.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_namespace_types.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_schemas.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_tokens.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_types.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-opc_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-opc_reader.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_csv.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_gnumeric.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_import_ods.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_import_xlsx.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_json.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_ods.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_parquet.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xls_xml.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xlsx.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml_impl.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml_map_def.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-session_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_iface_util.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_impl_types.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_interface.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_types.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-string_helper.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_detection_handler.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_handler.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_namespace_types.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_tokens.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_autofilter_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_conditional_format_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_drawing_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_handler.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_helper.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_pivot_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_revision_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_session_data.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_shared_strings_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_sheet_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_styles_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_table_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_types.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_workbook_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_context_base.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_context_global.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_element_types.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_element_validator.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_empty_context.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_map_tree.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_simple_stream_handler.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_stream_handler.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_stream_parser.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_structure_mapper.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_structure_tree.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_util.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xpath_parser.Plo \ + ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-yaml_document_tree.Plo \ + ./$(DEPDIR)/number_utils.Po \ + ./$(DEPDIR)/odf_helper_test-odf_helper.Po \ + ./$(DEPDIR)/odf_helper_test-odf_helper_test.Po \ + ./$(DEPDIR)/odf_helper_test-string_helper.Po \ + ./$(DEPDIR)/odf_namespace_types.Po \ + ./$(DEPDIR)/session_context.Po \ + ./$(DEPDIR)/spreadsheet_impl_types.Po \ + ./$(DEPDIR)/spreadsheet_interface.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-formula_result.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_global.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_namespace_types.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_schemas.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_tokens.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_types.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-session_context.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-spreadsheet_interface.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_autofilter_context.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_conditional_format_context.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_helper.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_session_data.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context_test.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_types.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-xml_context_base.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-xml_context_global.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-xml_element_types.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-xml_element_validator.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-xml_empty_context.Po \ + ./$(DEPDIR)/xlsx_sheet_context_test-xml_util.Po \ + ./$(DEPDIR)/xml_context_base.Po \ + ./$(DEPDIR)/xml_element_types.Po \ + ./$(DEPDIR)/xml_element_validator.Po \ + ./$(DEPDIR)/xml_empty_context.Po ./$(DEPDIR)/xml_map_tree.Po \ + ./$(DEPDIR)/xml_map_tree_test.Po \ + ./$(DEPDIR)/xml_structure_tree_test-string_helper.Po \ + ./$(DEPDIR)/xml_structure_tree_test-xml_structure_mapper.Po \ + ./$(DEPDIR)/xml_structure_tree_test-xml_structure_tree.Po \ + ./$(DEPDIR)/xml_structure_tree_test-xml_structure_tree_test.Po \ + ./$(DEPDIR)/xml_util.Po ./$(DEPDIR)/xpath_parser.Po \ + ./$(DEPDIR)/xpath_parser_test.Po \ + ./$(DEPDIR)/yaml_document_tree_test-json_util.Po \ + ./$(DEPDIR)/yaml_document_tree_test-yaml_document_tree.Po \ + ./$(DEPDIR)/yaml_document_tree_test-yaml_document_tree_test.Po +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(liborcus_@ORCUS_API_VERSION@_la_SOURCES) \ + $(common_test_SOURCES) $(css_document_tree_test_SOURCES) \ + $(dom_tree_test_SOURCES) $(gnumeric_cell_context_test_SOURCES) \ + $(gnumeric_sheet_context_test_SOURCES) \ + $(json_document_tree_test_SOURCES) \ + $(json_map_tree_test_SOURCES) \ + $(json_structure_tree_test_SOURCES) $(odf_helper_test_SOURCES) \ + $(xlsx_sheet_context_test_SOURCES) \ + $(xml_map_tree_test_SOURCES) \ + $(xml_structure_tree_test_SOURCES) \ + $(xpath_parser_test_SOURCES) \ + $(yaml_document_tree_test_SOURCES) +DIST_SOURCES = $(am__liborcus_@ORCUS_API_VERSION@_la_SOURCES_DIST) \ + $(common_test_SOURCES) $(css_document_tree_test_SOURCES) \ + $(dom_tree_test_SOURCES) \ + $(am__gnumeric_cell_context_test_SOURCES_DIST) \ + $(am__gnumeric_sheet_context_test_SOURCES_DIST) \ + $(json_document_tree_test_SOURCES) \ + $(json_map_tree_test_SOURCES) \ + $(json_structure_tree_test_SOURCES) \ + $(am__odf_helper_test_SOURCES_DIST) \ + $(am__xlsx_sheet_context_test_SOURCES_DIST) \ + $(xml_map_tree_test_SOURCES) \ + $(xml_structure_tree_test_SOURCES) \ + $(xpath_parser_test_SOURCES) \ + $(yaml_document_tree_test_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__extra_recursive_targets = check-valgrind-recursive \ + check-valgrind-memcheck-recursive \ + check-valgrind-helgrind-recursive check-valgrind-drd-recursive \ + check-valgrind-sgcheck-recursive +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/constants.inl.in \ + $(top_srcdir)/depcomp $(top_srcdir)/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ +BOOST_DATE_TIME_LDFLAGS = @BOOST_DATE_TIME_LDFLAGS@ +BOOST_DATE_TIME_LDPATH = @BOOST_DATE_TIME_LDPATH@ +BOOST_DATE_TIME_LIBS = @BOOST_DATE_TIME_LIBS@ +BOOST_FILESYSTEM_LDFLAGS = @BOOST_FILESYSTEM_LDFLAGS@ +BOOST_FILESYSTEM_LDPATH = @BOOST_FILESYSTEM_LDPATH@ +BOOST_FILESYSTEM_LIBS = @BOOST_FILESYSTEM_LIBS@ +BOOST_IOSTREAMS_LDFLAGS = @BOOST_IOSTREAMS_LDFLAGS@ +BOOST_IOSTREAMS_LDPATH = @BOOST_IOSTREAMS_LDPATH@ +BOOST_IOSTREAMS_LIBS = @BOOST_IOSTREAMS_LIBS@ +BOOST_LDPATH = @BOOST_LDPATH@ +BOOST_PROGRAM_OPTIONS_LDFLAGS = @BOOST_PROGRAM_OPTIONS_LDFLAGS@ +BOOST_PROGRAM_OPTIONS_LDPATH = @BOOST_PROGRAM_OPTIONS_LDPATH@ +BOOST_PROGRAM_OPTIONS_LIBS = @BOOST_PROGRAM_OPTIONS_LIBS@ +BOOST_ROOT = @BOOST_ROOT@ +BOOST_SYSTEM_LDFLAGS = @BOOST_SYSTEM_LDFLAGS@ +BOOST_SYSTEM_LDPATH = @BOOST_SYSTEM_LDPATH@ +BOOST_SYSTEM_LIBS = @BOOST_SYSTEM_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_VALGRIND_drd = @ENABLE_VALGRIND_drd@ +ENABLE_VALGRIND_helgrind = @ENABLE_VALGRIND_helgrind@ +ENABLE_VALGRIND_memcheck = @ENABLE_VALGRIND_memcheck@ +ENABLE_VALGRIND_sgcheck = @ENABLE_VALGRIND_sgcheck@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_CXX17 = @HAVE_CXX17@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IXION_REQUIRED_API_VERSION = @IXION_REQUIRED_API_VERSION@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBIXION_CFLAGS = @LIBIXION_CFLAGS@ +LIBIXION_LIBS = @LIBIXION_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MDDS_CFLAGS = @MDDS_CFLAGS@ +MDDS_LIBS = @MDDS_LIBS@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ORCUS_API_VERSION = @ORCUS_API_VERSION@ +ORCUS_MAJOR_VERSION = @ORCUS_MAJOR_VERSION@ +ORCUS_MICRO_VERSION = @ORCUS_MICRO_VERSION@ +ORCUS_MINOR_VERSION = @ORCUS_MINOR_VERSION@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PARQUET_CFLAGS = @PARQUET_CFLAGS@ +PARQUET_LIBS = @PARQUET_LIBS@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POW_LIB = @POW_LIB@ +PYTHON = @PYTHON@ +PYTHON_CFLAGS = @PYTHON_CFLAGS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_LIBS = @PYTHON_LIBS@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VALGRIND = @VALGRIND@ +VALGRIND_ENABLED = @VALGRIND_ENABLED@ +VERSION = @VERSION@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +valgrind_enabled_tools = @valgrind_enabled_tools@ +valgrind_tools = @valgrind_tools@ +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src/include \ + -I./include $(BOOST_CPPFLAGS) $(am__append_1) $(am__append_2) \ + $(am__append_3) $(am__append_4) -DSRCDIR=\""$(top_srcdir)"\" +EXTRA_DIST = \ + xml_element_types.hpp + +liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS = $(ZLIB_CFLAGS) \ + $(am__append_21) +liborcus_@ORCUS_API_VERSION@_la_LDFLAGS = -no-undefined \ + $(BOOST_SYSTEM_LDFLAGS) $(am__append_5) $(am__append_6) \ + $(am__append_16) $(am__append_22) +liborcus_@ORCUS_API_VERSION@_la_LIBADD = \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(BOOST_SYSTEM_LIBS) $(ZLIB_LIBS) $(am__append_7) \ + $(am__append_17) $(am__append_23) +lib_LTLIBRARIES = liborcus-@ORCUS_API_VERSION@.la +liborcus_@ORCUS_API_VERSION@_la_SOURCES = config.cpp \ + css_document_tree.cpp css_selector.cpp detection_result.hpp \ + detection_result.cpp dom_tree.cpp format_detection.cpp \ + formula_result.hpp formula_result.cpp impl_utils.hpp info.cpp \ + interface.cpp json_document_tree.cpp json_map_tree.hpp \ + json_map_tree.cpp json_structure_mapper.hpp \ + json_structure_mapper.cpp json_structure_tree.cpp \ + json_util.hpp json_util.cpp spreadsheet_interface.cpp \ + orcus_csv.cpp orcus_json.cpp orcus_xml.cpp orcus_xml_impl.hpp \ + orcus_xml_impl.cpp orcus_xml_map_def.cpp measurement.cpp \ + number_utils.cpp number_utils.hpp xml_context_base.hpp \ + xml_context_base.cpp xml_context_global.hpp \ + xml_context_global.cpp xml_element_types.cpp \ + xml_element_validator.hpp xml_element_validator.cpp \ + xml_empty_context.hpp xml_empty_context.cpp xml_map_tree.hpp \ + xml_map_tree.cpp xml_stream_handler.hpp xml_stream_handler.cpp \ + xml_stream_parser.hpp xml_stream_parser.cpp \ + xml_simple_stream_handler.hpp xml_simple_stream_handler.cpp \ + xml_structure_mapper.hpp xml_structure_mapper.cpp \ + xml_structure_tree.cpp xml_util.hpp xml_util.cpp \ + xpath_parser.cpp yaml_document_tree.cpp \ + ooxml_namespace_types.cpp ooxml_namespace_types.hpp \ + odf_namespace_types.hpp odf_namespace_types_hpp.inl \ + odf_namespace_types.cpp odf_namespace_types_cpp.inl \ + gnumeric_namespace_types.hpp gnumeric_namespace_types.cpp \ + xls_xml_namespace_types.hpp xls_xml_namespace_types.cpp \ + session_context.hpp session_context.cpp \ + spreadsheet_impl_types.hpp spreadsheet_impl_types.cpp \ + spreadsheet_types.cpp spreadsheet_iface_util.hpp \ + spreadsheet_iface_util.cpp string_helper.hpp string_helper.cpp \ + $(am__append_9) $(am__append_11) $(am__append_12) \ + $(am__append_15) $(am__append_20) + +# xlsx-sheet-context-test +@WITH_XLSX_FILTER_TRUE@xlsx_sheet_context_test_SOURCES = \ +@WITH_XLSX_FILTER_TRUE@ formula_result.cpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_global.cpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_namespace_types.cpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_schemas.cpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_tokens.cpp \ +@WITH_XLSX_FILTER_TRUE@ ooxml_types.cpp \ +@WITH_XLSX_FILTER_TRUE@ session_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ spreadsheet_interface.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_autofilter_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_conditional_format_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_helper.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_session_data.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_sheet_context_test.cpp \ +@WITH_XLSX_FILTER_TRUE@ xlsx_types.cpp \ +@WITH_XLSX_FILTER_TRUE@ xml_context_base.cpp \ +@WITH_XLSX_FILTER_TRUE@ xml_context_global.cpp \ +@WITH_XLSX_FILTER_TRUE@ xml_element_types.cpp \ +@WITH_XLSX_FILTER_TRUE@ xml_element_validator.cpp \ +@WITH_XLSX_FILTER_TRUE@ xml_empty_context.cpp \ +@WITH_XLSX_FILTER_TRUE@ xml_util.cpp + +@WITH_XLSX_FILTER_TRUE@xlsx_sheet_context_test_LDADD = \ +@WITH_XLSX_FILTER_TRUE@ liborcus-@ORCUS_API_VERSION@.la \ +@WITH_XLSX_FILTER_TRUE@ ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ +@WITH_XLSX_FILTER_TRUE@ ../test/liborcus-test.a + +@WITH_XLSX_FILTER_TRUE@xlsx_sheet_context_test_CPPFLAGS = -I$(top_builddir)/lib/liborcus/liborcus.la $(AM_CPPFLAGS) +@WITH_ODS_FILTER_TRUE@odf_helper_test_SOURCES = \ +@WITH_ODS_FILTER_TRUE@ odf_helper.cpp \ +@WITH_ODS_FILTER_TRUE@ string_helper.cpp \ +@WITH_ODS_FILTER_TRUE@ odf_helper_test.cpp + +@WITH_ODS_FILTER_TRUE@odf_helper_test_LDADD = \ +@WITH_ODS_FILTER_TRUE@ liborcus-@ORCUS_API_VERSION@.la \ +@WITH_ODS_FILTER_TRUE@ ../parser/liborcus-parser-@ORCUS_API_VERSION@.la + +@WITH_ODS_FILTER_TRUE@odf_helper_test_CPPFLAGS = -I$(top_builddir)/lib/liborcus/liborcus.la $(AM_CPPFLAGS) +@WITH_GNUMERIC_FILTER_TRUE@gnumeric_cell_context_test_SOURCES = \ +@WITH_GNUMERIC_FILTER_TRUE@ number_utils.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ session_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_cell_context_test.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_cell_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_value_format_parser.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_context_base.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_element_types.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_element_validator.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_empty_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_util.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_namespace_types.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_tokens.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_types.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ odf_namespace_types.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ spreadsheet_interface.cpp + +@WITH_GNUMERIC_FILTER_TRUE@gnumeric_cell_context_test_LDADD = \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus-@ORCUS_API_VERSION@.la \ +@WITH_GNUMERIC_FILTER_TRUE@ ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ +@WITH_GNUMERIC_FILTER_TRUE@ ../test/liborcus-test.a + +@WITH_GNUMERIC_FILTER_TRUE@orcus_gnumeric_cell_context_test_CPPFLAGS = -I$(top_builddir)/lib/liborcus/liborcus.la $(AM_CPPFLAGS) + +# gnumeric-sheet-context-test +@WITH_GNUMERIC_FILTER_TRUE@gnumeric_sheet_context_test_SOURCES = \ +@WITH_GNUMERIC_FILTER_TRUE@ session_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context_test.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_sheet_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_names_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_cell_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_filter_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_styles_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_value_format_parser.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_types.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ number_utils.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_context_base.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_element_types.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_element_validator.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_empty_context.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ xml_util.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_namespace_types.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ gnumeric_tokens.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ odf_namespace_types.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ spreadsheet_interface.cpp \ +@WITH_GNUMERIC_FILTER_TRUE@ string_helper.cpp + +@WITH_GNUMERIC_FILTER_TRUE@gnumeric_sheet_context_test_LDADD = \ +@WITH_GNUMERIC_FILTER_TRUE@ liborcus-@ORCUS_API_VERSION@.la \ +@WITH_GNUMERIC_FILTER_TRUE@ ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ +@WITH_GNUMERIC_FILTER_TRUE@ ../test/liborcus-test.a + +@WITH_GNUMERIC_FILTER_TRUE@gnumeric_sheet_context_test_CPPFLAGS = -I$(top_builddir)/lib/liborcus/liborcus.la $(AM_CPPFLAGS) + +# css-document-tree-test +css_document_tree_test_SOURCES = \ + css_document_tree.cpp \ + css_document_tree_test.cpp + +css_document_tree_test_LDADD = liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(BOOST_SYSTEM_LIBS) $(am__append_24) $(am__append_25) + +# json-document-tree-test +json_document_tree_test_SOURCES = \ + json_document_tree.cpp \ + json_util.cpp \ + json_document_tree_test.cpp + +json_document_tree_test_LDADD = liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + ../test/liborcus-test.a $(BOOST_SYSTEM_LIBS) $(am__append_26) \ + $(am__append_27) +json_document_tree_test_CPPFLAGS = -I$(top_builddir)/lib/liborcus/liborcus.la $(AM_CPPFLAGS) + +# yaml-document-tree-test +yaml_document_tree_test_SOURCES = \ + yaml_document_tree.cpp \ + json_util.cpp \ + yaml_document_tree_test.cpp + +yaml_document_tree_test_LDADD = liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(BOOST_SYSTEM_LIBS) $(am__append_28) $(am__append_29) +yaml_document_tree_test_CPPFLAGS = -I$(top_builddir)/lib/liborcus/liborcus.la $(AM_CPPFLAGS) + +# xml-map-tree-test +xml_map_tree_test_SOURCES = \ + xml_map_tree.cpp \ + xml_map_tree.hpp \ + xpath_parser.hpp \ + xpath_parser.cpp \ + spreadsheet_impl_types.hpp \ + spreadsheet_impl_types.cpp \ + xml_map_tree_test.cpp + +xml_map_tree_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + ../test/liborcus-test.a \ + $(BOOST_SYSTEM_LIBS) + + +# xml-structure-tree-test +xml_structure_tree_test_SOURCES = \ + string_helper.cpp \ + xml_structure_tree.cpp \ + xml_structure_mapper.cpp \ + xml_structure_tree_test.cpp + +xml_structure_tree_test_CPPFLAGS = -I$(top_builddir)/lib/liborcus/liborcus.la $(AM_CPPFLAGS) +xml_structure_tree_test_LDADD = liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(BOOST_SYSTEM_LIBS) $(am__append_30) $(am__append_31) + +# common-test +common_test_SOURCES = \ + common_test.cpp + +common_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la + + +# dom-tree-test +dom_tree_test_SOURCES = dom_tree_test.cpp +dom_tree_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la + + +# json-structure-tree-test +json_structure_tree_test_SOURCES = json_structure_tree_test.cpp +json_structure_tree_test_LDADD = liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(BOOST_SYSTEM_LIBS) $(am__append_32) $(am__append_33) + +# json-map-tree-test +json_map_tree_test_SOURCES = json_map_tree_test.cpp \ + json_map_tree.cpp \ + spreadsheet_impl_types.cpp + +json_map_tree_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(BOOST_SYSTEM_LIBS) + + +# xpath-parser-test +xpath_parser_test_SOURCES = \ + xpath_parser_test.cpp \ + xpath_parser.cpp + +xpath_parser_test_LDADD = \ + liborcus-@ORCUS_API_VERSION@.la \ + ../parser/liborcus-parser-@ORCUS_API_VERSION@.la \ + $(BOOST_SYSTEM_LIBS) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .log .o .obj .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/liborcus/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/liborcus/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +constants.inl: $(top_builddir)/config.status $(srcdir)/constants.inl.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +liborcus-@ORCUS_API_VERSION@.la: $(liborcus_@ORCUS_API_VERSION@_la_OBJECTS) $(liborcus_@ORCUS_API_VERSION@_la_DEPENDENCIES) $(EXTRA_liborcus_@ORCUS_API_VERSION@_la_DEPENDENCIES) + $(AM_V_CXXLD)$(liborcus_@ORCUS_API_VERSION@_la_LINK) -rpath $(libdir) $(liborcus_@ORCUS_API_VERSION@_la_OBJECTS) $(liborcus_@ORCUS_API_VERSION@_la_LIBADD) $(LIBS) + +common-test$(EXEEXT): $(common_test_OBJECTS) $(common_test_DEPENDENCIES) $(EXTRA_common_test_DEPENDENCIES) + @rm -f common-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(common_test_OBJECTS) $(common_test_LDADD) $(LIBS) + +css-document-tree-test$(EXEEXT): $(css_document_tree_test_OBJECTS) $(css_document_tree_test_DEPENDENCIES) $(EXTRA_css_document_tree_test_DEPENDENCIES) + @rm -f css-document-tree-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(css_document_tree_test_OBJECTS) $(css_document_tree_test_LDADD) $(LIBS) + +dom-tree-test$(EXEEXT): $(dom_tree_test_OBJECTS) $(dom_tree_test_DEPENDENCIES) $(EXTRA_dom_tree_test_DEPENDENCIES) + @rm -f dom-tree-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(dom_tree_test_OBJECTS) $(dom_tree_test_LDADD) $(LIBS) + +gnumeric-cell-context-test$(EXEEXT): $(gnumeric_cell_context_test_OBJECTS) $(gnumeric_cell_context_test_DEPENDENCIES) $(EXTRA_gnumeric_cell_context_test_DEPENDENCIES) + @rm -f gnumeric-cell-context-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(gnumeric_cell_context_test_OBJECTS) $(gnumeric_cell_context_test_LDADD) $(LIBS) + +gnumeric-sheet-context-test$(EXEEXT): $(gnumeric_sheet_context_test_OBJECTS) $(gnumeric_sheet_context_test_DEPENDENCIES) $(EXTRA_gnumeric_sheet_context_test_DEPENDENCIES) + @rm -f gnumeric-sheet-context-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(gnumeric_sheet_context_test_OBJECTS) $(gnumeric_sheet_context_test_LDADD) $(LIBS) + +json-document-tree-test$(EXEEXT): $(json_document_tree_test_OBJECTS) $(json_document_tree_test_DEPENDENCIES) $(EXTRA_json_document_tree_test_DEPENDENCIES) + @rm -f json-document-tree-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(json_document_tree_test_OBJECTS) $(json_document_tree_test_LDADD) $(LIBS) + +json-map-tree-test$(EXEEXT): $(json_map_tree_test_OBJECTS) $(json_map_tree_test_DEPENDENCIES) $(EXTRA_json_map_tree_test_DEPENDENCIES) + @rm -f json-map-tree-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(json_map_tree_test_OBJECTS) $(json_map_tree_test_LDADD) $(LIBS) + +json-structure-tree-test$(EXEEXT): $(json_structure_tree_test_OBJECTS) $(json_structure_tree_test_DEPENDENCIES) $(EXTRA_json_structure_tree_test_DEPENDENCIES) + @rm -f json-structure-tree-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(json_structure_tree_test_OBJECTS) $(json_structure_tree_test_LDADD) $(LIBS) + +odf-helper-test$(EXEEXT): $(odf_helper_test_OBJECTS) $(odf_helper_test_DEPENDENCIES) $(EXTRA_odf_helper_test_DEPENDENCIES) + @rm -f odf-helper-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(odf_helper_test_OBJECTS) $(odf_helper_test_LDADD) $(LIBS) + +xlsx-sheet-context-test$(EXEEXT): $(xlsx_sheet_context_test_OBJECTS) $(xlsx_sheet_context_test_DEPENDENCIES) $(EXTRA_xlsx_sheet_context_test_DEPENDENCIES) + @rm -f xlsx-sheet-context-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(xlsx_sheet_context_test_OBJECTS) $(xlsx_sheet_context_test_LDADD) $(LIBS) + +xml-map-tree-test$(EXEEXT): $(xml_map_tree_test_OBJECTS) $(xml_map_tree_test_DEPENDENCIES) $(EXTRA_xml_map_tree_test_DEPENDENCIES) + @rm -f xml-map-tree-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(xml_map_tree_test_OBJECTS) $(xml_map_tree_test_LDADD) $(LIBS) + +xml-structure-tree-test$(EXEEXT): $(xml_structure_tree_test_OBJECTS) $(xml_structure_tree_test_DEPENDENCIES) $(EXTRA_xml_structure_tree_test_DEPENDENCIES) + @rm -f xml-structure-tree-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(xml_structure_tree_test_OBJECTS) $(xml_structure_tree_test_LDADD) $(LIBS) + +xpath-parser-test$(EXEEXT): $(xpath_parser_test_OBJECTS) $(xpath_parser_test_DEPENDENCIES) $(EXTRA_xpath_parser_test_DEPENDENCIES) + @rm -f xpath-parser-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(xpath_parser_test_OBJECTS) $(xpath_parser_test_LDADD) $(LIBS) + +yaml-document-tree-test$(EXEEXT): $(yaml_document_tree_test_OBJECTS) $(yaml_document_tree_test_DEPENDENCIES) $(EXTRA_yaml_document_tree_test_DEPENDENCIES) + @rm -f yaml-document-tree-test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(yaml_document_tree_test_OBJECTS) $(yaml_document_tree_test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/css_document_tree.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/css_document_tree_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dom_tree_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_cell_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_cell_context_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_namespace_types.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_cell_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_filter_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_names_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_namespace_types.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_styles_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_tokens.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_types.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_value_format_parser.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-number_utils.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-odf_namespace_types.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-session_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-spreadsheet_interface.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-string_helper.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-xml_context_base.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-xml_element_types.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-xml_element_validator.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-xml_empty_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_sheet_context_test-xml_util.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_tokens.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_types.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnumeric_value_format_parser.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json_document_tree_test-json_document_tree.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json_document_tree_test-json_document_tree_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json_document_tree_test-json_util.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json_map_tree.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json_map_tree_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json_structure_tree_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-config.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-css_document_tree.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-css_selector.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-detection_result.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-dom_tree.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-format_detection.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-formula_result.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_cell_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_detection_handler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_filter_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_handler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_names_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_namespace_types.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_sheet_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_styles_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_tokens.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_types.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_value_format_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-info.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-interface.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_document_tree.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_map_tree.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_structure_mapper.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_structure_tree.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-measurement.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-number_utils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_document_styles_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_helper.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_namespace_types.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_number_format_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_para_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_style_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_styles.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_styles_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_tokens.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_content_xml_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_dde_links_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_session_data.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_content_types.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_global.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_namespace_types.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_schemas.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_tokens.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_types.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-opc_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-opc_reader.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_csv.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_gnumeric.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_import_ods.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_import_xlsx.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_json.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_ods.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_parquet.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xls_xml.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xlsx.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml_impl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml_map_def.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-session_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_iface_util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_impl_types.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_interface.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_types.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-string_helper.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_detection_handler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_handler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_namespace_types.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_tokens.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_autofilter_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_conditional_format_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_drawing_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_handler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_helper.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_pivot_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_revision_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_session_data.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_shared_strings_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_sheet_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_styles_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_table_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_types.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_workbook_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_context_base.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_context_global.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_element_types.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_element_validator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_empty_context.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_map_tree.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_simple_stream_handler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_stream_handler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_stream_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_structure_mapper.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_structure_tree.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_util.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xpath_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-yaml_document_tree.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/number_utils.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odf_helper_test-odf_helper.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odf_helper_test-odf_helper_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odf_helper_test-string_helper.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odf_namespace_types.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spreadsheet_impl_types.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spreadsheet_interface.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-formula_result.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-ooxml_global.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-ooxml_namespace_types.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-ooxml_schemas.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-ooxml_tokens.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-ooxml_types.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-session_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-spreadsheet_interface.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-xlsx_autofilter_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-xlsx_conditional_format_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-xlsx_helper.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-xlsx_session_data.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-xlsx_types.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-xml_context_base.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-xml_context_global.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-xml_element_types.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-xml_element_validator.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-xml_empty_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xlsx_sheet_context_test-xml_util.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_context_base.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_element_types.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_element_validator.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_empty_context.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_map_tree.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_map_tree_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_structure_tree_test-string_helper.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_structure_tree_test-xml_structure_mapper.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_structure_tree_test-xml_structure_tree.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_structure_tree_test-xml_structure_tree_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_util.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xpath_parser.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xpath_parser_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yaml_document_tree_test-json_util.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yaml_document_tree_test-yaml_document_tree.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yaml_document_tree_test-yaml_document_tree_test.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cpp.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +liborcus_@ORCUS_API_VERSION@_la-config.lo: config.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-config.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-config.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-config.lo `test -f 'config.cpp' || echo '$(srcdir)/'`config.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-config.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-config.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='config.cpp' object='liborcus_@ORCUS_API_VERSION@_la-config.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-config.lo `test -f 'config.cpp' || echo '$(srcdir)/'`config.cpp + +liborcus_@ORCUS_API_VERSION@_la-css_document_tree.lo: css_document_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-css_document_tree.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-css_document_tree.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-css_document_tree.lo `test -f 'css_document_tree.cpp' || echo '$(srcdir)/'`css_document_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-css_document_tree.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-css_document_tree.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='css_document_tree.cpp' object='liborcus_@ORCUS_API_VERSION@_la-css_document_tree.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-css_document_tree.lo `test -f 'css_document_tree.cpp' || echo '$(srcdir)/'`css_document_tree.cpp + +liborcus_@ORCUS_API_VERSION@_la-css_selector.lo: css_selector.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-css_selector.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-css_selector.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-css_selector.lo `test -f 'css_selector.cpp' || echo '$(srcdir)/'`css_selector.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-css_selector.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-css_selector.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='css_selector.cpp' object='liborcus_@ORCUS_API_VERSION@_la-css_selector.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-css_selector.lo `test -f 'css_selector.cpp' || echo '$(srcdir)/'`css_selector.cpp + +liborcus_@ORCUS_API_VERSION@_la-detection_result.lo: detection_result.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-detection_result.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-detection_result.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-detection_result.lo `test -f 'detection_result.cpp' || echo '$(srcdir)/'`detection_result.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-detection_result.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-detection_result.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='detection_result.cpp' object='liborcus_@ORCUS_API_VERSION@_la-detection_result.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-detection_result.lo `test -f 'detection_result.cpp' || echo '$(srcdir)/'`detection_result.cpp + +liborcus_@ORCUS_API_VERSION@_la-dom_tree.lo: dom_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-dom_tree.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-dom_tree.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-dom_tree.lo `test -f 'dom_tree.cpp' || echo '$(srcdir)/'`dom_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-dom_tree.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-dom_tree.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dom_tree.cpp' object='liborcus_@ORCUS_API_VERSION@_la-dom_tree.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-dom_tree.lo `test -f 'dom_tree.cpp' || echo '$(srcdir)/'`dom_tree.cpp + +liborcus_@ORCUS_API_VERSION@_la-format_detection.lo: format_detection.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-format_detection.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-format_detection.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-format_detection.lo `test -f 'format_detection.cpp' || echo '$(srcdir)/'`format_detection.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-format_detection.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-format_detection.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='format_detection.cpp' object='liborcus_@ORCUS_API_VERSION@_la-format_detection.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-format_detection.lo `test -f 'format_detection.cpp' || echo '$(srcdir)/'`format_detection.cpp + +liborcus_@ORCUS_API_VERSION@_la-formula_result.lo: formula_result.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-formula_result.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-formula_result.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-formula_result.lo `test -f 'formula_result.cpp' || echo '$(srcdir)/'`formula_result.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-formula_result.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-formula_result.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='formula_result.cpp' object='liborcus_@ORCUS_API_VERSION@_la-formula_result.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-formula_result.lo `test -f 'formula_result.cpp' || echo '$(srcdir)/'`formula_result.cpp + +liborcus_@ORCUS_API_VERSION@_la-info.lo: info.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-info.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-info.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-info.lo `test -f 'info.cpp' || echo '$(srcdir)/'`info.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-info.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-info.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='info.cpp' object='liborcus_@ORCUS_API_VERSION@_la-info.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-info.lo `test -f 'info.cpp' || echo '$(srcdir)/'`info.cpp + +liborcus_@ORCUS_API_VERSION@_la-interface.lo: interface.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-interface.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-interface.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-interface.lo `test -f 'interface.cpp' || echo '$(srcdir)/'`interface.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-interface.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-interface.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='interface.cpp' object='liborcus_@ORCUS_API_VERSION@_la-interface.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-interface.lo `test -f 'interface.cpp' || echo '$(srcdir)/'`interface.cpp + +liborcus_@ORCUS_API_VERSION@_la-json_document_tree.lo: json_document_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-json_document_tree.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_document_tree.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-json_document_tree.lo `test -f 'json_document_tree.cpp' || echo '$(srcdir)/'`json_document_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_document_tree.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_document_tree.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='json_document_tree.cpp' object='liborcus_@ORCUS_API_VERSION@_la-json_document_tree.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-json_document_tree.lo `test -f 'json_document_tree.cpp' || echo '$(srcdir)/'`json_document_tree.cpp + +liborcus_@ORCUS_API_VERSION@_la-json_map_tree.lo: json_map_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-json_map_tree.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_map_tree.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-json_map_tree.lo `test -f 'json_map_tree.cpp' || echo '$(srcdir)/'`json_map_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_map_tree.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_map_tree.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='json_map_tree.cpp' object='liborcus_@ORCUS_API_VERSION@_la-json_map_tree.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-json_map_tree.lo `test -f 'json_map_tree.cpp' || echo '$(srcdir)/'`json_map_tree.cpp + +liborcus_@ORCUS_API_VERSION@_la-json_structure_mapper.lo: json_structure_mapper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-json_structure_mapper.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_structure_mapper.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-json_structure_mapper.lo `test -f 'json_structure_mapper.cpp' || echo '$(srcdir)/'`json_structure_mapper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_structure_mapper.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_structure_mapper.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='json_structure_mapper.cpp' object='liborcus_@ORCUS_API_VERSION@_la-json_structure_mapper.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-json_structure_mapper.lo `test -f 'json_structure_mapper.cpp' || echo '$(srcdir)/'`json_structure_mapper.cpp + +liborcus_@ORCUS_API_VERSION@_la-json_structure_tree.lo: json_structure_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-json_structure_tree.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_structure_tree.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-json_structure_tree.lo `test -f 'json_structure_tree.cpp' || echo '$(srcdir)/'`json_structure_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_structure_tree.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_structure_tree.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='json_structure_tree.cpp' object='liborcus_@ORCUS_API_VERSION@_la-json_structure_tree.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-json_structure_tree.lo `test -f 'json_structure_tree.cpp' || echo '$(srcdir)/'`json_structure_tree.cpp + +liborcus_@ORCUS_API_VERSION@_la-json_util.lo: json_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-json_util.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_util.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-json_util.lo `test -f 'json_util.cpp' || echo '$(srcdir)/'`json_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_util.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_util.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='json_util.cpp' object='liborcus_@ORCUS_API_VERSION@_la-json_util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-json_util.lo `test -f 'json_util.cpp' || echo '$(srcdir)/'`json_util.cpp + +liborcus_@ORCUS_API_VERSION@_la-spreadsheet_interface.lo: spreadsheet_interface.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-spreadsheet_interface.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_interface.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-spreadsheet_interface.lo `test -f 'spreadsheet_interface.cpp' || echo '$(srcdir)/'`spreadsheet_interface.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_interface.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_interface.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='spreadsheet_interface.cpp' object='liborcus_@ORCUS_API_VERSION@_la-spreadsheet_interface.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-spreadsheet_interface.lo `test -f 'spreadsheet_interface.cpp' || echo '$(srcdir)/'`spreadsheet_interface.cpp + +liborcus_@ORCUS_API_VERSION@_la-orcus_csv.lo: orcus_csv.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-orcus_csv.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_csv.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_csv.lo `test -f 'orcus_csv.cpp' || echo '$(srcdir)/'`orcus_csv.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_csv.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_csv.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='orcus_csv.cpp' object='liborcus_@ORCUS_API_VERSION@_la-orcus_csv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_csv.lo `test -f 'orcus_csv.cpp' || echo '$(srcdir)/'`orcus_csv.cpp + +liborcus_@ORCUS_API_VERSION@_la-orcus_json.lo: orcus_json.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-orcus_json.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_json.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_json.lo `test -f 'orcus_json.cpp' || echo '$(srcdir)/'`orcus_json.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_json.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_json.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='orcus_json.cpp' object='liborcus_@ORCUS_API_VERSION@_la-orcus_json.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_json.lo `test -f 'orcus_json.cpp' || echo '$(srcdir)/'`orcus_json.cpp + +liborcus_@ORCUS_API_VERSION@_la-orcus_xml.lo: orcus_xml.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-orcus_xml.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_xml.lo `test -f 'orcus_xml.cpp' || echo '$(srcdir)/'`orcus_xml.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='orcus_xml.cpp' object='liborcus_@ORCUS_API_VERSION@_la-orcus_xml.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_xml.lo `test -f 'orcus_xml.cpp' || echo '$(srcdir)/'`orcus_xml.cpp + +liborcus_@ORCUS_API_VERSION@_la-orcus_xml_impl.lo: orcus_xml_impl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-orcus_xml_impl.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml_impl.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_xml_impl.lo `test -f 'orcus_xml_impl.cpp' || echo '$(srcdir)/'`orcus_xml_impl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml_impl.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml_impl.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='orcus_xml_impl.cpp' object='liborcus_@ORCUS_API_VERSION@_la-orcus_xml_impl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_xml_impl.lo `test -f 'orcus_xml_impl.cpp' || echo '$(srcdir)/'`orcus_xml_impl.cpp + +liborcus_@ORCUS_API_VERSION@_la-orcus_xml_map_def.lo: orcus_xml_map_def.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-orcus_xml_map_def.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml_map_def.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_xml_map_def.lo `test -f 'orcus_xml_map_def.cpp' || echo '$(srcdir)/'`orcus_xml_map_def.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml_map_def.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml_map_def.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='orcus_xml_map_def.cpp' object='liborcus_@ORCUS_API_VERSION@_la-orcus_xml_map_def.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_xml_map_def.lo `test -f 'orcus_xml_map_def.cpp' || echo '$(srcdir)/'`orcus_xml_map_def.cpp + +liborcus_@ORCUS_API_VERSION@_la-measurement.lo: measurement.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-measurement.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-measurement.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-measurement.lo `test -f 'measurement.cpp' || echo '$(srcdir)/'`measurement.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-measurement.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-measurement.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='measurement.cpp' object='liborcus_@ORCUS_API_VERSION@_la-measurement.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-measurement.lo `test -f 'measurement.cpp' || echo '$(srcdir)/'`measurement.cpp + +liborcus_@ORCUS_API_VERSION@_la-number_utils.lo: number_utils.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-number_utils.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-number_utils.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-number_utils.lo `test -f 'number_utils.cpp' || echo '$(srcdir)/'`number_utils.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-number_utils.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-number_utils.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='number_utils.cpp' object='liborcus_@ORCUS_API_VERSION@_la-number_utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-number_utils.lo `test -f 'number_utils.cpp' || echo '$(srcdir)/'`number_utils.cpp + +liborcus_@ORCUS_API_VERSION@_la-xml_context_base.lo: xml_context_base.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xml_context_base.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_context_base.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xml_context_base.lo `test -f 'xml_context_base.cpp' || echo '$(srcdir)/'`xml_context_base.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_context_base.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_context_base.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_context_base.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xml_context_base.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xml_context_base.lo `test -f 'xml_context_base.cpp' || echo '$(srcdir)/'`xml_context_base.cpp + +liborcus_@ORCUS_API_VERSION@_la-xml_context_global.lo: xml_context_global.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xml_context_global.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_context_global.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xml_context_global.lo `test -f 'xml_context_global.cpp' || echo '$(srcdir)/'`xml_context_global.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_context_global.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_context_global.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_context_global.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xml_context_global.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xml_context_global.lo `test -f 'xml_context_global.cpp' || echo '$(srcdir)/'`xml_context_global.cpp + +liborcus_@ORCUS_API_VERSION@_la-xml_element_types.lo: xml_element_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xml_element_types.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_element_types.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xml_element_types.lo `test -f 'xml_element_types.cpp' || echo '$(srcdir)/'`xml_element_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_element_types.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_element_types.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_element_types.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xml_element_types.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xml_element_types.lo `test -f 'xml_element_types.cpp' || echo '$(srcdir)/'`xml_element_types.cpp + +liborcus_@ORCUS_API_VERSION@_la-xml_element_validator.lo: xml_element_validator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xml_element_validator.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_element_validator.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xml_element_validator.lo `test -f 'xml_element_validator.cpp' || echo '$(srcdir)/'`xml_element_validator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_element_validator.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_element_validator.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_element_validator.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xml_element_validator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xml_element_validator.lo `test -f 'xml_element_validator.cpp' || echo '$(srcdir)/'`xml_element_validator.cpp + +liborcus_@ORCUS_API_VERSION@_la-xml_empty_context.lo: xml_empty_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xml_empty_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_empty_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xml_empty_context.lo `test -f 'xml_empty_context.cpp' || echo '$(srcdir)/'`xml_empty_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_empty_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_empty_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_empty_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xml_empty_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xml_empty_context.lo `test -f 'xml_empty_context.cpp' || echo '$(srcdir)/'`xml_empty_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-xml_map_tree.lo: xml_map_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xml_map_tree.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_map_tree.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xml_map_tree.lo `test -f 'xml_map_tree.cpp' || echo '$(srcdir)/'`xml_map_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_map_tree.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_map_tree.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_map_tree.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xml_map_tree.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xml_map_tree.lo `test -f 'xml_map_tree.cpp' || echo '$(srcdir)/'`xml_map_tree.cpp + +liborcus_@ORCUS_API_VERSION@_la-xml_stream_handler.lo: xml_stream_handler.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xml_stream_handler.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_stream_handler.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xml_stream_handler.lo `test -f 'xml_stream_handler.cpp' || echo '$(srcdir)/'`xml_stream_handler.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_stream_handler.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_stream_handler.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_stream_handler.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xml_stream_handler.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xml_stream_handler.lo `test -f 'xml_stream_handler.cpp' || echo '$(srcdir)/'`xml_stream_handler.cpp + +liborcus_@ORCUS_API_VERSION@_la-xml_stream_parser.lo: xml_stream_parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xml_stream_parser.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_stream_parser.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xml_stream_parser.lo `test -f 'xml_stream_parser.cpp' || echo '$(srcdir)/'`xml_stream_parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_stream_parser.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_stream_parser.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_stream_parser.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xml_stream_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xml_stream_parser.lo `test -f 'xml_stream_parser.cpp' || echo '$(srcdir)/'`xml_stream_parser.cpp + +liborcus_@ORCUS_API_VERSION@_la-xml_simple_stream_handler.lo: xml_simple_stream_handler.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xml_simple_stream_handler.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_simple_stream_handler.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xml_simple_stream_handler.lo `test -f 'xml_simple_stream_handler.cpp' || echo '$(srcdir)/'`xml_simple_stream_handler.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_simple_stream_handler.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_simple_stream_handler.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_simple_stream_handler.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xml_simple_stream_handler.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xml_simple_stream_handler.lo `test -f 'xml_simple_stream_handler.cpp' || echo '$(srcdir)/'`xml_simple_stream_handler.cpp + +liborcus_@ORCUS_API_VERSION@_la-xml_structure_mapper.lo: xml_structure_mapper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xml_structure_mapper.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_structure_mapper.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xml_structure_mapper.lo `test -f 'xml_structure_mapper.cpp' || echo '$(srcdir)/'`xml_structure_mapper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_structure_mapper.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_structure_mapper.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_structure_mapper.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xml_structure_mapper.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xml_structure_mapper.lo `test -f 'xml_structure_mapper.cpp' || echo '$(srcdir)/'`xml_structure_mapper.cpp + +liborcus_@ORCUS_API_VERSION@_la-xml_structure_tree.lo: xml_structure_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xml_structure_tree.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_structure_tree.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xml_structure_tree.lo `test -f 'xml_structure_tree.cpp' || echo '$(srcdir)/'`xml_structure_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_structure_tree.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_structure_tree.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_structure_tree.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xml_structure_tree.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xml_structure_tree.lo `test -f 'xml_structure_tree.cpp' || echo '$(srcdir)/'`xml_structure_tree.cpp + +liborcus_@ORCUS_API_VERSION@_la-xml_util.lo: xml_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xml_util.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_util.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xml_util.lo `test -f 'xml_util.cpp' || echo '$(srcdir)/'`xml_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_util.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_util.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_util.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xml_util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xml_util.lo `test -f 'xml_util.cpp' || echo '$(srcdir)/'`xml_util.cpp + +liborcus_@ORCUS_API_VERSION@_la-xpath_parser.lo: xpath_parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xpath_parser.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xpath_parser.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xpath_parser.lo `test -f 'xpath_parser.cpp' || echo '$(srcdir)/'`xpath_parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xpath_parser.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xpath_parser.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xpath_parser.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xpath_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xpath_parser.lo `test -f 'xpath_parser.cpp' || echo '$(srcdir)/'`xpath_parser.cpp + +liborcus_@ORCUS_API_VERSION@_la-yaml_document_tree.lo: yaml_document_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-yaml_document_tree.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-yaml_document_tree.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-yaml_document_tree.lo `test -f 'yaml_document_tree.cpp' || echo '$(srcdir)/'`yaml_document_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-yaml_document_tree.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-yaml_document_tree.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='yaml_document_tree.cpp' object='liborcus_@ORCUS_API_VERSION@_la-yaml_document_tree.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-yaml_document_tree.lo `test -f 'yaml_document_tree.cpp' || echo '$(srcdir)/'`yaml_document_tree.cpp + +liborcus_@ORCUS_API_VERSION@_la-ooxml_namespace_types.lo: ooxml_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-ooxml_namespace_types.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_namespace_types.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-ooxml_namespace_types.lo `test -f 'ooxml_namespace_types.cpp' || echo '$(srcdir)/'`ooxml_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_namespace_types.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_namespace_types.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_namespace_types.cpp' object='liborcus_@ORCUS_API_VERSION@_la-ooxml_namespace_types.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-ooxml_namespace_types.lo `test -f 'ooxml_namespace_types.cpp' || echo '$(srcdir)/'`ooxml_namespace_types.cpp + +liborcus_@ORCUS_API_VERSION@_la-odf_namespace_types.lo: odf_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-odf_namespace_types.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_namespace_types.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-odf_namespace_types.lo `test -f 'odf_namespace_types.cpp' || echo '$(srcdir)/'`odf_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_namespace_types.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_namespace_types.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_namespace_types.cpp' object='liborcus_@ORCUS_API_VERSION@_la-odf_namespace_types.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-odf_namespace_types.lo `test -f 'odf_namespace_types.cpp' || echo '$(srcdir)/'`odf_namespace_types.cpp + +liborcus_@ORCUS_API_VERSION@_la-gnumeric_namespace_types.lo: gnumeric_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-gnumeric_namespace_types.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_namespace_types.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_namespace_types.lo `test -f 'gnumeric_namespace_types.cpp' || echo '$(srcdir)/'`gnumeric_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_namespace_types.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_namespace_types.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_namespace_types.cpp' object='liborcus_@ORCUS_API_VERSION@_la-gnumeric_namespace_types.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_namespace_types.lo `test -f 'gnumeric_namespace_types.cpp' || echo '$(srcdir)/'`gnumeric_namespace_types.cpp + +liborcus_@ORCUS_API_VERSION@_la-xls_xml_namespace_types.lo: xls_xml_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xls_xml_namespace_types.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_namespace_types.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xls_xml_namespace_types.lo `test -f 'xls_xml_namespace_types.cpp' || echo '$(srcdir)/'`xls_xml_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_namespace_types.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_namespace_types.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xls_xml_namespace_types.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xls_xml_namespace_types.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xls_xml_namespace_types.lo `test -f 'xls_xml_namespace_types.cpp' || echo '$(srcdir)/'`xls_xml_namespace_types.cpp + +liborcus_@ORCUS_API_VERSION@_la-session_context.lo: session_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-session_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-session_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-session_context.lo `test -f 'session_context.cpp' || echo '$(srcdir)/'`session_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-session_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-session_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='session_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-session_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-session_context.lo `test -f 'session_context.cpp' || echo '$(srcdir)/'`session_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-spreadsheet_impl_types.lo: spreadsheet_impl_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-spreadsheet_impl_types.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_impl_types.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-spreadsheet_impl_types.lo `test -f 'spreadsheet_impl_types.cpp' || echo '$(srcdir)/'`spreadsheet_impl_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_impl_types.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_impl_types.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='spreadsheet_impl_types.cpp' object='liborcus_@ORCUS_API_VERSION@_la-spreadsheet_impl_types.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-spreadsheet_impl_types.lo `test -f 'spreadsheet_impl_types.cpp' || echo '$(srcdir)/'`spreadsheet_impl_types.cpp + +liborcus_@ORCUS_API_VERSION@_la-spreadsheet_types.lo: spreadsheet_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-spreadsheet_types.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_types.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-spreadsheet_types.lo `test -f 'spreadsheet_types.cpp' || echo '$(srcdir)/'`spreadsheet_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_types.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_types.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='spreadsheet_types.cpp' object='liborcus_@ORCUS_API_VERSION@_la-spreadsheet_types.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-spreadsheet_types.lo `test -f 'spreadsheet_types.cpp' || echo '$(srcdir)/'`spreadsheet_types.cpp + +liborcus_@ORCUS_API_VERSION@_la-spreadsheet_iface_util.lo: spreadsheet_iface_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-spreadsheet_iface_util.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_iface_util.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-spreadsheet_iface_util.lo `test -f 'spreadsheet_iface_util.cpp' || echo '$(srcdir)/'`spreadsheet_iface_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_iface_util.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_iface_util.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='spreadsheet_iface_util.cpp' object='liborcus_@ORCUS_API_VERSION@_la-spreadsheet_iface_util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-spreadsheet_iface_util.lo `test -f 'spreadsheet_iface_util.cpp' || echo '$(srcdir)/'`spreadsheet_iface_util.cpp + +liborcus_@ORCUS_API_VERSION@_la-string_helper.lo: string_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-string_helper.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-string_helper.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-string_helper.lo `test -f 'string_helper.cpp' || echo '$(srcdir)/'`string_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-string_helper.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-string_helper.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='string_helper.cpp' object='liborcus_@ORCUS_API_VERSION@_la-string_helper.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-string_helper.lo `test -f 'string_helper.cpp' || echo '$(srcdir)/'`string_helper.cpp + +liborcus_@ORCUS_API_VERSION@_la-ooxml_content_types.lo: ooxml_content_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-ooxml_content_types.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_content_types.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-ooxml_content_types.lo `test -f 'ooxml_content_types.cpp' || echo '$(srcdir)/'`ooxml_content_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_content_types.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_content_types.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_content_types.cpp' object='liborcus_@ORCUS_API_VERSION@_la-ooxml_content_types.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-ooxml_content_types.lo `test -f 'ooxml_content_types.cpp' || echo '$(srcdir)/'`ooxml_content_types.cpp + +liborcus_@ORCUS_API_VERSION@_la-ooxml_global.lo: ooxml_global.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-ooxml_global.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_global.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-ooxml_global.lo `test -f 'ooxml_global.cpp' || echo '$(srcdir)/'`ooxml_global.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_global.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_global.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_global.cpp' object='liborcus_@ORCUS_API_VERSION@_la-ooxml_global.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-ooxml_global.lo `test -f 'ooxml_global.cpp' || echo '$(srcdir)/'`ooxml_global.cpp + +liborcus_@ORCUS_API_VERSION@_la-ooxml_schemas.lo: ooxml_schemas.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-ooxml_schemas.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_schemas.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-ooxml_schemas.lo `test -f 'ooxml_schemas.cpp' || echo '$(srcdir)/'`ooxml_schemas.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_schemas.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_schemas.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_schemas.cpp' object='liborcus_@ORCUS_API_VERSION@_la-ooxml_schemas.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-ooxml_schemas.lo `test -f 'ooxml_schemas.cpp' || echo '$(srcdir)/'`ooxml_schemas.cpp + +liborcus_@ORCUS_API_VERSION@_la-ooxml_tokens.lo: ooxml_tokens.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-ooxml_tokens.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_tokens.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-ooxml_tokens.lo `test -f 'ooxml_tokens.cpp' || echo '$(srcdir)/'`ooxml_tokens.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_tokens.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_tokens.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_tokens.cpp' object='liborcus_@ORCUS_API_VERSION@_la-ooxml_tokens.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-ooxml_tokens.lo `test -f 'ooxml_tokens.cpp' || echo '$(srcdir)/'`ooxml_tokens.cpp + +liborcus_@ORCUS_API_VERSION@_la-ooxml_types.lo: ooxml_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-ooxml_types.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_types.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-ooxml_types.lo `test -f 'ooxml_types.cpp' || echo '$(srcdir)/'`ooxml_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_types.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_types.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_types.cpp' object='liborcus_@ORCUS_API_VERSION@_la-ooxml_types.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-ooxml_types.lo `test -f 'ooxml_types.cpp' || echo '$(srcdir)/'`ooxml_types.cpp + +liborcus_@ORCUS_API_VERSION@_la-opc_context.lo: opc_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-opc_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-opc_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-opc_context.lo `test -f 'opc_context.cpp' || echo '$(srcdir)/'`opc_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-opc_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-opc_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='opc_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-opc_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-opc_context.lo `test -f 'opc_context.cpp' || echo '$(srcdir)/'`opc_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-opc_reader.lo: opc_reader.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-opc_reader.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-opc_reader.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-opc_reader.lo `test -f 'opc_reader.cpp' || echo '$(srcdir)/'`opc_reader.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-opc_reader.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-opc_reader.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='opc_reader.cpp' object='liborcus_@ORCUS_API_VERSION@_la-opc_reader.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-opc_reader.lo `test -f 'opc_reader.cpp' || echo '$(srcdir)/'`opc_reader.cpp + +liborcus_@ORCUS_API_VERSION@_la-orcus_xlsx.lo: orcus_xlsx.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-orcus_xlsx.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xlsx.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_xlsx.lo `test -f 'orcus_xlsx.cpp' || echo '$(srcdir)/'`orcus_xlsx.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xlsx.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xlsx.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='orcus_xlsx.cpp' object='liborcus_@ORCUS_API_VERSION@_la-orcus_xlsx.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_xlsx.lo `test -f 'orcus_xlsx.cpp' || echo '$(srcdir)/'`orcus_xlsx.cpp + +liborcus_@ORCUS_API_VERSION@_la-orcus_import_xlsx.lo: orcus_import_xlsx.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-orcus_import_xlsx.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_import_xlsx.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_import_xlsx.lo `test -f 'orcus_import_xlsx.cpp' || echo '$(srcdir)/'`orcus_import_xlsx.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_import_xlsx.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_import_xlsx.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='orcus_import_xlsx.cpp' object='liborcus_@ORCUS_API_VERSION@_la-orcus_import_xlsx.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_import_xlsx.lo `test -f 'orcus_import_xlsx.cpp' || echo '$(srcdir)/'`orcus_import_xlsx.cpp + +liborcus_@ORCUS_API_VERSION@_la-xlsx_shared_strings_context.lo: xlsx_shared_strings_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xlsx_shared_strings_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_shared_strings_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_shared_strings_context.lo `test -f 'xlsx_shared_strings_context.cpp' || echo '$(srcdir)/'`xlsx_shared_strings_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_shared_strings_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_shared_strings_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_shared_strings_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xlsx_shared_strings_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_shared_strings_context.lo `test -f 'xlsx_shared_strings_context.cpp' || echo '$(srcdir)/'`xlsx_shared_strings_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-xlsx_drawing_context.lo: xlsx_drawing_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xlsx_drawing_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_drawing_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_drawing_context.lo `test -f 'xlsx_drawing_context.cpp' || echo '$(srcdir)/'`xlsx_drawing_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_drawing_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_drawing_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_drawing_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xlsx_drawing_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_drawing_context.lo `test -f 'xlsx_drawing_context.cpp' || echo '$(srcdir)/'`xlsx_drawing_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-xlsx_handler.lo: xlsx_handler.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xlsx_handler.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_handler.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_handler.lo `test -f 'xlsx_handler.cpp' || echo '$(srcdir)/'`xlsx_handler.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_handler.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_handler.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_handler.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xlsx_handler.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_handler.lo `test -f 'xlsx_handler.cpp' || echo '$(srcdir)/'`xlsx_handler.cpp + +liborcus_@ORCUS_API_VERSION@_la-xlsx_helper.lo: xlsx_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xlsx_helper.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_helper.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_helper.lo `test -f 'xlsx_helper.cpp' || echo '$(srcdir)/'`xlsx_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_helper.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_helper.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_helper.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xlsx_helper.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_helper.lo `test -f 'xlsx_helper.cpp' || echo '$(srcdir)/'`xlsx_helper.cpp + +liborcus_@ORCUS_API_VERSION@_la-xlsx_session_data.lo: xlsx_session_data.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xlsx_session_data.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_session_data.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_session_data.lo `test -f 'xlsx_session_data.cpp' || echo '$(srcdir)/'`xlsx_session_data.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_session_data.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_session_data.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_session_data.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xlsx_session_data.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_session_data.lo `test -f 'xlsx_session_data.cpp' || echo '$(srcdir)/'`xlsx_session_data.cpp + +liborcus_@ORCUS_API_VERSION@_la-xlsx_revision_context.lo: xlsx_revision_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xlsx_revision_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_revision_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_revision_context.lo `test -f 'xlsx_revision_context.cpp' || echo '$(srcdir)/'`xlsx_revision_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_revision_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_revision_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_revision_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xlsx_revision_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_revision_context.lo `test -f 'xlsx_revision_context.cpp' || echo '$(srcdir)/'`xlsx_revision_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-xlsx_pivot_context.lo: xlsx_pivot_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xlsx_pivot_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_pivot_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_pivot_context.lo `test -f 'xlsx_pivot_context.cpp' || echo '$(srcdir)/'`xlsx_pivot_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_pivot_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_pivot_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_pivot_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xlsx_pivot_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_pivot_context.lo `test -f 'xlsx_pivot_context.cpp' || echo '$(srcdir)/'`xlsx_pivot_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-xlsx_sheet_context.lo: xlsx_sheet_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xlsx_sheet_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_sheet_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_sheet_context.lo `test -f 'xlsx_sheet_context.cpp' || echo '$(srcdir)/'`xlsx_sheet_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_sheet_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_sheet_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_sheet_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xlsx_sheet_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_sheet_context.lo `test -f 'xlsx_sheet_context.cpp' || echo '$(srcdir)/'`xlsx_sheet_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-xlsx_styles_context.lo: xlsx_styles_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xlsx_styles_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_styles_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_styles_context.lo `test -f 'xlsx_styles_context.cpp' || echo '$(srcdir)/'`xlsx_styles_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_styles_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_styles_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_styles_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xlsx_styles_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_styles_context.lo `test -f 'xlsx_styles_context.cpp' || echo '$(srcdir)/'`xlsx_styles_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-xlsx_conditional_format_context.lo: xlsx_conditional_format_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xlsx_conditional_format_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_conditional_format_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_conditional_format_context.lo `test -f 'xlsx_conditional_format_context.cpp' || echo '$(srcdir)/'`xlsx_conditional_format_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_conditional_format_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_conditional_format_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_conditional_format_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xlsx_conditional_format_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_conditional_format_context.lo `test -f 'xlsx_conditional_format_context.cpp' || echo '$(srcdir)/'`xlsx_conditional_format_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-xlsx_table_context.lo: xlsx_table_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xlsx_table_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_table_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_table_context.lo `test -f 'xlsx_table_context.cpp' || echo '$(srcdir)/'`xlsx_table_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_table_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_table_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_table_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xlsx_table_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_table_context.lo `test -f 'xlsx_table_context.cpp' || echo '$(srcdir)/'`xlsx_table_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-xlsx_autofilter_context.lo: xlsx_autofilter_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xlsx_autofilter_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_autofilter_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_autofilter_context.lo `test -f 'xlsx_autofilter_context.cpp' || echo '$(srcdir)/'`xlsx_autofilter_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_autofilter_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_autofilter_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_autofilter_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xlsx_autofilter_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_autofilter_context.lo `test -f 'xlsx_autofilter_context.cpp' || echo '$(srcdir)/'`xlsx_autofilter_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-xlsx_types.lo: xlsx_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xlsx_types.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_types.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_types.lo `test -f 'xlsx_types.cpp' || echo '$(srcdir)/'`xlsx_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_types.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_types.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_types.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xlsx_types.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_types.lo `test -f 'xlsx_types.cpp' || echo '$(srcdir)/'`xlsx_types.cpp + +liborcus_@ORCUS_API_VERSION@_la-xlsx_workbook_context.lo: xlsx_workbook_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xlsx_workbook_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_workbook_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_workbook_context.lo `test -f 'xlsx_workbook_context.cpp' || echo '$(srcdir)/'`xlsx_workbook_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_workbook_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_workbook_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_workbook_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xlsx_workbook_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xlsx_workbook_context.lo `test -f 'xlsx_workbook_context.cpp' || echo '$(srcdir)/'`xlsx_workbook_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-xls_xml_tokens.lo: xls_xml_tokens.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xls_xml_tokens.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_tokens.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xls_xml_tokens.lo `test -f 'xls_xml_tokens.cpp' || echo '$(srcdir)/'`xls_xml_tokens.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_tokens.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_tokens.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xls_xml_tokens.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xls_xml_tokens.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xls_xml_tokens.lo `test -f 'xls_xml_tokens.cpp' || echo '$(srcdir)/'`xls_xml_tokens.cpp + +liborcus_@ORCUS_API_VERSION@_la-orcus_xls_xml.lo: orcus_xls_xml.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-orcus_xls_xml.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xls_xml.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_xls_xml.lo `test -f 'orcus_xls_xml.cpp' || echo '$(srcdir)/'`orcus_xls_xml.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xls_xml.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xls_xml.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='orcus_xls_xml.cpp' object='liborcus_@ORCUS_API_VERSION@_la-orcus_xls_xml.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_xls_xml.lo `test -f 'orcus_xls_xml.cpp' || echo '$(srcdir)/'`orcus_xls_xml.cpp + +liborcus_@ORCUS_API_VERSION@_la-xls_xml_detection_handler.lo: xls_xml_detection_handler.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xls_xml_detection_handler.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_detection_handler.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xls_xml_detection_handler.lo `test -f 'xls_xml_detection_handler.cpp' || echo '$(srcdir)/'`xls_xml_detection_handler.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_detection_handler.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_detection_handler.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xls_xml_detection_handler.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xls_xml_detection_handler.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xls_xml_detection_handler.lo `test -f 'xls_xml_detection_handler.cpp' || echo '$(srcdir)/'`xls_xml_detection_handler.cpp + +liborcus_@ORCUS_API_VERSION@_la-xls_xml_handler.lo: xls_xml_handler.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xls_xml_handler.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_handler.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xls_xml_handler.lo `test -f 'xls_xml_handler.cpp' || echo '$(srcdir)/'`xls_xml_handler.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_handler.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_handler.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xls_xml_handler.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xls_xml_handler.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xls_xml_handler.lo `test -f 'xls_xml_handler.cpp' || echo '$(srcdir)/'`xls_xml_handler.cpp + +liborcus_@ORCUS_API_VERSION@_la-xls_xml_context.lo: xls_xml_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-xls_xml_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-xls_xml_context.lo `test -f 'xls_xml_context.cpp' || echo '$(srcdir)/'`xls_xml_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xls_xml_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-xls_xml_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-xls_xml_context.lo `test -f 'xls_xml_context.cpp' || echo '$(srcdir)/'`xls_xml_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-odf_document_styles_context.lo: odf_document_styles_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-odf_document_styles_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_document_styles_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-odf_document_styles_context.lo `test -f 'odf_document_styles_context.cpp' || echo '$(srcdir)/'`odf_document_styles_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_document_styles_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_document_styles_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_document_styles_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-odf_document_styles_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-odf_document_styles_context.lo `test -f 'odf_document_styles_context.cpp' || echo '$(srcdir)/'`odf_document_styles_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-odf_para_context.lo: odf_para_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-odf_para_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_para_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-odf_para_context.lo `test -f 'odf_para_context.cpp' || echo '$(srcdir)/'`odf_para_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_para_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_para_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_para_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-odf_para_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-odf_para_context.lo `test -f 'odf_para_context.cpp' || echo '$(srcdir)/'`odf_para_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-odf_styles.lo: odf_styles.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-odf_styles.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_styles.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-odf_styles.lo `test -f 'odf_styles.cpp' || echo '$(srcdir)/'`odf_styles.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_styles.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_styles.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_styles.cpp' object='liborcus_@ORCUS_API_VERSION@_la-odf_styles.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-odf_styles.lo `test -f 'odf_styles.cpp' || echo '$(srcdir)/'`odf_styles.cpp + +liborcus_@ORCUS_API_VERSION@_la-odf_styles_context.lo: odf_styles_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-odf_styles_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_styles_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-odf_styles_context.lo `test -f 'odf_styles_context.cpp' || echo '$(srcdir)/'`odf_styles_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_styles_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_styles_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_styles_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-odf_styles_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-odf_styles_context.lo `test -f 'odf_styles_context.cpp' || echo '$(srcdir)/'`odf_styles_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-odf_style_context.lo: odf_style_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-odf_style_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_style_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-odf_style_context.lo `test -f 'odf_style_context.cpp' || echo '$(srcdir)/'`odf_style_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_style_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_style_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_style_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-odf_style_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-odf_style_context.lo `test -f 'odf_style_context.cpp' || echo '$(srcdir)/'`odf_style_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-odf_number_format_context.lo: odf_number_format_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-odf_number_format_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_number_format_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-odf_number_format_context.lo `test -f 'odf_number_format_context.cpp' || echo '$(srcdir)/'`odf_number_format_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_number_format_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_number_format_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_number_format_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-odf_number_format_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-odf_number_format_context.lo `test -f 'odf_number_format_context.cpp' || echo '$(srcdir)/'`odf_number_format_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-odf_tokens.lo: odf_tokens.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-odf_tokens.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_tokens.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-odf_tokens.lo `test -f 'odf_tokens.cpp' || echo '$(srcdir)/'`odf_tokens.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_tokens.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_tokens.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_tokens.cpp' object='liborcus_@ORCUS_API_VERSION@_la-odf_tokens.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-odf_tokens.lo `test -f 'odf_tokens.cpp' || echo '$(srcdir)/'`odf_tokens.cpp + +liborcus_@ORCUS_API_VERSION@_la-ods_content_xml_context.lo: ods_content_xml_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-ods_content_xml_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_content_xml_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-ods_content_xml_context.lo `test -f 'ods_content_xml_context.cpp' || echo '$(srcdir)/'`ods_content_xml_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_content_xml_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_content_xml_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ods_content_xml_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-ods_content_xml_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-ods_content_xml_context.lo `test -f 'ods_content_xml_context.cpp' || echo '$(srcdir)/'`ods_content_xml_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-ods_dde_links_context.lo: ods_dde_links_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-ods_dde_links_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_dde_links_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-ods_dde_links_context.lo `test -f 'ods_dde_links_context.cpp' || echo '$(srcdir)/'`ods_dde_links_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_dde_links_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_dde_links_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ods_dde_links_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-ods_dde_links_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-ods_dde_links_context.lo `test -f 'ods_dde_links_context.cpp' || echo '$(srcdir)/'`ods_dde_links_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-ods_session_data.lo: ods_session_data.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-ods_session_data.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_session_data.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-ods_session_data.lo `test -f 'ods_session_data.cpp' || echo '$(srcdir)/'`ods_session_data.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_session_data.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_session_data.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ods_session_data.cpp' object='liborcus_@ORCUS_API_VERSION@_la-ods_session_data.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-ods_session_data.lo `test -f 'ods_session_data.cpp' || echo '$(srcdir)/'`ods_session_data.cpp + +liborcus_@ORCUS_API_VERSION@_la-odf_helper.lo: odf_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-odf_helper.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_helper.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-odf_helper.lo `test -f 'odf_helper.cpp' || echo '$(srcdir)/'`odf_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_helper.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_helper.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_helper.cpp' object='liborcus_@ORCUS_API_VERSION@_la-odf_helper.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-odf_helper.lo `test -f 'odf_helper.cpp' || echo '$(srcdir)/'`odf_helper.cpp + +liborcus_@ORCUS_API_VERSION@_la-orcus_ods.lo: orcus_ods.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-orcus_ods.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_ods.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_ods.lo `test -f 'orcus_ods.cpp' || echo '$(srcdir)/'`orcus_ods.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_ods.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_ods.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='orcus_ods.cpp' object='liborcus_@ORCUS_API_VERSION@_la-orcus_ods.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_ods.lo `test -f 'orcus_ods.cpp' || echo '$(srcdir)/'`orcus_ods.cpp + +liborcus_@ORCUS_API_VERSION@_la-orcus_import_ods.lo: orcus_import_ods.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-orcus_import_ods.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_import_ods.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_import_ods.lo `test -f 'orcus_import_ods.cpp' || echo '$(srcdir)/'`orcus_import_ods.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_import_ods.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_import_ods.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='orcus_import_ods.cpp' object='liborcus_@ORCUS_API_VERSION@_la-orcus_import_ods.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_import_ods.lo `test -f 'orcus_import_ods.cpp' || echo '$(srcdir)/'`orcus_import_ods.cpp + +liborcus_@ORCUS_API_VERSION@_la-gnumeric_cell_context.lo: gnumeric_cell_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-gnumeric_cell_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_cell_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_cell_context.lo `test -f 'gnumeric_cell_context.cpp' || echo '$(srcdir)/'`gnumeric_cell_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_cell_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_cell_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_cell_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-gnumeric_cell_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_cell_context.lo `test -f 'gnumeric_cell_context.cpp' || echo '$(srcdir)/'`gnumeric_cell_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-gnumeric_context.lo: gnumeric_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-gnumeric_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_context.lo `test -f 'gnumeric_context.cpp' || echo '$(srcdir)/'`gnumeric_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-gnumeric_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_context.lo `test -f 'gnumeric_context.cpp' || echo '$(srcdir)/'`gnumeric_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-gnumeric_detection_handler.lo: gnumeric_detection_handler.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-gnumeric_detection_handler.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_detection_handler.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_detection_handler.lo `test -f 'gnumeric_detection_handler.cpp' || echo '$(srcdir)/'`gnumeric_detection_handler.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_detection_handler.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_detection_handler.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_detection_handler.cpp' object='liborcus_@ORCUS_API_VERSION@_la-gnumeric_detection_handler.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_detection_handler.lo `test -f 'gnumeric_detection_handler.cpp' || echo '$(srcdir)/'`gnumeric_detection_handler.cpp + +liborcus_@ORCUS_API_VERSION@_la-gnumeric_filter_context.lo: gnumeric_filter_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-gnumeric_filter_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_filter_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_filter_context.lo `test -f 'gnumeric_filter_context.cpp' || echo '$(srcdir)/'`gnumeric_filter_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_filter_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_filter_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_filter_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-gnumeric_filter_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_filter_context.lo `test -f 'gnumeric_filter_context.cpp' || echo '$(srcdir)/'`gnumeric_filter_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-gnumeric_handler.lo: gnumeric_handler.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-gnumeric_handler.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_handler.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_handler.lo `test -f 'gnumeric_handler.cpp' || echo '$(srcdir)/'`gnumeric_handler.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_handler.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_handler.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_handler.cpp' object='liborcus_@ORCUS_API_VERSION@_la-gnumeric_handler.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_handler.lo `test -f 'gnumeric_handler.cpp' || echo '$(srcdir)/'`gnumeric_handler.cpp + +liborcus_@ORCUS_API_VERSION@_la-gnumeric_names_context.lo: gnumeric_names_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-gnumeric_names_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_names_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_names_context.lo `test -f 'gnumeric_names_context.cpp' || echo '$(srcdir)/'`gnumeric_names_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_names_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_names_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_names_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-gnumeric_names_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_names_context.lo `test -f 'gnumeric_names_context.cpp' || echo '$(srcdir)/'`gnumeric_names_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-gnumeric_sheet_context.lo: gnumeric_sheet_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-gnumeric_sheet_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_sheet_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_sheet_context.lo `test -f 'gnumeric_sheet_context.cpp' || echo '$(srcdir)/'`gnumeric_sheet_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_sheet_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_sheet_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_sheet_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-gnumeric_sheet_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_sheet_context.lo `test -f 'gnumeric_sheet_context.cpp' || echo '$(srcdir)/'`gnumeric_sheet_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-gnumeric_styles_context.lo: gnumeric_styles_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-gnumeric_styles_context.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_styles_context.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_styles_context.lo `test -f 'gnumeric_styles_context.cpp' || echo '$(srcdir)/'`gnumeric_styles_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_styles_context.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_styles_context.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_styles_context.cpp' object='liborcus_@ORCUS_API_VERSION@_la-gnumeric_styles_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_styles_context.lo `test -f 'gnumeric_styles_context.cpp' || echo '$(srcdir)/'`gnumeric_styles_context.cpp + +liborcus_@ORCUS_API_VERSION@_la-gnumeric_tokens.lo: gnumeric_tokens.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-gnumeric_tokens.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_tokens.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_tokens.lo `test -f 'gnumeric_tokens.cpp' || echo '$(srcdir)/'`gnumeric_tokens.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_tokens.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_tokens.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_tokens.cpp' object='liborcus_@ORCUS_API_VERSION@_la-gnumeric_tokens.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_tokens.lo `test -f 'gnumeric_tokens.cpp' || echo '$(srcdir)/'`gnumeric_tokens.cpp + +liborcus_@ORCUS_API_VERSION@_la-gnumeric_types.lo: gnumeric_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-gnumeric_types.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_types.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_types.lo `test -f 'gnumeric_types.cpp' || echo '$(srcdir)/'`gnumeric_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_types.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_types.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_types.cpp' object='liborcus_@ORCUS_API_VERSION@_la-gnumeric_types.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_types.lo `test -f 'gnumeric_types.cpp' || echo '$(srcdir)/'`gnumeric_types.cpp + +liborcus_@ORCUS_API_VERSION@_la-gnumeric_value_format_parser.lo: gnumeric_value_format_parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-gnumeric_value_format_parser.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_value_format_parser.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_value_format_parser.lo `test -f 'gnumeric_value_format_parser.cpp' || echo '$(srcdir)/'`gnumeric_value_format_parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_value_format_parser.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_value_format_parser.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_value_format_parser.cpp' object='liborcus_@ORCUS_API_VERSION@_la-gnumeric_value_format_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-gnumeric_value_format_parser.lo `test -f 'gnumeric_value_format_parser.cpp' || echo '$(srcdir)/'`gnumeric_value_format_parser.cpp + +liborcus_@ORCUS_API_VERSION@_la-orcus_gnumeric.lo: orcus_gnumeric.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-orcus_gnumeric.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_gnumeric.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_gnumeric.lo `test -f 'orcus_gnumeric.cpp' || echo '$(srcdir)/'`orcus_gnumeric.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_gnumeric.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_gnumeric.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='orcus_gnumeric.cpp' object='liborcus_@ORCUS_API_VERSION@_la-orcus_gnumeric.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_gnumeric.lo `test -f 'orcus_gnumeric.cpp' || echo '$(srcdir)/'`orcus_gnumeric.cpp + +liborcus_@ORCUS_API_VERSION@_la-orcus_parquet.lo: orcus_parquet.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -MT liborcus_@ORCUS_API_VERSION@_la-orcus_parquet.lo -MD -MP -MF $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_parquet.Tpo -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_parquet.lo `test -f 'orcus_parquet.cpp' || echo '$(srcdir)/'`orcus_parquet.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_parquet.Tpo $(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_parquet.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='orcus_parquet.cpp' object='liborcus_@ORCUS_API_VERSION@_la-orcus_parquet.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liborcus_@ORCUS_API_VERSION@_la_CXXFLAGS) $(CXXFLAGS) -c -o liborcus_@ORCUS_API_VERSION@_la-orcus_parquet.lo `test -f 'orcus_parquet.cpp' || echo '$(srcdir)/'`orcus_parquet.cpp + +gnumeric_sheet_context_test-session_context.o: session_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-session_context.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-session_context.Tpo -c -o gnumeric_sheet_context_test-session_context.o `test -f 'session_context.cpp' || echo '$(srcdir)/'`session_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-session_context.Tpo $(DEPDIR)/gnumeric_sheet_context_test-session_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='session_context.cpp' object='gnumeric_sheet_context_test-session_context.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-session_context.o `test -f 'session_context.cpp' || echo '$(srcdir)/'`session_context.cpp + +gnumeric_sheet_context_test-session_context.obj: session_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-session_context.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-session_context.Tpo -c -o gnumeric_sheet_context_test-session_context.obj `if test -f 'session_context.cpp'; then $(CYGPATH_W) 'session_context.cpp'; else $(CYGPATH_W) '$(srcdir)/session_context.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-session_context.Tpo $(DEPDIR)/gnumeric_sheet_context_test-session_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='session_context.cpp' object='gnumeric_sheet_context_test-session_context.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-session_context.obj `if test -f 'session_context.cpp'; then $(CYGPATH_W) 'session_context.cpp'; else $(CYGPATH_W) '$(srcdir)/session_context.cpp'; fi` + +gnumeric_sheet_context_test-gnumeric_sheet_context_test.o: gnumeric_sheet_context_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_sheet_context_test.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context_test.Tpo -c -o gnumeric_sheet_context_test-gnumeric_sheet_context_test.o `test -f 'gnumeric_sheet_context_test.cpp' || echo '$(srcdir)/'`gnumeric_sheet_context_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context_test.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_sheet_context_test.cpp' object='gnumeric_sheet_context_test-gnumeric_sheet_context_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_sheet_context_test.o `test -f 'gnumeric_sheet_context_test.cpp' || echo '$(srcdir)/'`gnumeric_sheet_context_test.cpp + +gnumeric_sheet_context_test-gnumeric_sheet_context_test.obj: gnumeric_sheet_context_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_sheet_context_test.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context_test.Tpo -c -o gnumeric_sheet_context_test-gnumeric_sheet_context_test.obj `if test -f 'gnumeric_sheet_context_test.cpp'; then $(CYGPATH_W) 'gnumeric_sheet_context_test.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_sheet_context_test.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context_test.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_sheet_context_test.cpp' object='gnumeric_sheet_context_test-gnumeric_sheet_context_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_sheet_context_test.obj `if test -f 'gnumeric_sheet_context_test.cpp'; then $(CYGPATH_W) 'gnumeric_sheet_context_test.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_sheet_context_test.cpp'; fi` + +gnumeric_sheet_context_test-gnumeric_sheet_context.o: gnumeric_sheet_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_sheet_context.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context.Tpo -c -o gnumeric_sheet_context_test-gnumeric_sheet_context.o `test -f 'gnumeric_sheet_context.cpp' || echo '$(srcdir)/'`gnumeric_sheet_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_sheet_context.cpp' object='gnumeric_sheet_context_test-gnumeric_sheet_context.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_sheet_context.o `test -f 'gnumeric_sheet_context.cpp' || echo '$(srcdir)/'`gnumeric_sheet_context.cpp + +gnumeric_sheet_context_test-gnumeric_sheet_context.obj: gnumeric_sheet_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_sheet_context.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context.Tpo -c -o gnumeric_sheet_context_test-gnumeric_sheet_context.obj `if test -f 'gnumeric_sheet_context.cpp'; then $(CYGPATH_W) 'gnumeric_sheet_context.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_sheet_context.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_sheet_context.cpp' object='gnumeric_sheet_context_test-gnumeric_sheet_context.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_sheet_context.obj `if test -f 'gnumeric_sheet_context.cpp'; then $(CYGPATH_W) 'gnumeric_sheet_context.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_sheet_context.cpp'; fi` + +gnumeric_sheet_context_test-gnumeric_names_context.o: gnumeric_names_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_names_context.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_names_context.Tpo -c -o gnumeric_sheet_context_test-gnumeric_names_context.o `test -f 'gnumeric_names_context.cpp' || echo '$(srcdir)/'`gnumeric_names_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_names_context.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_names_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_names_context.cpp' object='gnumeric_sheet_context_test-gnumeric_names_context.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_names_context.o `test -f 'gnumeric_names_context.cpp' || echo '$(srcdir)/'`gnumeric_names_context.cpp + +gnumeric_sheet_context_test-gnumeric_names_context.obj: gnumeric_names_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_names_context.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_names_context.Tpo -c -o gnumeric_sheet_context_test-gnumeric_names_context.obj `if test -f 'gnumeric_names_context.cpp'; then $(CYGPATH_W) 'gnumeric_names_context.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_names_context.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_names_context.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_names_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_names_context.cpp' object='gnumeric_sheet_context_test-gnumeric_names_context.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_names_context.obj `if test -f 'gnumeric_names_context.cpp'; then $(CYGPATH_W) 'gnumeric_names_context.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_names_context.cpp'; fi` + +gnumeric_sheet_context_test-gnumeric_cell_context.o: gnumeric_cell_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_cell_context.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_cell_context.Tpo -c -o gnumeric_sheet_context_test-gnumeric_cell_context.o `test -f 'gnumeric_cell_context.cpp' || echo '$(srcdir)/'`gnumeric_cell_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_cell_context.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_cell_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_cell_context.cpp' object='gnumeric_sheet_context_test-gnumeric_cell_context.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_cell_context.o `test -f 'gnumeric_cell_context.cpp' || echo '$(srcdir)/'`gnumeric_cell_context.cpp + +gnumeric_sheet_context_test-gnumeric_cell_context.obj: gnumeric_cell_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_cell_context.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_cell_context.Tpo -c -o gnumeric_sheet_context_test-gnumeric_cell_context.obj `if test -f 'gnumeric_cell_context.cpp'; then $(CYGPATH_W) 'gnumeric_cell_context.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_cell_context.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_cell_context.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_cell_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_cell_context.cpp' object='gnumeric_sheet_context_test-gnumeric_cell_context.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_cell_context.obj `if test -f 'gnumeric_cell_context.cpp'; then $(CYGPATH_W) 'gnumeric_cell_context.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_cell_context.cpp'; fi` + +gnumeric_sheet_context_test-gnumeric_filter_context.o: gnumeric_filter_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_filter_context.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_filter_context.Tpo -c -o gnumeric_sheet_context_test-gnumeric_filter_context.o `test -f 'gnumeric_filter_context.cpp' || echo '$(srcdir)/'`gnumeric_filter_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_filter_context.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_filter_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_filter_context.cpp' object='gnumeric_sheet_context_test-gnumeric_filter_context.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_filter_context.o `test -f 'gnumeric_filter_context.cpp' || echo '$(srcdir)/'`gnumeric_filter_context.cpp + +gnumeric_sheet_context_test-gnumeric_filter_context.obj: gnumeric_filter_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_filter_context.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_filter_context.Tpo -c -o gnumeric_sheet_context_test-gnumeric_filter_context.obj `if test -f 'gnumeric_filter_context.cpp'; then $(CYGPATH_W) 'gnumeric_filter_context.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_filter_context.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_filter_context.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_filter_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_filter_context.cpp' object='gnumeric_sheet_context_test-gnumeric_filter_context.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_filter_context.obj `if test -f 'gnumeric_filter_context.cpp'; then $(CYGPATH_W) 'gnumeric_filter_context.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_filter_context.cpp'; fi` + +gnumeric_sheet_context_test-gnumeric_styles_context.o: gnumeric_styles_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_styles_context.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_styles_context.Tpo -c -o gnumeric_sheet_context_test-gnumeric_styles_context.o `test -f 'gnumeric_styles_context.cpp' || echo '$(srcdir)/'`gnumeric_styles_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_styles_context.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_styles_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_styles_context.cpp' object='gnumeric_sheet_context_test-gnumeric_styles_context.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_styles_context.o `test -f 'gnumeric_styles_context.cpp' || echo '$(srcdir)/'`gnumeric_styles_context.cpp + +gnumeric_sheet_context_test-gnumeric_styles_context.obj: gnumeric_styles_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_styles_context.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_styles_context.Tpo -c -o gnumeric_sheet_context_test-gnumeric_styles_context.obj `if test -f 'gnumeric_styles_context.cpp'; then $(CYGPATH_W) 'gnumeric_styles_context.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_styles_context.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_styles_context.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_styles_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_styles_context.cpp' object='gnumeric_sheet_context_test-gnumeric_styles_context.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_styles_context.obj `if test -f 'gnumeric_styles_context.cpp'; then $(CYGPATH_W) 'gnumeric_styles_context.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_styles_context.cpp'; fi` + +gnumeric_sheet_context_test-gnumeric_value_format_parser.o: gnumeric_value_format_parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_value_format_parser.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_value_format_parser.Tpo -c -o gnumeric_sheet_context_test-gnumeric_value_format_parser.o `test -f 'gnumeric_value_format_parser.cpp' || echo '$(srcdir)/'`gnumeric_value_format_parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_value_format_parser.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_value_format_parser.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_value_format_parser.cpp' object='gnumeric_sheet_context_test-gnumeric_value_format_parser.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_value_format_parser.o `test -f 'gnumeric_value_format_parser.cpp' || echo '$(srcdir)/'`gnumeric_value_format_parser.cpp + +gnumeric_sheet_context_test-gnumeric_value_format_parser.obj: gnumeric_value_format_parser.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_value_format_parser.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_value_format_parser.Tpo -c -o gnumeric_sheet_context_test-gnumeric_value_format_parser.obj `if test -f 'gnumeric_value_format_parser.cpp'; then $(CYGPATH_W) 'gnumeric_value_format_parser.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_value_format_parser.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_value_format_parser.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_value_format_parser.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_value_format_parser.cpp' object='gnumeric_sheet_context_test-gnumeric_value_format_parser.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_value_format_parser.obj `if test -f 'gnumeric_value_format_parser.cpp'; then $(CYGPATH_W) 'gnumeric_value_format_parser.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_value_format_parser.cpp'; fi` + +gnumeric_sheet_context_test-gnumeric_types.o: gnumeric_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_types.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_types.Tpo -c -o gnumeric_sheet_context_test-gnumeric_types.o `test -f 'gnumeric_types.cpp' || echo '$(srcdir)/'`gnumeric_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_types.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_types.cpp' object='gnumeric_sheet_context_test-gnumeric_types.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_types.o `test -f 'gnumeric_types.cpp' || echo '$(srcdir)/'`gnumeric_types.cpp + +gnumeric_sheet_context_test-gnumeric_types.obj: gnumeric_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_types.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_types.Tpo -c -o gnumeric_sheet_context_test-gnumeric_types.obj `if test -f 'gnumeric_types.cpp'; then $(CYGPATH_W) 'gnumeric_types.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_types.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_types.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_types.cpp' object='gnumeric_sheet_context_test-gnumeric_types.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_types.obj `if test -f 'gnumeric_types.cpp'; then $(CYGPATH_W) 'gnumeric_types.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_types.cpp'; fi` + +gnumeric_sheet_context_test-number_utils.o: number_utils.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-number_utils.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-number_utils.Tpo -c -o gnumeric_sheet_context_test-number_utils.o `test -f 'number_utils.cpp' || echo '$(srcdir)/'`number_utils.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-number_utils.Tpo $(DEPDIR)/gnumeric_sheet_context_test-number_utils.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='number_utils.cpp' object='gnumeric_sheet_context_test-number_utils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-number_utils.o `test -f 'number_utils.cpp' || echo '$(srcdir)/'`number_utils.cpp + +gnumeric_sheet_context_test-number_utils.obj: number_utils.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-number_utils.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-number_utils.Tpo -c -o gnumeric_sheet_context_test-number_utils.obj `if test -f 'number_utils.cpp'; then $(CYGPATH_W) 'number_utils.cpp'; else $(CYGPATH_W) '$(srcdir)/number_utils.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-number_utils.Tpo $(DEPDIR)/gnumeric_sheet_context_test-number_utils.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='number_utils.cpp' object='gnumeric_sheet_context_test-number_utils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-number_utils.obj `if test -f 'number_utils.cpp'; then $(CYGPATH_W) 'number_utils.cpp'; else $(CYGPATH_W) '$(srcdir)/number_utils.cpp'; fi` + +gnumeric_sheet_context_test-xml_context_base.o: xml_context_base.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-xml_context_base.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-xml_context_base.Tpo -c -o gnumeric_sheet_context_test-xml_context_base.o `test -f 'xml_context_base.cpp' || echo '$(srcdir)/'`xml_context_base.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-xml_context_base.Tpo $(DEPDIR)/gnumeric_sheet_context_test-xml_context_base.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_context_base.cpp' object='gnumeric_sheet_context_test-xml_context_base.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-xml_context_base.o `test -f 'xml_context_base.cpp' || echo '$(srcdir)/'`xml_context_base.cpp + +gnumeric_sheet_context_test-xml_context_base.obj: xml_context_base.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-xml_context_base.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-xml_context_base.Tpo -c -o gnumeric_sheet_context_test-xml_context_base.obj `if test -f 'xml_context_base.cpp'; then $(CYGPATH_W) 'xml_context_base.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_context_base.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-xml_context_base.Tpo $(DEPDIR)/gnumeric_sheet_context_test-xml_context_base.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_context_base.cpp' object='gnumeric_sheet_context_test-xml_context_base.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-xml_context_base.obj `if test -f 'xml_context_base.cpp'; then $(CYGPATH_W) 'xml_context_base.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_context_base.cpp'; fi` + +gnumeric_sheet_context_test-xml_element_types.o: xml_element_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-xml_element_types.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-xml_element_types.Tpo -c -o gnumeric_sheet_context_test-xml_element_types.o `test -f 'xml_element_types.cpp' || echo '$(srcdir)/'`xml_element_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-xml_element_types.Tpo $(DEPDIR)/gnumeric_sheet_context_test-xml_element_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_element_types.cpp' object='gnumeric_sheet_context_test-xml_element_types.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-xml_element_types.o `test -f 'xml_element_types.cpp' || echo '$(srcdir)/'`xml_element_types.cpp + +gnumeric_sheet_context_test-xml_element_types.obj: xml_element_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-xml_element_types.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-xml_element_types.Tpo -c -o gnumeric_sheet_context_test-xml_element_types.obj `if test -f 'xml_element_types.cpp'; then $(CYGPATH_W) 'xml_element_types.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_element_types.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-xml_element_types.Tpo $(DEPDIR)/gnumeric_sheet_context_test-xml_element_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_element_types.cpp' object='gnumeric_sheet_context_test-xml_element_types.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-xml_element_types.obj `if test -f 'xml_element_types.cpp'; then $(CYGPATH_W) 'xml_element_types.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_element_types.cpp'; fi` + +gnumeric_sheet_context_test-xml_element_validator.o: xml_element_validator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-xml_element_validator.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-xml_element_validator.Tpo -c -o gnumeric_sheet_context_test-xml_element_validator.o `test -f 'xml_element_validator.cpp' || echo '$(srcdir)/'`xml_element_validator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-xml_element_validator.Tpo $(DEPDIR)/gnumeric_sheet_context_test-xml_element_validator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_element_validator.cpp' object='gnumeric_sheet_context_test-xml_element_validator.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-xml_element_validator.o `test -f 'xml_element_validator.cpp' || echo '$(srcdir)/'`xml_element_validator.cpp + +gnumeric_sheet_context_test-xml_element_validator.obj: xml_element_validator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-xml_element_validator.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-xml_element_validator.Tpo -c -o gnumeric_sheet_context_test-xml_element_validator.obj `if test -f 'xml_element_validator.cpp'; then $(CYGPATH_W) 'xml_element_validator.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_element_validator.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-xml_element_validator.Tpo $(DEPDIR)/gnumeric_sheet_context_test-xml_element_validator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_element_validator.cpp' object='gnumeric_sheet_context_test-xml_element_validator.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-xml_element_validator.obj `if test -f 'xml_element_validator.cpp'; then $(CYGPATH_W) 'xml_element_validator.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_element_validator.cpp'; fi` + +gnumeric_sheet_context_test-xml_empty_context.o: xml_empty_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-xml_empty_context.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-xml_empty_context.Tpo -c -o gnumeric_sheet_context_test-xml_empty_context.o `test -f 'xml_empty_context.cpp' || echo '$(srcdir)/'`xml_empty_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-xml_empty_context.Tpo $(DEPDIR)/gnumeric_sheet_context_test-xml_empty_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_empty_context.cpp' object='gnumeric_sheet_context_test-xml_empty_context.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-xml_empty_context.o `test -f 'xml_empty_context.cpp' || echo '$(srcdir)/'`xml_empty_context.cpp + +gnumeric_sheet_context_test-xml_empty_context.obj: xml_empty_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-xml_empty_context.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-xml_empty_context.Tpo -c -o gnumeric_sheet_context_test-xml_empty_context.obj `if test -f 'xml_empty_context.cpp'; then $(CYGPATH_W) 'xml_empty_context.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_empty_context.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-xml_empty_context.Tpo $(DEPDIR)/gnumeric_sheet_context_test-xml_empty_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_empty_context.cpp' object='gnumeric_sheet_context_test-xml_empty_context.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-xml_empty_context.obj `if test -f 'xml_empty_context.cpp'; then $(CYGPATH_W) 'xml_empty_context.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_empty_context.cpp'; fi` + +gnumeric_sheet_context_test-xml_util.o: xml_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-xml_util.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-xml_util.Tpo -c -o gnumeric_sheet_context_test-xml_util.o `test -f 'xml_util.cpp' || echo '$(srcdir)/'`xml_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-xml_util.Tpo $(DEPDIR)/gnumeric_sheet_context_test-xml_util.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_util.cpp' object='gnumeric_sheet_context_test-xml_util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-xml_util.o `test -f 'xml_util.cpp' || echo '$(srcdir)/'`xml_util.cpp + +gnumeric_sheet_context_test-xml_util.obj: xml_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-xml_util.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-xml_util.Tpo -c -o gnumeric_sheet_context_test-xml_util.obj `if test -f 'xml_util.cpp'; then $(CYGPATH_W) 'xml_util.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_util.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-xml_util.Tpo $(DEPDIR)/gnumeric_sheet_context_test-xml_util.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_util.cpp' object='gnumeric_sheet_context_test-xml_util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-xml_util.obj `if test -f 'xml_util.cpp'; then $(CYGPATH_W) 'xml_util.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_util.cpp'; fi` + +gnumeric_sheet_context_test-gnumeric_namespace_types.o: gnumeric_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_namespace_types.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_namespace_types.Tpo -c -o gnumeric_sheet_context_test-gnumeric_namespace_types.o `test -f 'gnumeric_namespace_types.cpp' || echo '$(srcdir)/'`gnumeric_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_namespace_types.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_namespace_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_namespace_types.cpp' object='gnumeric_sheet_context_test-gnumeric_namespace_types.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_namespace_types.o `test -f 'gnumeric_namespace_types.cpp' || echo '$(srcdir)/'`gnumeric_namespace_types.cpp + +gnumeric_sheet_context_test-gnumeric_namespace_types.obj: gnumeric_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_namespace_types.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_namespace_types.Tpo -c -o gnumeric_sheet_context_test-gnumeric_namespace_types.obj `if test -f 'gnumeric_namespace_types.cpp'; then $(CYGPATH_W) 'gnumeric_namespace_types.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_namespace_types.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_namespace_types.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_namespace_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_namespace_types.cpp' object='gnumeric_sheet_context_test-gnumeric_namespace_types.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_namespace_types.obj `if test -f 'gnumeric_namespace_types.cpp'; then $(CYGPATH_W) 'gnumeric_namespace_types.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_namespace_types.cpp'; fi` + +gnumeric_sheet_context_test-gnumeric_tokens.o: gnumeric_tokens.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_tokens.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_tokens.Tpo -c -o gnumeric_sheet_context_test-gnumeric_tokens.o `test -f 'gnumeric_tokens.cpp' || echo '$(srcdir)/'`gnumeric_tokens.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_tokens.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_tokens.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_tokens.cpp' object='gnumeric_sheet_context_test-gnumeric_tokens.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_tokens.o `test -f 'gnumeric_tokens.cpp' || echo '$(srcdir)/'`gnumeric_tokens.cpp + +gnumeric_sheet_context_test-gnumeric_tokens.obj: gnumeric_tokens.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-gnumeric_tokens.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_tokens.Tpo -c -o gnumeric_sheet_context_test-gnumeric_tokens.obj `if test -f 'gnumeric_tokens.cpp'; then $(CYGPATH_W) 'gnumeric_tokens.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_tokens.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_tokens.Tpo $(DEPDIR)/gnumeric_sheet_context_test-gnumeric_tokens.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gnumeric_tokens.cpp' object='gnumeric_sheet_context_test-gnumeric_tokens.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-gnumeric_tokens.obj `if test -f 'gnumeric_tokens.cpp'; then $(CYGPATH_W) 'gnumeric_tokens.cpp'; else $(CYGPATH_W) '$(srcdir)/gnumeric_tokens.cpp'; fi` + +gnumeric_sheet_context_test-odf_namespace_types.o: odf_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-odf_namespace_types.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-odf_namespace_types.Tpo -c -o gnumeric_sheet_context_test-odf_namespace_types.o `test -f 'odf_namespace_types.cpp' || echo '$(srcdir)/'`odf_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-odf_namespace_types.Tpo $(DEPDIR)/gnumeric_sheet_context_test-odf_namespace_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_namespace_types.cpp' object='gnumeric_sheet_context_test-odf_namespace_types.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-odf_namespace_types.o `test -f 'odf_namespace_types.cpp' || echo '$(srcdir)/'`odf_namespace_types.cpp + +gnumeric_sheet_context_test-odf_namespace_types.obj: odf_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-odf_namespace_types.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-odf_namespace_types.Tpo -c -o gnumeric_sheet_context_test-odf_namespace_types.obj `if test -f 'odf_namespace_types.cpp'; then $(CYGPATH_W) 'odf_namespace_types.cpp'; else $(CYGPATH_W) '$(srcdir)/odf_namespace_types.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-odf_namespace_types.Tpo $(DEPDIR)/gnumeric_sheet_context_test-odf_namespace_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_namespace_types.cpp' object='gnumeric_sheet_context_test-odf_namespace_types.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-odf_namespace_types.obj `if test -f 'odf_namespace_types.cpp'; then $(CYGPATH_W) 'odf_namespace_types.cpp'; else $(CYGPATH_W) '$(srcdir)/odf_namespace_types.cpp'; fi` + +gnumeric_sheet_context_test-spreadsheet_interface.o: spreadsheet_interface.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-spreadsheet_interface.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-spreadsheet_interface.Tpo -c -o gnumeric_sheet_context_test-spreadsheet_interface.o `test -f 'spreadsheet_interface.cpp' || echo '$(srcdir)/'`spreadsheet_interface.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-spreadsheet_interface.Tpo $(DEPDIR)/gnumeric_sheet_context_test-spreadsheet_interface.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='spreadsheet_interface.cpp' object='gnumeric_sheet_context_test-spreadsheet_interface.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-spreadsheet_interface.o `test -f 'spreadsheet_interface.cpp' || echo '$(srcdir)/'`spreadsheet_interface.cpp + +gnumeric_sheet_context_test-spreadsheet_interface.obj: spreadsheet_interface.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-spreadsheet_interface.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-spreadsheet_interface.Tpo -c -o gnumeric_sheet_context_test-spreadsheet_interface.obj `if test -f 'spreadsheet_interface.cpp'; then $(CYGPATH_W) 'spreadsheet_interface.cpp'; else $(CYGPATH_W) '$(srcdir)/spreadsheet_interface.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-spreadsheet_interface.Tpo $(DEPDIR)/gnumeric_sheet_context_test-spreadsheet_interface.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='spreadsheet_interface.cpp' object='gnumeric_sheet_context_test-spreadsheet_interface.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-spreadsheet_interface.obj `if test -f 'spreadsheet_interface.cpp'; then $(CYGPATH_W) 'spreadsheet_interface.cpp'; else $(CYGPATH_W) '$(srcdir)/spreadsheet_interface.cpp'; fi` + +gnumeric_sheet_context_test-string_helper.o: string_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-string_helper.o -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-string_helper.Tpo -c -o gnumeric_sheet_context_test-string_helper.o `test -f 'string_helper.cpp' || echo '$(srcdir)/'`string_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-string_helper.Tpo $(DEPDIR)/gnumeric_sheet_context_test-string_helper.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='string_helper.cpp' object='gnumeric_sheet_context_test-string_helper.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-string_helper.o `test -f 'string_helper.cpp' || echo '$(srcdir)/'`string_helper.cpp + +gnumeric_sheet_context_test-string_helper.obj: string_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gnumeric_sheet_context_test-string_helper.obj -MD -MP -MF $(DEPDIR)/gnumeric_sheet_context_test-string_helper.Tpo -c -o gnumeric_sheet_context_test-string_helper.obj `if test -f 'string_helper.cpp'; then $(CYGPATH_W) 'string_helper.cpp'; else $(CYGPATH_W) '$(srcdir)/string_helper.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnumeric_sheet_context_test-string_helper.Tpo $(DEPDIR)/gnumeric_sheet_context_test-string_helper.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='string_helper.cpp' object='gnumeric_sheet_context_test-string_helper.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnumeric_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gnumeric_sheet_context_test-string_helper.obj `if test -f 'string_helper.cpp'; then $(CYGPATH_W) 'string_helper.cpp'; else $(CYGPATH_W) '$(srcdir)/string_helper.cpp'; fi` + +json_document_tree_test-json_document_tree.o: json_document_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(json_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT json_document_tree_test-json_document_tree.o -MD -MP -MF $(DEPDIR)/json_document_tree_test-json_document_tree.Tpo -c -o json_document_tree_test-json_document_tree.o `test -f 'json_document_tree.cpp' || echo '$(srcdir)/'`json_document_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/json_document_tree_test-json_document_tree.Tpo $(DEPDIR)/json_document_tree_test-json_document_tree.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='json_document_tree.cpp' object='json_document_tree_test-json_document_tree.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(json_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o json_document_tree_test-json_document_tree.o `test -f 'json_document_tree.cpp' || echo '$(srcdir)/'`json_document_tree.cpp + +json_document_tree_test-json_document_tree.obj: json_document_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(json_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT json_document_tree_test-json_document_tree.obj -MD -MP -MF $(DEPDIR)/json_document_tree_test-json_document_tree.Tpo -c -o json_document_tree_test-json_document_tree.obj `if test -f 'json_document_tree.cpp'; then $(CYGPATH_W) 'json_document_tree.cpp'; else $(CYGPATH_W) '$(srcdir)/json_document_tree.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/json_document_tree_test-json_document_tree.Tpo $(DEPDIR)/json_document_tree_test-json_document_tree.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='json_document_tree.cpp' object='json_document_tree_test-json_document_tree.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(json_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o json_document_tree_test-json_document_tree.obj `if test -f 'json_document_tree.cpp'; then $(CYGPATH_W) 'json_document_tree.cpp'; else $(CYGPATH_W) '$(srcdir)/json_document_tree.cpp'; fi` + +json_document_tree_test-json_util.o: json_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(json_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT json_document_tree_test-json_util.o -MD -MP -MF $(DEPDIR)/json_document_tree_test-json_util.Tpo -c -o json_document_tree_test-json_util.o `test -f 'json_util.cpp' || echo '$(srcdir)/'`json_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/json_document_tree_test-json_util.Tpo $(DEPDIR)/json_document_tree_test-json_util.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='json_util.cpp' object='json_document_tree_test-json_util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(json_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o json_document_tree_test-json_util.o `test -f 'json_util.cpp' || echo '$(srcdir)/'`json_util.cpp + +json_document_tree_test-json_util.obj: json_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(json_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT json_document_tree_test-json_util.obj -MD -MP -MF $(DEPDIR)/json_document_tree_test-json_util.Tpo -c -o json_document_tree_test-json_util.obj `if test -f 'json_util.cpp'; then $(CYGPATH_W) 'json_util.cpp'; else $(CYGPATH_W) '$(srcdir)/json_util.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/json_document_tree_test-json_util.Tpo $(DEPDIR)/json_document_tree_test-json_util.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='json_util.cpp' object='json_document_tree_test-json_util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(json_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o json_document_tree_test-json_util.obj `if test -f 'json_util.cpp'; then $(CYGPATH_W) 'json_util.cpp'; else $(CYGPATH_W) '$(srcdir)/json_util.cpp'; fi` + +json_document_tree_test-json_document_tree_test.o: json_document_tree_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(json_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT json_document_tree_test-json_document_tree_test.o -MD -MP -MF $(DEPDIR)/json_document_tree_test-json_document_tree_test.Tpo -c -o json_document_tree_test-json_document_tree_test.o `test -f 'json_document_tree_test.cpp' || echo '$(srcdir)/'`json_document_tree_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/json_document_tree_test-json_document_tree_test.Tpo $(DEPDIR)/json_document_tree_test-json_document_tree_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='json_document_tree_test.cpp' object='json_document_tree_test-json_document_tree_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(json_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o json_document_tree_test-json_document_tree_test.o `test -f 'json_document_tree_test.cpp' || echo '$(srcdir)/'`json_document_tree_test.cpp + +json_document_tree_test-json_document_tree_test.obj: json_document_tree_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(json_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT json_document_tree_test-json_document_tree_test.obj -MD -MP -MF $(DEPDIR)/json_document_tree_test-json_document_tree_test.Tpo -c -o json_document_tree_test-json_document_tree_test.obj `if test -f 'json_document_tree_test.cpp'; then $(CYGPATH_W) 'json_document_tree_test.cpp'; else $(CYGPATH_W) '$(srcdir)/json_document_tree_test.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/json_document_tree_test-json_document_tree_test.Tpo $(DEPDIR)/json_document_tree_test-json_document_tree_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='json_document_tree_test.cpp' object='json_document_tree_test-json_document_tree_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(json_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o json_document_tree_test-json_document_tree_test.obj `if test -f 'json_document_tree_test.cpp'; then $(CYGPATH_W) 'json_document_tree_test.cpp'; else $(CYGPATH_W) '$(srcdir)/json_document_tree_test.cpp'; fi` + +odf_helper_test-odf_helper.o: odf_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(odf_helper_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT odf_helper_test-odf_helper.o -MD -MP -MF $(DEPDIR)/odf_helper_test-odf_helper.Tpo -c -o odf_helper_test-odf_helper.o `test -f 'odf_helper.cpp' || echo '$(srcdir)/'`odf_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/odf_helper_test-odf_helper.Tpo $(DEPDIR)/odf_helper_test-odf_helper.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_helper.cpp' object='odf_helper_test-odf_helper.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(odf_helper_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o odf_helper_test-odf_helper.o `test -f 'odf_helper.cpp' || echo '$(srcdir)/'`odf_helper.cpp + +odf_helper_test-odf_helper.obj: odf_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(odf_helper_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT odf_helper_test-odf_helper.obj -MD -MP -MF $(DEPDIR)/odf_helper_test-odf_helper.Tpo -c -o odf_helper_test-odf_helper.obj `if test -f 'odf_helper.cpp'; then $(CYGPATH_W) 'odf_helper.cpp'; else $(CYGPATH_W) '$(srcdir)/odf_helper.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/odf_helper_test-odf_helper.Tpo $(DEPDIR)/odf_helper_test-odf_helper.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_helper.cpp' object='odf_helper_test-odf_helper.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(odf_helper_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o odf_helper_test-odf_helper.obj `if test -f 'odf_helper.cpp'; then $(CYGPATH_W) 'odf_helper.cpp'; else $(CYGPATH_W) '$(srcdir)/odf_helper.cpp'; fi` + +odf_helper_test-string_helper.o: string_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(odf_helper_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT odf_helper_test-string_helper.o -MD -MP -MF $(DEPDIR)/odf_helper_test-string_helper.Tpo -c -o odf_helper_test-string_helper.o `test -f 'string_helper.cpp' || echo '$(srcdir)/'`string_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/odf_helper_test-string_helper.Tpo $(DEPDIR)/odf_helper_test-string_helper.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='string_helper.cpp' object='odf_helper_test-string_helper.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(odf_helper_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o odf_helper_test-string_helper.o `test -f 'string_helper.cpp' || echo '$(srcdir)/'`string_helper.cpp + +odf_helper_test-string_helper.obj: string_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(odf_helper_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT odf_helper_test-string_helper.obj -MD -MP -MF $(DEPDIR)/odf_helper_test-string_helper.Tpo -c -o odf_helper_test-string_helper.obj `if test -f 'string_helper.cpp'; then $(CYGPATH_W) 'string_helper.cpp'; else $(CYGPATH_W) '$(srcdir)/string_helper.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/odf_helper_test-string_helper.Tpo $(DEPDIR)/odf_helper_test-string_helper.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='string_helper.cpp' object='odf_helper_test-string_helper.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(odf_helper_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o odf_helper_test-string_helper.obj `if test -f 'string_helper.cpp'; then $(CYGPATH_W) 'string_helper.cpp'; else $(CYGPATH_W) '$(srcdir)/string_helper.cpp'; fi` + +odf_helper_test-odf_helper_test.o: odf_helper_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(odf_helper_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT odf_helper_test-odf_helper_test.o -MD -MP -MF $(DEPDIR)/odf_helper_test-odf_helper_test.Tpo -c -o odf_helper_test-odf_helper_test.o `test -f 'odf_helper_test.cpp' || echo '$(srcdir)/'`odf_helper_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/odf_helper_test-odf_helper_test.Tpo $(DEPDIR)/odf_helper_test-odf_helper_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_helper_test.cpp' object='odf_helper_test-odf_helper_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(odf_helper_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o odf_helper_test-odf_helper_test.o `test -f 'odf_helper_test.cpp' || echo '$(srcdir)/'`odf_helper_test.cpp + +odf_helper_test-odf_helper_test.obj: odf_helper_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(odf_helper_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT odf_helper_test-odf_helper_test.obj -MD -MP -MF $(DEPDIR)/odf_helper_test-odf_helper_test.Tpo -c -o odf_helper_test-odf_helper_test.obj `if test -f 'odf_helper_test.cpp'; then $(CYGPATH_W) 'odf_helper_test.cpp'; else $(CYGPATH_W) '$(srcdir)/odf_helper_test.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/odf_helper_test-odf_helper_test.Tpo $(DEPDIR)/odf_helper_test-odf_helper_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='odf_helper_test.cpp' object='odf_helper_test-odf_helper_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(odf_helper_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o odf_helper_test-odf_helper_test.obj `if test -f 'odf_helper_test.cpp'; then $(CYGPATH_W) 'odf_helper_test.cpp'; else $(CYGPATH_W) '$(srcdir)/odf_helper_test.cpp'; fi` + +xlsx_sheet_context_test-formula_result.o: formula_result.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-formula_result.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-formula_result.Tpo -c -o xlsx_sheet_context_test-formula_result.o `test -f 'formula_result.cpp' || echo '$(srcdir)/'`formula_result.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-formula_result.Tpo $(DEPDIR)/xlsx_sheet_context_test-formula_result.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='formula_result.cpp' object='xlsx_sheet_context_test-formula_result.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-formula_result.o `test -f 'formula_result.cpp' || echo '$(srcdir)/'`formula_result.cpp + +xlsx_sheet_context_test-formula_result.obj: formula_result.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-formula_result.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-formula_result.Tpo -c -o xlsx_sheet_context_test-formula_result.obj `if test -f 'formula_result.cpp'; then $(CYGPATH_W) 'formula_result.cpp'; else $(CYGPATH_W) '$(srcdir)/formula_result.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-formula_result.Tpo $(DEPDIR)/xlsx_sheet_context_test-formula_result.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='formula_result.cpp' object='xlsx_sheet_context_test-formula_result.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-formula_result.obj `if test -f 'formula_result.cpp'; then $(CYGPATH_W) 'formula_result.cpp'; else $(CYGPATH_W) '$(srcdir)/formula_result.cpp'; fi` + +xlsx_sheet_context_test-ooxml_global.o: ooxml_global.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-ooxml_global.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-ooxml_global.Tpo -c -o xlsx_sheet_context_test-ooxml_global.o `test -f 'ooxml_global.cpp' || echo '$(srcdir)/'`ooxml_global.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-ooxml_global.Tpo $(DEPDIR)/xlsx_sheet_context_test-ooxml_global.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_global.cpp' object='xlsx_sheet_context_test-ooxml_global.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-ooxml_global.o `test -f 'ooxml_global.cpp' || echo '$(srcdir)/'`ooxml_global.cpp + +xlsx_sheet_context_test-ooxml_global.obj: ooxml_global.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-ooxml_global.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-ooxml_global.Tpo -c -o xlsx_sheet_context_test-ooxml_global.obj `if test -f 'ooxml_global.cpp'; then $(CYGPATH_W) 'ooxml_global.cpp'; else $(CYGPATH_W) '$(srcdir)/ooxml_global.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-ooxml_global.Tpo $(DEPDIR)/xlsx_sheet_context_test-ooxml_global.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_global.cpp' object='xlsx_sheet_context_test-ooxml_global.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-ooxml_global.obj `if test -f 'ooxml_global.cpp'; then $(CYGPATH_W) 'ooxml_global.cpp'; else $(CYGPATH_W) '$(srcdir)/ooxml_global.cpp'; fi` + +xlsx_sheet_context_test-ooxml_namespace_types.o: ooxml_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-ooxml_namespace_types.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-ooxml_namespace_types.Tpo -c -o xlsx_sheet_context_test-ooxml_namespace_types.o `test -f 'ooxml_namespace_types.cpp' || echo '$(srcdir)/'`ooxml_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-ooxml_namespace_types.Tpo $(DEPDIR)/xlsx_sheet_context_test-ooxml_namespace_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_namespace_types.cpp' object='xlsx_sheet_context_test-ooxml_namespace_types.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-ooxml_namespace_types.o `test -f 'ooxml_namespace_types.cpp' || echo '$(srcdir)/'`ooxml_namespace_types.cpp + +xlsx_sheet_context_test-ooxml_namespace_types.obj: ooxml_namespace_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-ooxml_namespace_types.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-ooxml_namespace_types.Tpo -c -o xlsx_sheet_context_test-ooxml_namespace_types.obj `if test -f 'ooxml_namespace_types.cpp'; then $(CYGPATH_W) 'ooxml_namespace_types.cpp'; else $(CYGPATH_W) '$(srcdir)/ooxml_namespace_types.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-ooxml_namespace_types.Tpo $(DEPDIR)/xlsx_sheet_context_test-ooxml_namespace_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_namespace_types.cpp' object='xlsx_sheet_context_test-ooxml_namespace_types.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-ooxml_namespace_types.obj `if test -f 'ooxml_namespace_types.cpp'; then $(CYGPATH_W) 'ooxml_namespace_types.cpp'; else $(CYGPATH_W) '$(srcdir)/ooxml_namespace_types.cpp'; fi` + +xlsx_sheet_context_test-ooxml_schemas.o: ooxml_schemas.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-ooxml_schemas.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-ooxml_schemas.Tpo -c -o xlsx_sheet_context_test-ooxml_schemas.o `test -f 'ooxml_schemas.cpp' || echo '$(srcdir)/'`ooxml_schemas.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-ooxml_schemas.Tpo $(DEPDIR)/xlsx_sheet_context_test-ooxml_schemas.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_schemas.cpp' object='xlsx_sheet_context_test-ooxml_schemas.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-ooxml_schemas.o `test -f 'ooxml_schemas.cpp' || echo '$(srcdir)/'`ooxml_schemas.cpp + +xlsx_sheet_context_test-ooxml_schemas.obj: ooxml_schemas.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-ooxml_schemas.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-ooxml_schemas.Tpo -c -o xlsx_sheet_context_test-ooxml_schemas.obj `if test -f 'ooxml_schemas.cpp'; then $(CYGPATH_W) 'ooxml_schemas.cpp'; else $(CYGPATH_W) '$(srcdir)/ooxml_schemas.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-ooxml_schemas.Tpo $(DEPDIR)/xlsx_sheet_context_test-ooxml_schemas.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_schemas.cpp' object='xlsx_sheet_context_test-ooxml_schemas.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-ooxml_schemas.obj `if test -f 'ooxml_schemas.cpp'; then $(CYGPATH_W) 'ooxml_schemas.cpp'; else $(CYGPATH_W) '$(srcdir)/ooxml_schemas.cpp'; fi` + +xlsx_sheet_context_test-ooxml_tokens.o: ooxml_tokens.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-ooxml_tokens.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-ooxml_tokens.Tpo -c -o xlsx_sheet_context_test-ooxml_tokens.o `test -f 'ooxml_tokens.cpp' || echo '$(srcdir)/'`ooxml_tokens.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-ooxml_tokens.Tpo $(DEPDIR)/xlsx_sheet_context_test-ooxml_tokens.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_tokens.cpp' object='xlsx_sheet_context_test-ooxml_tokens.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-ooxml_tokens.o `test -f 'ooxml_tokens.cpp' || echo '$(srcdir)/'`ooxml_tokens.cpp + +xlsx_sheet_context_test-ooxml_tokens.obj: ooxml_tokens.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-ooxml_tokens.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-ooxml_tokens.Tpo -c -o xlsx_sheet_context_test-ooxml_tokens.obj `if test -f 'ooxml_tokens.cpp'; then $(CYGPATH_W) 'ooxml_tokens.cpp'; else $(CYGPATH_W) '$(srcdir)/ooxml_tokens.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-ooxml_tokens.Tpo $(DEPDIR)/xlsx_sheet_context_test-ooxml_tokens.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_tokens.cpp' object='xlsx_sheet_context_test-ooxml_tokens.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-ooxml_tokens.obj `if test -f 'ooxml_tokens.cpp'; then $(CYGPATH_W) 'ooxml_tokens.cpp'; else $(CYGPATH_W) '$(srcdir)/ooxml_tokens.cpp'; fi` + +xlsx_sheet_context_test-ooxml_types.o: ooxml_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-ooxml_types.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-ooxml_types.Tpo -c -o xlsx_sheet_context_test-ooxml_types.o `test -f 'ooxml_types.cpp' || echo '$(srcdir)/'`ooxml_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-ooxml_types.Tpo $(DEPDIR)/xlsx_sheet_context_test-ooxml_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_types.cpp' object='xlsx_sheet_context_test-ooxml_types.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-ooxml_types.o `test -f 'ooxml_types.cpp' || echo '$(srcdir)/'`ooxml_types.cpp + +xlsx_sheet_context_test-ooxml_types.obj: ooxml_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-ooxml_types.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-ooxml_types.Tpo -c -o xlsx_sheet_context_test-ooxml_types.obj `if test -f 'ooxml_types.cpp'; then $(CYGPATH_W) 'ooxml_types.cpp'; else $(CYGPATH_W) '$(srcdir)/ooxml_types.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-ooxml_types.Tpo $(DEPDIR)/xlsx_sheet_context_test-ooxml_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ooxml_types.cpp' object='xlsx_sheet_context_test-ooxml_types.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-ooxml_types.obj `if test -f 'ooxml_types.cpp'; then $(CYGPATH_W) 'ooxml_types.cpp'; else $(CYGPATH_W) '$(srcdir)/ooxml_types.cpp'; fi` + +xlsx_sheet_context_test-session_context.o: session_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-session_context.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-session_context.Tpo -c -o xlsx_sheet_context_test-session_context.o `test -f 'session_context.cpp' || echo '$(srcdir)/'`session_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-session_context.Tpo $(DEPDIR)/xlsx_sheet_context_test-session_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='session_context.cpp' object='xlsx_sheet_context_test-session_context.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-session_context.o `test -f 'session_context.cpp' || echo '$(srcdir)/'`session_context.cpp + +xlsx_sheet_context_test-session_context.obj: session_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-session_context.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-session_context.Tpo -c -o xlsx_sheet_context_test-session_context.obj `if test -f 'session_context.cpp'; then $(CYGPATH_W) 'session_context.cpp'; else $(CYGPATH_W) '$(srcdir)/session_context.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-session_context.Tpo $(DEPDIR)/xlsx_sheet_context_test-session_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='session_context.cpp' object='xlsx_sheet_context_test-session_context.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-session_context.obj `if test -f 'session_context.cpp'; then $(CYGPATH_W) 'session_context.cpp'; else $(CYGPATH_W) '$(srcdir)/session_context.cpp'; fi` + +xlsx_sheet_context_test-spreadsheet_interface.o: spreadsheet_interface.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-spreadsheet_interface.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-spreadsheet_interface.Tpo -c -o xlsx_sheet_context_test-spreadsheet_interface.o `test -f 'spreadsheet_interface.cpp' || echo '$(srcdir)/'`spreadsheet_interface.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-spreadsheet_interface.Tpo $(DEPDIR)/xlsx_sheet_context_test-spreadsheet_interface.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='spreadsheet_interface.cpp' object='xlsx_sheet_context_test-spreadsheet_interface.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-spreadsheet_interface.o `test -f 'spreadsheet_interface.cpp' || echo '$(srcdir)/'`spreadsheet_interface.cpp + +xlsx_sheet_context_test-spreadsheet_interface.obj: spreadsheet_interface.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-spreadsheet_interface.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-spreadsheet_interface.Tpo -c -o xlsx_sheet_context_test-spreadsheet_interface.obj `if test -f 'spreadsheet_interface.cpp'; then $(CYGPATH_W) 'spreadsheet_interface.cpp'; else $(CYGPATH_W) '$(srcdir)/spreadsheet_interface.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-spreadsheet_interface.Tpo $(DEPDIR)/xlsx_sheet_context_test-spreadsheet_interface.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='spreadsheet_interface.cpp' object='xlsx_sheet_context_test-spreadsheet_interface.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-spreadsheet_interface.obj `if test -f 'spreadsheet_interface.cpp'; then $(CYGPATH_W) 'spreadsheet_interface.cpp'; else $(CYGPATH_W) '$(srcdir)/spreadsheet_interface.cpp'; fi` + +xlsx_sheet_context_test-xlsx_autofilter_context.o: xlsx_autofilter_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xlsx_autofilter_context.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xlsx_autofilter_context.Tpo -c -o xlsx_sheet_context_test-xlsx_autofilter_context.o `test -f 'xlsx_autofilter_context.cpp' || echo '$(srcdir)/'`xlsx_autofilter_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xlsx_autofilter_context.Tpo $(DEPDIR)/xlsx_sheet_context_test-xlsx_autofilter_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_autofilter_context.cpp' object='xlsx_sheet_context_test-xlsx_autofilter_context.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xlsx_autofilter_context.o `test -f 'xlsx_autofilter_context.cpp' || echo '$(srcdir)/'`xlsx_autofilter_context.cpp + +xlsx_sheet_context_test-xlsx_autofilter_context.obj: xlsx_autofilter_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xlsx_autofilter_context.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xlsx_autofilter_context.Tpo -c -o xlsx_sheet_context_test-xlsx_autofilter_context.obj `if test -f 'xlsx_autofilter_context.cpp'; then $(CYGPATH_W) 'xlsx_autofilter_context.cpp'; else $(CYGPATH_W) '$(srcdir)/xlsx_autofilter_context.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xlsx_autofilter_context.Tpo $(DEPDIR)/xlsx_sheet_context_test-xlsx_autofilter_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_autofilter_context.cpp' object='xlsx_sheet_context_test-xlsx_autofilter_context.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xlsx_autofilter_context.obj `if test -f 'xlsx_autofilter_context.cpp'; then $(CYGPATH_W) 'xlsx_autofilter_context.cpp'; else $(CYGPATH_W) '$(srcdir)/xlsx_autofilter_context.cpp'; fi` + +xlsx_sheet_context_test-xlsx_conditional_format_context.o: xlsx_conditional_format_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xlsx_conditional_format_context.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xlsx_conditional_format_context.Tpo -c -o xlsx_sheet_context_test-xlsx_conditional_format_context.o `test -f 'xlsx_conditional_format_context.cpp' || echo '$(srcdir)/'`xlsx_conditional_format_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xlsx_conditional_format_context.Tpo $(DEPDIR)/xlsx_sheet_context_test-xlsx_conditional_format_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_conditional_format_context.cpp' object='xlsx_sheet_context_test-xlsx_conditional_format_context.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xlsx_conditional_format_context.o `test -f 'xlsx_conditional_format_context.cpp' || echo '$(srcdir)/'`xlsx_conditional_format_context.cpp + +xlsx_sheet_context_test-xlsx_conditional_format_context.obj: xlsx_conditional_format_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xlsx_conditional_format_context.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xlsx_conditional_format_context.Tpo -c -o xlsx_sheet_context_test-xlsx_conditional_format_context.obj `if test -f 'xlsx_conditional_format_context.cpp'; then $(CYGPATH_W) 'xlsx_conditional_format_context.cpp'; else $(CYGPATH_W) '$(srcdir)/xlsx_conditional_format_context.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xlsx_conditional_format_context.Tpo $(DEPDIR)/xlsx_sheet_context_test-xlsx_conditional_format_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_conditional_format_context.cpp' object='xlsx_sheet_context_test-xlsx_conditional_format_context.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xlsx_conditional_format_context.obj `if test -f 'xlsx_conditional_format_context.cpp'; then $(CYGPATH_W) 'xlsx_conditional_format_context.cpp'; else $(CYGPATH_W) '$(srcdir)/xlsx_conditional_format_context.cpp'; fi` + +xlsx_sheet_context_test-xlsx_helper.o: xlsx_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xlsx_helper.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xlsx_helper.Tpo -c -o xlsx_sheet_context_test-xlsx_helper.o `test -f 'xlsx_helper.cpp' || echo '$(srcdir)/'`xlsx_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xlsx_helper.Tpo $(DEPDIR)/xlsx_sheet_context_test-xlsx_helper.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_helper.cpp' object='xlsx_sheet_context_test-xlsx_helper.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xlsx_helper.o `test -f 'xlsx_helper.cpp' || echo '$(srcdir)/'`xlsx_helper.cpp + +xlsx_sheet_context_test-xlsx_helper.obj: xlsx_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xlsx_helper.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xlsx_helper.Tpo -c -o xlsx_sheet_context_test-xlsx_helper.obj `if test -f 'xlsx_helper.cpp'; then $(CYGPATH_W) 'xlsx_helper.cpp'; else $(CYGPATH_W) '$(srcdir)/xlsx_helper.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xlsx_helper.Tpo $(DEPDIR)/xlsx_sheet_context_test-xlsx_helper.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_helper.cpp' object='xlsx_sheet_context_test-xlsx_helper.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xlsx_helper.obj `if test -f 'xlsx_helper.cpp'; then $(CYGPATH_W) 'xlsx_helper.cpp'; else $(CYGPATH_W) '$(srcdir)/xlsx_helper.cpp'; fi` + +xlsx_sheet_context_test-xlsx_session_data.o: xlsx_session_data.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xlsx_session_data.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xlsx_session_data.Tpo -c -o xlsx_sheet_context_test-xlsx_session_data.o `test -f 'xlsx_session_data.cpp' || echo '$(srcdir)/'`xlsx_session_data.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xlsx_session_data.Tpo $(DEPDIR)/xlsx_sheet_context_test-xlsx_session_data.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_session_data.cpp' object='xlsx_sheet_context_test-xlsx_session_data.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xlsx_session_data.o `test -f 'xlsx_session_data.cpp' || echo '$(srcdir)/'`xlsx_session_data.cpp + +xlsx_sheet_context_test-xlsx_session_data.obj: xlsx_session_data.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xlsx_session_data.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xlsx_session_data.Tpo -c -o xlsx_sheet_context_test-xlsx_session_data.obj `if test -f 'xlsx_session_data.cpp'; then $(CYGPATH_W) 'xlsx_session_data.cpp'; else $(CYGPATH_W) '$(srcdir)/xlsx_session_data.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xlsx_session_data.Tpo $(DEPDIR)/xlsx_sheet_context_test-xlsx_session_data.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_session_data.cpp' object='xlsx_sheet_context_test-xlsx_session_data.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xlsx_session_data.obj `if test -f 'xlsx_session_data.cpp'; then $(CYGPATH_W) 'xlsx_session_data.cpp'; else $(CYGPATH_W) '$(srcdir)/xlsx_session_data.cpp'; fi` + +xlsx_sheet_context_test-xlsx_sheet_context.o: xlsx_sheet_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xlsx_sheet_context.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context.Tpo -c -o xlsx_sheet_context_test-xlsx_sheet_context.o `test -f 'xlsx_sheet_context.cpp' || echo '$(srcdir)/'`xlsx_sheet_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context.Tpo $(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_sheet_context.cpp' object='xlsx_sheet_context_test-xlsx_sheet_context.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xlsx_sheet_context.o `test -f 'xlsx_sheet_context.cpp' || echo '$(srcdir)/'`xlsx_sheet_context.cpp + +xlsx_sheet_context_test-xlsx_sheet_context.obj: xlsx_sheet_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xlsx_sheet_context.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context.Tpo -c -o xlsx_sheet_context_test-xlsx_sheet_context.obj `if test -f 'xlsx_sheet_context.cpp'; then $(CYGPATH_W) 'xlsx_sheet_context.cpp'; else $(CYGPATH_W) '$(srcdir)/xlsx_sheet_context.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context.Tpo $(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_sheet_context.cpp' object='xlsx_sheet_context_test-xlsx_sheet_context.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xlsx_sheet_context.obj `if test -f 'xlsx_sheet_context.cpp'; then $(CYGPATH_W) 'xlsx_sheet_context.cpp'; else $(CYGPATH_W) '$(srcdir)/xlsx_sheet_context.cpp'; fi` + +xlsx_sheet_context_test-xlsx_sheet_context_test.o: xlsx_sheet_context_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xlsx_sheet_context_test.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context_test.Tpo -c -o xlsx_sheet_context_test-xlsx_sheet_context_test.o `test -f 'xlsx_sheet_context_test.cpp' || echo '$(srcdir)/'`xlsx_sheet_context_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context_test.Tpo $(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_sheet_context_test.cpp' object='xlsx_sheet_context_test-xlsx_sheet_context_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xlsx_sheet_context_test.o `test -f 'xlsx_sheet_context_test.cpp' || echo '$(srcdir)/'`xlsx_sheet_context_test.cpp + +xlsx_sheet_context_test-xlsx_sheet_context_test.obj: xlsx_sheet_context_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xlsx_sheet_context_test.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context_test.Tpo -c -o xlsx_sheet_context_test-xlsx_sheet_context_test.obj `if test -f 'xlsx_sheet_context_test.cpp'; then $(CYGPATH_W) 'xlsx_sheet_context_test.cpp'; else $(CYGPATH_W) '$(srcdir)/xlsx_sheet_context_test.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context_test.Tpo $(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_sheet_context_test.cpp' object='xlsx_sheet_context_test-xlsx_sheet_context_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xlsx_sheet_context_test.obj `if test -f 'xlsx_sheet_context_test.cpp'; then $(CYGPATH_W) 'xlsx_sheet_context_test.cpp'; else $(CYGPATH_W) '$(srcdir)/xlsx_sheet_context_test.cpp'; fi` + +xlsx_sheet_context_test-xlsx_types.o: xlsx_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xlsx_types.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xlsx_types.Tpo -c -o xlsx_sheet_context_test-xlsx_types.o `test -f 'xlsx_types.cpp' || echo '$(srcdir)/'`xlsx_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xlsx_types.Tpo $(DEPDIR)/xlsx_sheet_context_test-xlsx_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_types.cpp' object='xlsx_sheet_context_test-xlsx_types.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xlsx_types.o `test -f 'xlsx_types.cpp' || echo '$(srcdir)/'`xlsx_types.cpp + +xlsx_sheet_context_test-xlsx_types.obj: xlsx_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xlsx_types.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xlsx_types.Tpo -c -o xlsx_sheet_context_test-xlsx_types.obj `if test -f 'xlsx_types.cpp'; then $(CYGPATH_W) 'xlsx_types.cpp'; else $(CYGPATH_W) '$(srcdir)/xlsx_types.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xlsx_types.Tpo $(DEPDIR)/xlsx_sheet_context_test-xlsx_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xlsx_types.cpp' object='xlsx_sheet_context_test-xlsx_types.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xlsx_types.obj `if test -f 'xlsx_types.cpp'; then $(CYGPATH_W) 'xlsx_types.cpp'; else $(CYGPATH_W) '$(srcdir)/xlsx_types.cpp'; fi` + +xlsx_sheet_context_test-xml_context_base.o: xml_context_base.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xml_context_base.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xml_context_base.Tpo -c -o xlsx_sheet_context_test-xml_context_base.o `test -f 'xml_context_base.cpp' || echo '$(srcdir)/'`xml_context_base.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xml_context_base.Tpo $(DEPDIR)/xlsx_sheet_context_test-xml_context_base.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_context_base.cpp' object='xlsx_sheet_context_test-xml_context_base.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xml_context_base.o `test -f 'xml_context_base.cpp' || echo '$(srcdir)/'`xml_context_base.cpp + +xlsx_sheet_context_test-xml_context_base.obj: xml_context_base.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xml_context_base.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xml_context_base.Tpo -c -o xlsx_sheet_context_test-xml_context_base.obj `if test -f 'xml_context_base.cpp'; then $(CYGPATH_W) 'xml_context_base.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_context_base.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xml_context_base.Tpo $(DEPDIR)/xlsx_sheet_context_test-xml_context_base.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_context_base.cpp' object='xlsx_sheet_context_test-xml_context_base.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xml_context_base.obj `if test -f 'xml_context_base.cpp'; then $(CYGPATH_W) 'xml_context_base.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_context_base.cpp'; fi` + +xlsx_sheet_context_test-xml_context_global.o: xml_context_global.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xml_context_global.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xml_context_global.Tpo -c -o xlsx_sheet_context_test-xml_context_global.o `test -f 'xml_context_global.cpp' || echo '$(srcdir)/'`xml_context_global.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xml_context_global.Tpo $(DEPDIR)/xlsx_sheet_context_test-xml_context_global.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_context_global.cpp' object='xlsx_sheet_context_test-xml_context_global.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xml_context_global.o `test -f 'xml_context_global.cpp' || echo '$(srcdir)/'`xml_context_global.cpp + +xlsx_sheet_context_test-xml_context_global.obj: xml_context_global.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xml_context_global.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xml_context_global.Tpo -c -o xlsx_sheet_context_test-xml_context_global.obj `if test -f 'xml_context_global.cpp'; then $(CYGPATH_W) 'xml_context_global.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_context_global.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xml_context_global.Tpo $(DEPDIR)/xlsx_sheet_context_test-xml_context_global.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_context_global.cpp' object='xlsx_sheet_context_test-xml_context_global.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xml_context_global.obj `if test -f 'xml_context_global.cpp'; then $(CYGPATH_W) 'xml_context_global.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_context_global.cpp'; fi` + +xlsx_sheet_context_test-xml_element_types.o: xml_element_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xml_element_types.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xml_element_types.Tpo -c -o xlsx_sheet_context_test-xml_element_types.o `test -f 'xml_element_types.cpp' || echo '$(srcdir)/'`xml_element_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xml_element_types.Tpo $(DEPDIR)/xlsx_sheet_context_test-xml_element_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_element_types.cpp' object='xlsx_sheet_context_test-xml_element_types.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xml_element_types.o `test -f 'xml_element_types.cpp' || echo '$(srcdir)/'`xml_element_types.cpp + +xlsx_sheet_context_test-xml_element_types.obj: xml_element_types.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xml_element_types.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xml_element_types.Tpo -c -o xlsx_sheet_context_test-xml_element_types.obj `if test -f 'xml_element_types.cpp'; then $(CYGPATH_W) 'xml_element_types.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_element_types.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xml_element_types.Tpo $(DEPDIR)/xlsx_sheet_context_test-xml_element_types.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_element_types.cpp' object='xlsx_sheet_context_test-xml_element_types.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xml_element_types.obj `if test -f 'xml_element_types.cpp'; then $(CYGPATH_W) 'xml_element_types.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_element_types.cpp'; fi` + +xlsx_sheet_context_test-xml_element_validator.o: xml_element_validator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xml_element_validator.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xml_element_validator.Tpo -c -o xlsx_sheet_context_test-xml_element_validator.o `test -f 'xml_element_validator.cpp' || echo '$(srcdir)/'`xml_element_validator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xml_element_validator.Tpo $(DEPDIR)/xlsx_sheet_context_test-xml_element_validator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_element_validator.cpp' object='xlsx_sheet_context_test-xml_element_validator.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xml_element_validator.o `test -f 'xml_element_validator.cpp' || echo '$(srcdir)/'`xml_element_validator.cpp + +xlsx_sheet_context_test-xml_element_validator.obj: xml_element_validator.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xml_element_validator.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xml_element_validator.Tpo -c -o xlsx_sheet_context_test-xml_element_validator.obj `if test -f 'xml_element_validator.cpp'; then $(CYGPATH_W) 'xml_element_validator.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_element_validator.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xml_element_validator.Tpo $(DEPDIR)/xlsx_sheet_context_test-xml_element_validator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_element_validator.cpp' object='xlsx_sheet_context_test-xml_element_validator.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xml_element_validator.obj `if test -f 'xml_element_validator.cpp'; then $(CYGPATH_W) 'xml_element_validator.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_element_validator.cpp'; fi` + +xlsx_sheet_context_test-xml_empty_context.o: xml_empty_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xml_empty_context.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xml_empty_context.Tpo -c -o xlsx_sheet_context_test-xml_empty_context.o `test -f 'xml_empty_context.cpp' || echo '$(srcdir)/'`xml_empty_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xml_empty_context.Tpo $(DEPDIR)/xlsx_sheet_context_test-xml_empty_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_empty_context.cpp' object='xlsx_sheet_context_test-xml_empty_context.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xml_empty_context.o `test -f 'xml_empty_context.cpp' || echo '$(srcdir)/'`xml_empty_context.cpp + +xlsx_sheet_context_test-xml_empty_context.obj: xml_empty_context.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xml_empty_context.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xml_empty_context.Tpo -c -o xlsx_sheet_context_test-xml_empty_context.obj `if test -f 'xml_empty_context.cpp'; then $(CYGPATH_W) 'xml_empty_context.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_empty_context.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xml_empty_context.Tpo $(DEPDIR)/xlsx_sheet_context_test-xml_empty_context.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_empty_context.cpp' object='xlsx_sheet_context_test-xml_empty_context.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xml_empty_context.obj `if test -f 'xml_empty_context.cpp'; then $(CYGPATH_W) 'xml_empty_context.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_empty_context.cpp'; fi` + +xlsx_sheet_context_test-xml_util.o: xml_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xml_util.o -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xml_util.Tpo -c -o xlsx_sheet_context_test-xml_util.o `test -f 'xml_util.cpp' || echo '$(srcdir)/'`xml_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xml_util.Tpo $(DEPDIR)/xlsx_sheet_context_test-xml_util.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_util.cpp' object='xlsx_sheet_context_test-xml_util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xml_util.o `test -f 'xml_util.cpp' || echo '$(srcdir)/'`xml_util.cpp + +xlsx_sheet_context_test-xml_util.obj: xml_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xlsx_sheet_context_test-xml_util.obj -MD -MP -MF $(DEPDIR)/xlsx_sheet_context_test-xml_util.Tpo -c -o xlsx_sheet_context_test-xml_util.obj `if test -f 'xml_util.cpp'; then $(CYGPATH_W) 'xml_util.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_util.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xlsx_sheet_context_test-xml_util.Tpo $(DEPDIR)/xlsx_sheet_context_test-xml_util.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_util.cpp' object='xlsx_sheet_context_test-xml_util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xlsx_sheet_context_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xlsx_sheet_context_test-xml_util.obj `if test -f 'xml_util.cpp'; then $(CYGPATH_W) 'xml_util.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_util.cpp'; fi` + +xml_structure_tree_test-string_helper.o: string_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xml_structure_tree_test-string_helper.o -MD -MP -MF $(DEPDIR)/xml_structure_tree_test-string_helper.Tpo -c -o xml_structure_tree_test-string_helper.o `test -f 'string_helper.cpp' || echo '$(srcdir)/'`string_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xml_structure_tree_test-string_helper.Tpo $(DEPDIR)/xml_structure_tree_test-string_helper.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='string_helper.cpp' object='xml_structure_tree_test-string_helper.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xml_structure_tree_test-string_helper.o `test -f 'string_helper.cpp' || echo '$(srcdir)/'`string_helper.cpp + +xml_structure_tree_test-string_helper.obj: string_helper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xml_structure_tree_test-string_helper.obj -MD -MP -MF $(DEPDIR)/xml_structure_tree_test-string_helper.Tpo -c -o xml_structure_tree_test-string_helper.obj `if test -f 'string_helper.cpp'; then $(CYGPATH_W) 'string_helper.cpp'; else $(CYGPATH_W) '$(srcdir)/string_helper.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xml_structure_tree_test-string_helper.Tpo $(DEPDIR)/xml_structure_tree_test-string_helper.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='string_helper.cpp' object='xml_structure_tree_test-string_helper.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xml_structure_tree_test-string_helper.obj `if test -f 'string_helper.cpp'; then $(CYGPATH_W) 'string_helper.cpp'; else $(CYGPATH_W) '$(srcdir)/string_helper.cpp'; fi` + +xml_structure_tree_test-xml_structure_tree.o: xml_structure_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xml_structure_tree_test-xml_structure_tree.o -MD -MP -MF $(DEPDIR)/xml_structure_tree_test-xml_structure_tree.Tpo -c -o xml_structure_tree_test-xml_structure_tree.o `test -f 'xml_structure_tree.cpp' || echo '$(srcdir)/'`xml_structure_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xml_structure_tree_test-xml_structure_tree.Tpo $(DEPDIR)/xml_structure_tree_test-xml_structure_tree.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_structure_tree.cpp' object='xml_structure_tree_test-xml_structure_tree.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xml_structure_tree_test-xml_structure_tree.o `test -f 'xml_structure_tree.cpp' || echo '$(srcdir)/'`xml_structure_tree.cpp + +xml_structure_tree_test-xml_structure_tree.obj: xml_structure_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xml_structure_tree_test-xml_structure_tree.obj -MD -MP -MF $(DEPDIR)/xml_structure_tree_test-xml_structure_tree.Tpo -c -o xml_structure_tree_test-xml_structure_tree.obj `if test -f 'xml_structure_tree.cpp'; then $(CYGPATH_W) 'xml_structure_tree.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_structure_tree.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xml_structure_tree_test-xml_structure_tree.Tpo $(DEPDIR)/xml_structure_tree_test-xml_structure_tree.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_structure_tree.cpp' object='xml_structure_tree_test-xml_structure_tree.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xml_structure_tree_test-xml_structure_tree.obj `if test -f 'xml_structure_tree.cpp'; then $(CYGPATH_W) 'xml_structure_tree.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_structure_tree.cpp'; fi` + +xml_structure_tree_test-xml_structure_mapper.o: xml_structure_mapper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xml_structure_tree_test-xml_structure_mapper.o -MD -MP -MF $(DEPDIR)/xml_structure_tree_test-xml_structure_mapper.Tpo -c -o xml_structure_tree_test-xml_structure_mapper.o `test -f 'xml_structure_mapper.cpp' || echo '$(srcdir)/'`xml_structure_mapper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xml_structure_tree_test-xml_structure_mapper.Tpo $(DEPDIR)/xml_structure_tree_test-xml_structure_mapper.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_structure_mapper.cpp' object='xml_structure_tree_test-xml_structure_mapper.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xml_structure_tree_test-xml_structure_mapper.o `test -f 'xml_structure_mapper.cpp' || echo '$(srcdir)/'`xml_structure_mapper.cpp + +xml_structure_tree_test-xml_structure_mapper.obj: xml_structure_mapper.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xml_structure_tree_test-xml_structure_mapper.obj -MD -MP -MF $(DEPDIR)/xml_structure_tree_test-xml_structure_mapper.Tpo -c -o xml_structure_tree_test-xml_structure_mapper.obj `if test -f 'xml_structure_mapper.cpp'; then $(CYGPATH_W) 'xml_structure_mapper.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_structure_mapper.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xml_structure_tree_test-xml_structure_mapper.Tpo $(DEPDIR)/xml_structure_tree_test-xml_structure_mapper.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_structure_mapper.cpp' object='xml_structure_tree_test-xml_structure_mapper.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xml_structure_tree_test-xml_structure_mapper.obj `if test -f 'xml_structure_mapper.cpp'; then $(CYGPATH_W) 'xml_structure_mapper.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_structure_mapper.cpp'; fi` + +xml_structure_tree_test-xml_structure_tree_test.o: xml_structure_tree_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xml_structure_tree_test-xml_structure_tree_test.o -MD -MP -MF $(DEPDIR)/xml_structure_tree_test-xml_structure_tree_test.Tpo -c -o xml_structure_tree_test-xml_structure_tree_test.o `test -f 'xml_structure_tree_test.cpp' || echo '$(srcdir)/'`xml_structure_tree_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xml_structure_tree_test-xml_structure_tree_test.Tpo $(DEPDIR)/xml_structure_tree_test-xml_structure_tree_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_structure_tree_test.cpp' object='xml_structure_tree_test-xml_structure_tree_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xml_structure_tree_test-xml_structure_tree_test.o `test -f 'xml_structure_tree_test.cpp' || echo '$(srcdir)/'`xml_structure_tree_test.cpp + +xml_structure_tree_test-xml_structure_tree_test.obj: xml_structure_tree_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT xml_structure_tree_test-xml_structure_tree_test.obj -MD -MP -MF $(DEPDIR)/xml_structure_tree_test-xml_structure_tree_test.Tpo -c -o xml_structure_tree_test-xml_structure_tree_test.obj `if test -f 'xml_structure_tree_test.cpp'; then $(CYGPATH_W) 'xml_structure_tree_test.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_structure_tree_test.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xml_structure_tree_test-xml_structure_tree_test.Tpo $(DEPDIR)/xml_structure_tree_test-xml_structure_tree_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='xml_structure_tree_test.cpp' object='xml_structure_tree_test-xml_structure_tree_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_structure_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o xml_structure_tree_test-xml_structure_tree_test.obj `if test -f 'xml_structure_tree_test.cpp'; then $(CYGPATH_W) 'xml_structure_tree_test.cpp'; else $(CYGPATH_W) '$(srcdir)/xml_structure_tree_test.cpp'; fi` + +yaml_document_tree_test-yaml_document_tree.o: yaml_document_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT yaml_document_tree_test-yaml_document_tree.o -MD -MP -MF $(DEPDIR)/yaml_document_tree_test-yaml_document_tree.Tpo -c -o yaml_document_tree_test-yaml_document_tree.o `test -f 'yaml_document_tree.cpp' || echo '$(srcdir)/'`yaml_document_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/yaml_document_tree_test-yaml_document_tree.Tpo $(DEPDIR)/yaml_document_tree_test-yaml_document_tree.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='yaml_document_tree.cpp' object='yaml_document_tree_test-yaml_document_tree.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o yaml_document_tree_test-yaml_document_tree.o `test -f 'yaml_document_tree.cpp' || echo '$(srcdir)/'`yaml_document_tree.cpp + +yaml_document_tree_test-yaml_document_tree.obj: yaml_document_tree.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT yaml_document_tree_test-yaml_document_tree.obj -MD -MP -MF $(DEPDIR)/yaml_document_tree_test-yaml_document_tree.Tpo -c -o yaml_document_tree_test-yaml_document_tree.obj `if test -f 'yaml_document_tree.cpp'; then $(CYGPATH_W) 'yaml_document_tree.cpp'; else $(CYGPATH_W) '$(srcdir)/yaml_document_tree.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/yaml_document_tree_test-yaml_document_tree.Tpo $(DEPDIR)/yaml_document_tree_test-yaml_document_tree.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='yaml_document_tree.cpp' object='yaml_document_tree_test-yaml_document_tree.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o yaml_document_tree_test-yaml_document_tree.obj `if test -f 'yaml_document_tree.cpp'; then $(CYGPATH_W) 'yaml_document_tree.cpp'; else $(CYGPATH_W) '$(srcdir)/yaml_document_tree.cpp'; fi` + +yaml_document_tree_test-json_util.o: json_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT yaml_document_tree_test-json_util.o -MD -MP -MF $(DEPDIR)/yaml_document_tree_test-json_util.Tpo -c -o yaml_document_tree_test-json_util.o `test -f 'json_util.cpp' || echo '$(srcdir)/'`json_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/yaml_document_tree_test-json_util.Tpo $(DEPDIR)/yaml_document_tree_test-json_util.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='json_util.cpp' object='yaml_document_tree_test-json_util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o yaml_document_tree_test-json_util.o `test -f 'json_util.cpp' || echo '$(srcdir)/'`json_util.cpp + +yaml_document_tree_test-json_util.obj: json_util.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT yaml_document_tree_test-json_util.obj -MD -MP -MF $(DEPDIR)/yaml_document_tree_test-json_util.Tpo -c -o yaml_document_tree_test-json_util.obj `if test -f 'json_util.cpp'; then $(CYGPATH_W) 'json_util.cpp'; else $(CYGPATH_W) '$(srcdir)/json_util.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/yaml_document_tree_test-json_util.Tpo $(DEPDIR)/yaml_document_tree_test-json_util.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='json_util.cpp' object='yaml_document_tree_test-json_util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o yaml_document_tree_test-json_util.obj `if test -f 'json_util.cpp'; then $(CYGPATH_W) 'json_util.cpp'; else $(CYGPATH_W) '$(srcdir)/json_util.cpp'; fi` + +yaml_document_tree_test-yaml_document_tree_test.o: yaml_document_tree_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT yaml_document_tree_test-yaml_document_tree_test.o -MD -MP -MF $(DEPDIR)/yaml_document_tree_test-yaml_document_tree_test.Tpo -c -o yaml_document_tree_test-yaml_document_tree_test.o `test -f 'yaml_document_tree_test.cpp' || echo '$(srcdir)/'`yaml_document_tree_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/yaml_document_tree_test-yaml_document_tree_test.Tpo $(DEPDIR)/yaml_document_tree_test-yaml_document_tree_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='yaml_document_tree_test.cpp' object='yaml_document_tree_test-yaml_document_tree_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o yaml_document_tree_test-yaml_document_tree_test.o `test -f 'yaml_document_tree_test.cpp' || echo '$(srcdir)/'`yaml_document_tree_test.cpp + +yaml_document_tree_test-yaml_document_tree_test.obj: yaml_document_tree_test.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT yaml_document_tree_test-yaml_document_tree_test.obj -MD -MP -MF $(DEPDIR)/yaml_document_tree_test-yaml_document_tree_test.Tpo -c -o yaml_document_tree_test-yaml_document_tree_test.obj `if test -f 'yaml_document_tree_test.cpp'; then $(CYGPATH_W) 'yaml_document_tree_test.cpp'; else $(CYGPATH_W) '$(srcdir)/yaml_document_tree_test.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/yaml_document_tree_test-yaml_document_tree_test.Tpo $(DEPDIR)/yaml_document_tree_test-yaml_document_tree_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='yaml_document_tree_test.cpp' object='yaml_document_tree_test-yaml_document_tree_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_document_tree_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o yaml_document_tree_test-yaml_document_tree_test.obj `if test -f 'yaml_document_tree_test.cpp'; then $(CYGPATH_W) 'yaml_document_tree_test.cpp'; else $(CYGPATH_W) '$(srcdir)/yaml_document_tree_test.cpp'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +check-valgrind-local: +check-valgrind-memcheck-local: +check-valgrind-helgrind-local: +check-valgrind-drd-local: +check-valgrind-sgcheck-local: + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +xlsx-sheet-context-test.log: xlsx-sheet-context-test$(EXEEXT) + @p='xlsx-sheet-context-test$(EXEEXT)'; \ + b='xlsx-sheet-context-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +odf-helper-test.log: odf-helper-test$(EXEEXT) + @p='odf-helper-test$(EXEEXT)'; \ + b='odf-helper-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +gnumeric-cell-context-test.log: gnumeric-cell-context-test$(EXEEXT) + @p='gnumeric-cell-context-test$(EXEEXT)'; \ + b='gnumeric-cell-context-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +gnumeric-sheet-context-test.log: gnumeric-sheet-context-test$(EXEEXT) + @p='gnumeric-sheet-context-test$(EXEEXT)'; \ + b='gnumeric-sheet-context-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +css-document-tree-test.log: css-document-tree-test$(EXEEXT) + @p='css-document-tree-test$(EXEEXT)'; \ + b='css-document-tree-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +json-document-tree-test.log: json-document-tree-test$(EXEEXT) + @p='json-document-tree-test$(EXEEXT)'; \ + b='json-document-tree-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +yaml-document-tree-test.log: yaml-document-tree-test$(EXEEXT) + @p='yaml-document-tree-test$(EXEEXT)'; \ + b='yaml-document-tree-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +xml-map-tree-test.log: xml-map-tree-test$(EXEEXT) + @p='xml-map-tree-test$(EXEEXT)'; \ + b='xml-map-tree-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +common-test.log: common-test$(EXEEXT) + @p='common-test$(EXEEXT)'; \ + b='common-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +dom-tree-test.log: dom-tree-test$(EXEEXT) + @p='dom-tree-test$(EXEEXT)'; \ + b='dom-tree-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +json-structure-tree-test.log: json-structure-tree-test$(EXEEXT) + @p='json-structure-tree-test$(EXEEXT)'; \ + b='json-structure-tree-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +json-map-tree-test.log: json-map-tree-test$(EXEEXT) + @p='json-map-tree-test$(EXEEXT)'; \ + b='json-map-tree-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +xml-structure-tree-test.log: xml-structure-tree-test$(EXEEXT) + @p='xml-structure-tree-test$(EXEEXT)'; \ + b='xml-structure-tree-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +xpath-parser-test.log: xpath-parser-test$(EXEEXT) + @p='xpath-parser-test$(EXEEXT)'; \ + b='xpath-parser-test'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(LTLIBRARIES) +install-EXTRAPROGRAMS: install-libLTLIBRARIES + +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +check-valgrind: check-valgrind-am + +check-valgrind-am: check-valgrind-local + +check-valgrind-drd: check-valgrind-drd-am + +check-valgrind-drd-am: check-valgrind-drd-local + +check-valgrind-helgrind: check-valgrind-helgrind-am + +check-valgrind-helgrind-am: check-valgrind-helgrind-local + +check-valgrind-memcheck: check-valgrind-memcheck-am + +check-valgrind-memcheck-am: check-valgrind-memcheck-local + +check-valgrind-sgcheck: check-valgrind-sgcheck-am + +check-valgrind-sgcheck-am: check-valgrind-sgcheck-local + +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/common_test.Po + -rm -f ./$(DEPDIR)/css_document_tree.Po + -rm -f ./$(DEPDIR)/css_document_tree_test.Po + -rm -f ./$(DEPDIR)/dom_tree_test.Po + -rm -f ./$(DEPDIR)/gnumeric_cell_context.Po + -rm -f ./$(DEPDIR)/gnumeric_cell_context_test.Po + -rm -f ./$(DEPDIR)/gnumeric_namespace_types.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_cell_context.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_filter_context.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_names_context.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_namespace_types.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context_test.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_styles_context.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_tokens.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_types.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_value_format_parser.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-number_utils.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-odf_namespace_types.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-session_context.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-spreadsheet_interface.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-string_helper.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-xml_context_base.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-xml_element_types.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-xml_element_validator.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-xml_empty_context.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-xml_util.Po + -rm -f ./$(DEPDIR)/gnumeric_tokens.Po + -rm -f ./$(DEPDIR)/gnumeric_types.Po + -rm -f ./$(DEPDIR)/gnumeric_value_format_parser.Po + -rm -f ./$(DEPDIR)/json_document_tree_test-json_document_tree.Po + -rm -f ./$(DEPDIR)/json_document_tree_test-json_document_tree_test.Po + -rm -f ./$(DEPDIR)/json_document_tree_test-json_util.Po + -rm -f ./$(DEPDIR)/json_map_tree.Po + -rm -f ./$(DEPDIR)/json_map_tree_test.Po + -rm -f ./$(DEPDIR)/json_structure_tree_test.Po + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-config.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-css_document_tree.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-css_selector.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-detection_result.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-dom_tree.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-format_detection.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-formula_result.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_cell_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_detection_handler.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_filter_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_handler.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_names_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_namespace_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_sheet_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_styles_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_tokens.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_value_format_parser.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-info.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-interface.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_document_tree.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_map_tree.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_structure_mapper.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_structure_tree.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_util.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-measurement.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-number_utils.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_document_styles_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_helper.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_namespace_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_number_format_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_para_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_style_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_styles.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_styles_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_tokens.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_content_xml_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_dde_links_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_session_data.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_content_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_global.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_namespace_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_schemas.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_tokens.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-opc_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-opc_reader.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_csv.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_gnumeric.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_import_ods.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_import_xlsx.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_json.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_ods.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_parquet.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xls_xml.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xlsx.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml_impl.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml_map_def.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-session_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_iface_util.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_impl_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_interface.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-string_helper.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_detection_handler.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_handler.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_namespace_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_tokens.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_autofilter_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_conditional_format_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_drawing_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_handler.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_helper.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_pivot_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_revision_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_session_data.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_shared_strings_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_sheet_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_styles_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_table_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_workbook_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_context_base.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_context_global.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_element_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_element_validator.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_empty_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_map_tree.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_simple_stream_handler.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_stream_handler.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_stream_parser.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_structure_mapper.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_structure_tree.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_util.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xpath_parser.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-yaml_document_tree.Plo + -rm -f ./$(DEPDIR)/number_utils.Po + -rm -f ./$(DEPDIR)/odf_helper_test-odf_helper.Po + -rm -f ./$(DEPDIR)/odf_helper_test-odf_helper_test.Po + -rm -f ./$(DEPDIR)/odf_helper_test-string_helper.Po + -rm -f ./$(DEPDIR)/odf_namespace_types.Po + -rm -f ./$(DEPDIR)/session_context.Po + -rm -f ./$(DEPDIR)/spreadsheet_impl_types.Po + -rm -f ./$(DEPDIR)/spreadsheet_interface.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-formula_result.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_global.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_namespace_types.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_schemas.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_tokens.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_types.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-session_context.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-spreadsheet_interface.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_autofilter_context.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_conditional_format_context.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_helper.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_session_data.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context_test.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_types.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xml_context_base.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xml_context_global.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xml_element_types.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xml_element_validator.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xml_empty_context.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xml_util.Po + -rm -f ./$(DEPDIR)/xml_context_base.Po + -rm -f ./$(DEPDIR)/xml_element_types.Po + -rm -f ./$(DEPDIR)/xml_element_validator.Po + -rm -f ./$(DEPDIR)/xml_empty_context.Po + -rm -f ./$(DEPDIR)/xml_map_tree.Po + -rm -f ./$(DEPDIR)/xml_map_tree_test.Po + -rm -f ./$(DEPDIR)/xml_structure_tree_test-string_helper.Po + -rm -f ./$(DEPDIR)/xml_structure_tree_test-xml_structure_mapper.Po + -rm -f ./$(DEPDIR)/xml_structure_tree_test-xml_structure_tree.Po + -rm -f ./$(DEPDIR)/xml_structure_tree_test-xml_structure_tree_test.Po + -rm -f ./$(DEPDIR)/xml_util.Po + -rm -f ./$(DEPDIR)/xpath_parser.Po + -rm -f ./$(DEPDIR)/xpath_parser_test.Po + -rm -f ./$(DEPDIR)/yaml_document_tree_test-json_util.Po + -rm -f ./$(DEPDIR)/yaml_document_tree_test-yaml_document_tree.Po + -rm -f ./$(DEPDIR)/yaml_document_tree_test-yaml_document_tree_test.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-local distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/common_test.Po + -rm -f ./$(DEPDIR)/css_document_tree.Po + -rm -f ./$(DEPDIR)/css_document_tree_test.Po + -rm -f ./$(DEPDIR)/dom_tree_test.Po + -rm -f ./$(DEPDIR)/gnumeric_cell_context.Po + -rm -f ./$(DEPDIR)/gnumeric_cell_context_test.Po + -rm -f ./$(DEPDIR)/gnumeric_namespace_types.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_cell_context.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_filter_context.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_names_context.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_namespace_types.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_sheet_context_test.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_styles_context.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_tokens.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_types.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-gnumeric_value_format_parser.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-number_utils.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-odf_namespace_types.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-session_context.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-spreadsheet_interface.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-string_helper.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-xml_context_base.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-xml_element_types.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-xml_element_validator.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-xml_empty_context.Po + -rm -f ./$(DEPDIR)/gnumeric_sheet_context_test-xml_util.Po + -rm -f ./$(DEPDIR)/gnumeric_tokens.Po + -rm -f ./$(DEPDIR)/gnumeric_types.Po + -rm -f ./$(DEPDIR)/gnumeric_value_format_parser.Po + -rm -f ./$(DEPDIR)/json_document_tree_test-json_document_tree.Po + -rm -f ./$(DEPDIR)/json_document_tree_test-json_document_tree_test.Po + -rm -f ./$(DEPDIR)/json_document_tree_test-json_util.Po + -rm -f ./$(DEPDIR)/json_map_tree.Po + -rm -f ./$(DEPDIR)/json_map_tree_test.Po + -rm -f ./$(DEPDIR)/json_structure_tree_test.Po + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-config.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-css_document_tree.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-css_selector.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-detection_result.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-dom_tree.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-format_detection.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-formula_result.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_cell_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_detection_handler.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_filter_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_handler.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_names_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_namespace_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_sheet_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_styles_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_tokens.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-gnumeric_value_format_parser.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-info.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-interface.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_document_tree.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_map_tree.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_structure_mapper.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_structure_tree.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-json_util.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-measurement.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-number_utils.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_document_styles_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_helper.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_namespace_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_number_format_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_para_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_style_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_styles.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_styles_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-odf_tokens.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_content_xml_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_dde_links_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ods_session_data.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_content_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_global.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_namespace_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_schemas.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_tokens.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-ooxml_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-opc_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-opc_reader.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_csv.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_gnumeric.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_import_ods.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_import_xlsx.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_json.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_ods.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_parquet.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xls_xml.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xlsx.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml_impl.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-orcus_xml_map_def.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-session_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_iface_util.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_impl_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_interface.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-spreadsheet_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-string_helper.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_detection_handler.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_handler.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_namespace_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xls_xml_tokens.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_autofilter_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_conditional_format_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_drawing_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_handler.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_helper.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_pivot_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_revision_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_session_data.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_shared_strings_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_sheet_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_styles_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_table_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xlsx_workbook_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_context_base.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_context_global.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_element_types.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_element_validator.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_empty_context.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_map_tree.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_simple_stream_handler.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_stream_handler.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_stream_parser.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_structure_mapper.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_structure_tree.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xml_util.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-xpath_parser.Plo + -rm -f ./$(DEPDIR)/liborcus_@ORCUS_API_VERSION@_la-yaml_document_tree.Plo + -rm -f ./$(DEPDIR)/number_utils.Po + -rm -f ./$(DEPDIR)/odf_helper_test-odf_helper.Po + -rm -f ./$(DEPDIR)/odf_helper_test-odf_helper_test.Po + -rm -f ./$(DEPDIR)/odf_helper_test-string_helper.Po + -rm -f ./$(DEPDIR)/odf_namespace_types.Po + -rm -f ./$(DEPDIR)/session_context.Po + -rm -f ./$(DEPDIR)/spreadsheet_impl_types.Po + -rm -f ./$(DEPDIR)/spreadsheet_interface.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-formula_result.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_global.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_namespace_types.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_schemas.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_tokens.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-ooxml_types.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-session_context.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-spreadsheet_interface.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_autofilter_context.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_conditional_format_context.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_helper.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_session_data.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_sheet_context_test.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xlsx_types.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xml_context_base.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xml_context_global.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xml_element_types.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xml_element_validator.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xml_empty_context.Po + -rm -f ./$(DEPDIR)/xlsx_sheet_context_test-xml_util.Po + -rm -f ./$(DEPDIR)/xml_context_base.Po + -rm -f ./$(DEPDIR)/xml_element_types.Po + -rm -f ./$(DEPDIR)/xml_element_validator.Po + -rm -f ./$(DEPDIR)/xml_empty_context.Po + -rm -f ./$(DEPDIR)/xml_map_tree.Po + -rm -f ./$(DEPDIR)/xml_map_tree_test.Po + -rm -f ./$(DEPDIR)/xml_structure_tree_test-string_helper.Po + -rm -f ./$(DEPDIR)/xml_structure_tree_test-xml_structure_mapper.Po + -rm -f ./$(DEPDIR)/xml_structure_tree_test-xml_structure_tree.Po + -rm -f ./$(DEPDIR)/xml_structure_tree_test-xml_structure_tree_test.Po + -rm -f ./$(DEPDIR)/xml_util.Po + -rm -f ./$(DEPDIR)/xpath_parser.Po + -rm -f ./$(DEPDIR)/xpath_parser_test.Po + -rm -f ./$(DEPDIR)/yaml_document_tree_test-json_util.Po + -rm -f ./$(DEPDIR)/yaml_document_tree_test-yaml_document_tree.Po + -rm -f ./$(DEPDIR)/yaml_document_tree_test-yaml_document_tree_test.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ + check-am check-valgrind-am check-valgrind-drd-am \ + check-valgrind-drd-local check-valgrind-helgrind-am \ + check-valgrind-helgrind-local check-valgrind-local \ + check-valgrind-memcheck-am check-valgrind-memcheck-local \ + check-valgrind-sgcheck-am check-valgrind-sgcheck-local clean \ + clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-local distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \ + uninstall uninstall-am uninstall-libLTLIBRARIES + +.PRECIOUS: Makefile + + +distclean-local: + rm -rf $(TESTS) + +@VALGRIND_CHECK_RULES@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/liborcus/common_test.cpp b/src/liborcus/common_test.cpp new file mode 100644 index 0000000..8e4f4c7 --- /dev/null +++ b/src/liborcus/common_test.cpp @@ -0,0 +1,245 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/measurement.hpp> +#include <orcus/spreadsheet/types.hpp> + +#include <cstdlib> +#include <cassert> +#include <iostream> +#include <sstream> +#include <cmath> + +using namespace std; +using namespace orcus; + +void test_date_time_conversion() +{ + struct { + const char* str; + int year; + int month; + int day; + int hour; + int minute; + double second; + } tests[] = { + { "2011-02-12", 2011, 2, 12, 0, 0, 0.0 }, + { "1934-12-23T21:34:56.69", 1934, 12, 23, 21, 34, 56.69 }, + }; + + for (size_t i = 0, n = sizeof(tests)/sizeof(tests[0]); i < n; ++i) + { + std::string_view str(tests[i].str); + date_time_t ret = date_time_t::from_chars(str); + cout << "original: " << str << endl; + cout << "converted: year=" << ret.year << ", month=" << ret.month << ", day=" + << ret.day << ", hour=" << ret.hour << ", minute=" << ret.minute << ", second=" << ret.second << endl; + assert(ret.year == tests[i].year); + assert(ret.month == tests[i].month); + assert(ret.day == tests[i].day); + assert(ret.hour == tests[i].hour); + assert(ret.minute == tests[i].minute); + assert(ret.second == tests[i].second); + } +} + +string to_string(length_unit_t unit) +{ + switch (unit) + { + case length_unit_t::centimeter: + return "centimeter"; + case length_unit_t::inch: + return "inch"; + case length_unit_t::point: + return "point"; + case length_unit_t::twip: + return "twip"; + case length_unit_t::unknown: + default: + ; + } + return "unknown"; +} + +void test_measurement_conversion() +{ + struct { + const char* str; + double expected; + size_t decimals; + length_unit_t unit; + } tests[] = { + { "12.34", 12.34, 2, length_unit_t::unknown }, + { "35", 35, 0, length_unit_t::unknown }, + { "0.69825", 0.69825, 5, length_unit_t::unknown }, + { ".1592", 0.1592, 4, length_unit_t::unknown }, + { "5", 5.0, 0, length_unit_t::unknown }, + { "-3", -3.0, 0, length_unit_t::unknown }, + { "-3.456", -3.456, 3, length_unit_t::unknown }, + { "-.987", -0.987, 3, length_unit_t::unknown }, + { "-100.987.", -100.987, 3, length_unit_t::unknown }, // Second decimal point should stop the parsing. + + { "12.345in", 12.345, 3, length_unit_t::inch }, + { "120.30001cm", 120.30001, 5, length_unit_t::centimeter }, + { "3.12mm", 3.12, 2, length_unit_t::millimeter }, + { "32.681pt", 32.681, 2, length_unit_t::point }, + { "0.1234px", 0.1234, 4, length_unit_t::pixel }, + }; + + for (size_t i = 0, n = sizeof(tests)/sizeof(tests[0]); i < n; ++i) + { + length_t ret = to_length(tests[i].str); + cout << "original: '" << tests[i].str << "', converted: " << ret.value + << " (" << to_string(ret.unit) << "), expected: " + << tests[i].expected << " (" << to_string(tests[i].unit) << ")" << endl; + + // Check for double-precision equality without the rounding error. + double factor = 1.0; + for (size_t j = 0; j < tests[i].decimals; ++j) + factor *= 10.0; + + double converted = round(ret.value * factor); + double expected = round(tests[i].expected * factor); + assert(converted == expected); + + assert(ret.unit == tests[i].unit); + } +} + +void test_measurement_conversion_2() +{ + struct check + { + length_unit_t from; + length_unit_t to; + double original; + double expected; + }; + + std::vector<check> checks = + { + { length_unit_t::millimeter, length_unit_t::twip, 254.0, 14400.0 }, + }; + + for (const check& c : checks) + { + // without volatile, sometimes the following assert evaluates to false on 32-bit debian platforms. + volatile double observed = convert(c.original, c.from, c.to); + assert(observed == c.expected); + } +} + +void test_string2number_conversion() +{ + struct { + const char* str; + double expected; + size_t decimals; + size_t end_pos; + } tests[] = { + { "1.2", 1.2, 1, 3 }, + { "1.2a", 1.2, 1, 3 }, + { "1.2.", 1.2, 1, 3 }, + { "1.3456", 1.3456, 4, 6 }, + { "-10.345", -10.345, 3, 7 }, + { "-10.345-", -10.345, 3, 7 }, + { "1.2E-2", 1.2E-2, 3, 6 }, + { "1.26E+3", 1.26E+3, 1, 7 }, + }; + + for (size_t i = 0, n = sizeof(tests)/sizeof(tests[0]); i < n; ++i) + { + const char* p = tests[i].str; + const char* p_parse_ended = nullptr; + double converted = to_double(p, &p_parse_ended); + cout << "original: '" << tests[i].str << "', converted: " << converted + << ", expected: " << tests[i].expected << endl; + + // Check for double-precision equality without the rounding error. + double factor = 1.0; + for (size_t j = 0; j < tests[i].decimals; ++j) + factor *= 10.0; + + converted = round(converted * factor); + double expected = round(tests[i].expected * factor); + assert(converted == expected); + + // Check the end parse position. + const char* pos_expected = p + tests[i].end_pos; + assert(pos_expected == p_parse_ended); + } +} + +void test_string2long_conversion() +{ + struct { + const char* str; + long expected; + size_t end_pos; + } tests[] = { + { "1", 1, 1 }, + { "12", 12, 2 }, + { "13.4", 13, 2 }, + { "-23", -23, 3 }, + { "678abc", 678, 3 }, + }; + + for (size_t i = 0, n = sizeof(tests)/sizeof(tests[0]); i < n; ++i) + { + const char* p = tests[i].str; + const char* p_parse_ended = nullptr; + long converted = to_long(p, &p_parse_ended); + cout << "original: '" << tests[i].str << "', converted: " << converted + << ", expected: " << tests[i].expected << endl; + + assert(converted == tests[i].expected); + + // Check the end parse position. + const char* pos_expected = p + tests[i].end_pos; + assert(pos_expected == p_parse_ended); + } +} + +void test_spreadsheet_types() +{ + std::vector<spreadsheet::error_value_t> values = + { + spreadsheet::error_value_t::div0, + spreadsheet::error_value_t::na, + spreadsheet::error_value_t::name, + spreadsheet::error_value_t::null, + spreadsheet::error_value_t::num, + spreadsheet::error_value_t::ref, + spreadsheet::error_value_t::value + }; + + for (spreadsheet::error_value_t ev : values) + { + // Round-trip each enum value. + std::ostringstream os; + os << ev; + std::string s = os.str(); + auto converted = spreadsheet::to_error_value_enum(s); + assert(converted == ev); + } +} + +int main() +{ + test_date_time_conversion(); + test_measurement_conversion(); + test_measurement_conversion_2(); + test_string2number_conversion(); + test_string2long_conversion(); + test_spreadsheet_types(); + + return EXIT_SUCCESS; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/config.cpp b/src/liborcus/config.cpp new file mode 100644 index 0000000..9195e02 --- /dev/null +++ b/src/liborcus/config.cpp @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/config.hpp" + +namespace orcus { + +config::config(format_t input) : + input_format(input), + debug(false), + structure_check(true) +{ + // Initialize format-specific config settings below. + + switch (input_format) + { + case format_t::csv: + { + csv_config csv; + csv.header_row_size = 0; + csv.split_to_multiple_sheets = false; + data = csv; + break; + } + case format_t::gnumeric: + case format_t::ods: + case format_t::xls_xml: + case format_t::xlsx: + case format_t::unknown: + default: + ; + } +} + +json_config::json_config() : + output_format(dump_format_t::none), + preserve_object_order(true), + resolve_references(false), + persistent_string_values(true) {} + +json_config::~json_config() {} + +yaml_config::yaml_config() : + output_format(output_format_type::none) {} + +yaml_config::~yaml_config() {} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/constants.inl.in b/src/liborcus/constants.inl.in new file mode 100644 index 0000000..da93f77 --- /dev/null +++ b/src/liborcus/constants.inl.in @@ -0,0 +1,4 @@ + +#define ORCUS_MAJOR_VERSION @ORCUS_MAJOR_VERSION@ +#define ORCUS_MINOR_VERSION @ORCUS_MINOR_VERSION@ +#define ORCUS_MICRO_VERSION @ORCUS_MICRO_VERSION@ diff --git a/src/liborcus/css_document_tree.cpp b/src/liborcus/css_document_tree.cpp new file mode 100644 index 0000000..6960084 --- /dev/null +++ b/src/liborcus/css_document_tree.cpp @@ -0,0 +1,647 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/css_document_tree.hpp> +#include <orcus/css_parser.hpp> +#include <orcus/string_pool.hpp> + +#define ORCUS_DEBUG_CSS_DOCTREE 0 + +#include <iostream> +#include <unordered_map> +#include <map> +#include <algorithm> +#include <iterator> +#include <string_view> + +namespace orcus { + +namespace { + +struct selector_type +{ + css_selector_t selector; + css::pseudo_element_t pseudo_element; +}; + +class parser_handler +{ + css_document_tree& m_doc; + std::vector<selector_type> m_cur_selector_group; + css_properties_t m_cur_properties; + std::string_view m_cur_prop_name; + std::vector<css_property_value_t> m_cur_prop_values; + css_selector_t m_cur_selector; /// current selector + css_simple_selector_t m_cur_simple_selector; + css::pseudo_element_t m_cur_pseudo_element; + css::combinator_t m_cur_combinator; + bool m_in_prop:1; +public: + parser_handler(css_document_tree& doc) : + m_doc(doc), + m_cur_pseudo_element(0), + m_cur_combinator(css::combinator_t::descendant), + m_in_prop(false) {} + + void at_rule_name(std::string_view name) + { +#if ORCUS_DEBUG_CSS_DOCTREE + cout << "@" << name; +#else + (void)name; +#endif + } + + void simple_selector_type(std::string_view type) + { + m_cur_simple_selector.name = type; + } + + void simple_selector_class(std::string_view cls) + { + m_cur_simple_selector.classes.insert(cls); + } + + void simple_selector_pseudo_element(css::pseudo_element_t pe) + { + // Only the one applied to the last simple selector is valid. + m_cur_pseudo_element |= pe; + } + + void simple_selector_pseudo_class(css::pseudo_class_t pc) + { + m_cur_simple_selector.pseudo_classes |= pc; + } + + void simple_selector_id(std::string_view id) + { + m_cur_simple_selector.id = id; + } + + void end_simple_selector() + { + if (m_cur_selector.first.empty()) + m_cur_selector.first = m_cur_simple_selector; + else + { + css_chained_simple_selector_t css; + css.combinator = m_cur_combinator; + css.simple_selector = m_cur_simple_selector; + m_cur_selector.chained.push_back(css); + } + + m_cur_simple_selector.clear(); + } + + void end_selector() + { +#if ORCUS_DEBUG_CSS_DOCTREE + cout << m_cur_selector << "|"; +#endif + selector_type sel; + sel.selector = m_cur_selector; + sel.pseudo_element = m_cur_pseudo_element; + m_cur_selector_group.push_back(sel); + m_cur_selector.clear(); + m_cur_pseudo_element = 0; + } + + void combinator(css::combinator_t combinator) + { + m_cur_combinator = combinator; + } + + void property_name(std::string_view name) + { + m_cur_prop_name = name; +#if ORCUS_DEBUG_CSS_DOCTREE + cout << name << ":"; +#endif + } + + void value(std::string_view s) + { + m_cur_prop_values.push_back(s); +#if ORCUS_DEBUG_CSS_DOCTREE + cout << " '" << s << "'"; +#endif + } + + void rgb(uint8_t red, uint8_t green, uint8_t blue) + { +#if ORCUS_DEBUG_CSS_DOCTREE + cout << " rgb(" << (int)red << ',' << (int)green << ',' << (int)blue << ')'; +#endif + css_property_value_t val; + val.type = css::property_value_t::rgb; + val.value = css::rgba_color_t{red, green, blue, 0.0}; + m_cur_prop_values.push_back(val); + } + + void rgba(uint8_t red, uint8_t green, uint8_t blue, double alpha) + { +#if ORCUS_DEBUG_CSS_DOCTREE + cout << " rgba(" << (int)red << ',' << (int)green << ',' << (int)blue << ',' << alpha << ')'; +#endif + css_property_value_t val; + val.type = css::property_value_t::rgba; + val.value = css::rgba_color_t{red, green, blue, alpha}; + m_cur_prop_values.push_back(val); + } + + void hsl(uint8_t hue, uint8_t sat, uint8_t light) + { +#if ORCUS_DEBUG_CSS_DOCTREE + cout << "hsl(" << (int)hue << ',' << (int)sat << ',' << (int)light << ')'; +#endif + css_property_value_t val; + val.type = css::property_value_t::hsl; + val.value = css::hsla_color_t{hue, sat, light, 0.0}; + m_cur_prop_values.push_back(val); + } + + void hsla(uint8_t hue, uint8_t sat, uint8_t light, double alpha) + { +#if ORCUS_DEBUG_CSS_DOCTREE + cout << "hsla(" << (int)hue << ',' << (int)sat << ',' << (int)light << ',' << alpha << ')'; +#endif + css_property_value_t val; + val.type = css::property_value_t::hsla; + val.value = css::hsla_color_t{hue, sat, light, alpha}; + m_cur_prop_values.push_back(val); + } + + void url(std::string_view url) + { +#if ORCUS_DEBUG_CSS_DOCTREE + cout << " url(" << url << ")"; +#endif + css_property_value_t val; + val.type = orcus::css::property_value_t::url; + val.value = url; + m_cur_prop_values.push_back(val); + } + + void begin_parse() + { +#if ORCUS_DEBUG_CSS_DOCTREE + cout << "========" << endl; +#endif + } + + void end_parse() + { +#if ORCUS_DEBUG_CSS_DOCTREE + cout << "========" << endl; +#endif + } + + void begin_block() + { +#if ORCUS_DEBUG_CSS_DOCTREE + cout << endl << "{" << endl; +#endif + m_in_prop = true; + } + + void end_block() + { +#if ORCUS_DEBUG_CSS_DOCTREE + cout << "}" << endl; +#endif + m_in_prop = false; + + // Push the property set and selector group to the document tree. + + std::vector<selector_type>::iterator it = m_cur_selector_group.begin(), ite = m_cur_selector_group.end(); + for (; it != ite; ++it) + m_doc.insert_properties(it->selector, it->pseudo_element, m_cur_properties); + + m_cur_selector_group.clear(); + m_cur_properties.clear(); + } + + void begin_property() + { +#if ORCUS_DEBUG_CSS_DOCTREE + if (m_in_prop) + cout << " "; + cout << "* "; +#endif + } + + void end_property() + { + m_cur_properties.insert( + css_properties_t::value_type(m_cur_prop_name, m_cur_prop_values)); + m_cur_prop_name = std::string_view{}; + m_cur_prop_values.clear(); +#if ORCUS_DEBUG_CSS_DOCTREE + cout << endl; +#endif + } +}; + +struct simple_selector_node; + +typedef std::unordered_map< + css_simple_selector_t, simple_selector_node, css_simple_selector_t::hash> simple_selectors_type; + +typedef std::map<css::combinator_t, simple_selectors_type> combinators_type; + +struct simple_selector_node +{ + css_pseudo_element_properties_t properties; + combinators_type children; +}; + +css_simple_selector_t intern(string_pool& sp, const css_simple_selector_t& sel) +{ + css_simple_selector_t interned; + + if (!sel.name.empty()) + interned.name = sp.intern(sel.name).first; + if (!sel.id.empty()) + interned.id = sp.intern(sel.id).first; + + css_simple_selector_t::classes_type::const_iterator it = sel.classes.begin(), ite = sel.classes.end(); + for (; it != ite; ++it) + interned.classes.insert(sp.intern(*it).first); + + interned.pseudo_classes = sel.pseudo_classes; + + return interned; +} + +css_selector_t intern(string_pool& sp, const css_selector_t& sel) +{ + css_selector_t interned; + interned.first = intern(sp, sel.first); + + css_selector_t::chained_type::const_iterator it = sel.chained.begin(), ite = sel.chained.end(); + for (; it != ite; ++it) + { + const css_chained_simple_selector_t& cs = *it; + css_chained_simple_selector_t cs_interned; + cs_interned.combinator = cs.combinator; + cs_interned.simple_selector = intern(sp, cs.simple_selector); + interned.chained.push_back(cs_interned); + } + + return interned; +} + +class intern_inserter +{ + string_pool& m_sp; + std::vector<css_property_value_t>& m_dest; +public: + intern_inserter(string_pool& sp, std::vector<css_property_value_t>& dest) : + m_sp(sp), m_dest(dest) {} + + void operator() (const css_property_value_t& v) const + { + switch (v.type) + { + case css::property_value_t::string: + case css::property_value_t::url: + { + // String value needs interning. + css_property_value_t interned = v; + auto s = std::get<std::string_view>(v.value); + interned.value = m_sp.intern(s).first; + m_dest.push_back(interned); + break; + } + default: + m_dest.push_back(v); + } + } +}; + +void store_properties( + string_pool& sp, css_pseudo_element_properties_t& store, + css::pseudo_element_t pseudo_flags, const css_properties_t& props) +{ + css_pseudo_element_properties_t::iterator it_store = store.find(pseudo_flags); + if (it_store == store.end()) + { + // No storage for this pseudo flag value. Create a new one. + std::pair<css_pseudo_element_properties_t::iterator, bool> r = + store.insert( + css_pseudo_element_properties_t::value_type( + pseudo_flags, css_properties_t())); + if (!r.second) + // insertion failed. + return; + + it_store = r.first; + } + + css_properties_t& prop_store = it_store->second; + + css_properties_t::const_iterator it = props.begin(), ite = props.end(); + for (; it != ite; ++it) + { + std::string_view key = sp.intern(it->first).first; + std::vector<css_property_value_t> vals; + for_each(it->second.begin(), it->second.end(), intern_inserter(sp, vals)); + prop_store[key] = vals; + } +} + +simple_selector_node* get_or_create_simple_selector_node( + simple_selectors_type& store, const css_simple_selector_t& ss) +{ + simple_selectors_type::iterator it = store.find(ss); + if (it == store.end()) + { + // Insert this root selector. + std::pair<simple_selectors_type::iterator, bool> r = + store.insert( + simple_selectors_type::value_type( + ss, simple_selector_node())); + + if (!r.second) + // Insertion failed. + return nullptr; + + it = r.first; + } + + return &it->second; +} + +const simple_selector_node* get_simple_selector_node( + const simple_selectors_type& store, const css_simple_selector_t& ss) +{ + simple_selectors_type::const_iterator it = store.find(ss); + return it == store.end() ? nullptr : &it->second; +} + +simple_selectors_type* get_or_create_simple_selectors_type( + combinators_type& store, css::combinator_t combinator) +{ + combinators_type::iterator it = store.find(combinator); + if (it == store.end()) + { + // Insert new combinator. + std::pair<combinators_type::iterator, bool> r = + store.insert( + combinators_type::value_type( + combinator, simple_selectors_type())); + if (!r.second) + // Insertion failed. + return nullptr; + + it = r.first; + } + + return &it->second; +} + +const simple_selectors_type* get_simple_selectors_type( + const combinators_type& store, css::combinator_t combinator) +{ + combinators_type::const_iterator it = store.find(combinator); + return it == store.end() ? nullptr : &it->second; +} + +void dump_pseudo_elements(css::pseudo_element_t elem) +{ + if (!elem) + return; + + if (elem & css::pseudo_element_after) + std::cout << "::after"; + if (elem & css::pseudo_element_before) + std::cout << "::before"; + if (elem & css::pseudo_element_first_letter) + std::cout << "::first-letter"; + if (elem & css::pseudo_element_first_line) + std::cout << "::first-line"; + if (elem & css::pseudo_element_selection) + std::cout << "::selection"; + if (elem & css::pseudo_element_backdrop) + std::cout << "::backdrop"; +} + +void dump_properties(const css_properties_t& props) +{ + std::cout << '{' << std::endl; + css_properties_t::const_iterator it = props.begin(), ite = props.end(); + for (; it != ite; ++it) + { + std::cout << " * " << it->first << ": "; + const std::vector<css_property_value_t>& vals = it->second; + std::copy(vals.begin(), vals.end(), std::ostream_iterator<css_property_value_t>(std::cout, " ")); + std::cout << ';' << std::endl; + } + std::cout << '}' << std::endl; +} + +void dump_all_properties(const css_selector_t& selector, const css_pseudo_element_properties_t& properties) +{ + css_pseudo_element_properties_t::const_iterator it_prop = properties.begin(), ite_prop = properties.end(); + for (; it_prop != ite_prop; ++it_prop) + { + const css_properties_t& prop = it_prop->second; + if (prop.empty()) + continue; + + std::cout << selector; + dump_pseudo_elements(it_prop->first); + std::cout << std::endl; + dump_properties(prop); + } +} + +void dump_chained_recursive( + css_selector_t& selector, css::combinator_t op, const simple_selectors_type& ss) +{ + simple_selectors_type::const_iterator it_ss = ss.begin(), ite_ss = ss.end(); + for (; it_ss != ite_ss; ++it_ss) + { + css_chained_simple_selector_t chained_ss; + chained_ss.combinator = op; + chained_ss.simple_selector = it_ss->first; + selector.chained.push_back(chained_ss); + + const simple_selector_node& node = it_ss->second; + dump_all_properties(selector, node.properties); + + combinators_type::const_iterator it_comb = node.children.begin(), ite_comb = node.children.end(); + for (; it_comb != ite_comb; ++it_comb) + dump_chained_recursive(selector, it_comb->first, it_comb->second); + + selector.chained.pop_back(); + } +} + +const css_pseudo_element_properties_t* get_properties_map( + const simple_selectors_type& root, const css_selector_t& selector) +{ + const simple_selector_node* node = get_simple_selector_node(root, selector.first); + if (!node) + return nullptr; + + if (!selector.chained.empty()) + { + // Follow the chain to find the right node to store new properties. + css_selector_t::chained_type::const_iterator it_chain = selector.chained.begin(); + css_selector_t::chained_type::const_iterator ite_chain = selector.chained.end(); + const combinators_type* combos = &node->children; + for (; it_chain != ite_chain; ++it_chain) + { + const css_chained_simple_selector_t& css = *it_chain; + const simple_selectors_type* ss = get_simple_selectors_type(*combos, css.combinator); + if (!ss) + return nullptr; + + node = get_simple_selector_node(*ss, css.simple_selector); + if (!node) + return nullptr; + + combos = &node->children; + } + } + + assert(node); + return &node->properties; +} + +} + +css_document_tree::insertion_error::insertion_error(const std::string& msg) : + general_error(msg) {} + +struct css_document_tree::impl +{ + string_pool m_string_pool; + simple_selectors_type m_root; +}; + +css_document_tree::css_document_tree() : mp_impl(std::make_unique<impl>()) +{ +} + +css_document_tree::css_document_tree(css_document_tree&& other) : + mp_impl(std::move(other.mp_impl)) +{ + other.mp_impl = std::make_unique<impl>(); +} + +css_document_tree::~css_document_tree() = default; + +css_document_tree& css_document_tree::operator=(css_document_tree&& other) +{ + css_document_tree tmp(std::move(other)); + swap(tmp); + + return *this; +} + +void css_document_tree::load(std::string_view stream) +{ + if (stream.empty()) + return; + + parser_handler handler(*this); + css_parser<parser_handler> parser(stream, handler); + parser.parse(); +} + +void css_document_tree::insert_properties( + const css_selector_t& selector, + css::pseudo_element_t pseudo_elem, + const css_properties_t& props) +{ + if (props.empty()) + return; + + css_selector_t selector_interned = intern(mp_impl->m_string_pool, selector); + + // See if the root selector already exists. + simple_selector_node* node = + get_or_create_simple_selector_node(mp_impl->m_root, selector_interned.first); + + if (!node) + throw insertion_error("failed to find or create the root simple selector node."); + + if (!selector_interned.chained.empty()) + { + // Follow the chain to find the right node to store new properties. + css_selector_t::chained_type::iterator it_chain = selector_interned.chained.begin(); + css_selector_t::chained_type::iterator ite_chain = selector_interned.chained.end(); + combinators_type* combos = &node->children; + for (; it_chain != ite_chain; ++it_chain) + { + css_chained_simple_selector_t& css = *it_chain; + simple_selectors_type* ss = get_or_create_simple_selectors_type(*combos, css.combinator); + if (!ss) + throw insertion_error("failed to find or create the simple selectors type by combinator."); + + node = get_or_create_simple_selector_node(*ss, css.simple_selector); + if (!node) + throw insertion_error("failed to find or create the simple selector node."); + + combos = &node->children; + } + } + + // We found the right node to store the properties. + assert(node); + store_properties(mp_impl->m_string_pool, node->properties, pseudo_elem, props); +} + +const css_properties_t* css_document_tree::get_properties( + const css_selector_t& selector, css::pseudo_element_t pseudo_elem) const +{ + const css_pseudo_element_properties_t* prop_map = get_properties_map(mp_impl->m_root, selector); + if (!prop_map) + return nullptr; + + css_pseudo_element_properties_t::const_iterator it = prop_map->find(pseudo_elem); + if (it == prop_map->end()) + return nullptr; + + return &it->second; +} + +const css_pseudo_element_properties_t* +css_document_tree::get_all_properties(const css_selector_t& selector) const +{ + return get_properties_map(mp_impl->m_root, selector); +} + +void css_document_tree::dump() const +{ + css_selector_t selector; + + const simple_selectors_type& ss = mp_impl->m_root; + simple_selectors_type::const_iterator it_ss = ss.begin(), ite_ss = ss.end(); + for (; it_ss != ite_ss; ++it_ss) + { + selector.first = it_ss->first; + + const simple_selector_node& node = it_ss->second; + dump_all_properties(selector, node.properties); + + combinators_type::const_iterator it_comb = node.children.begin(), ite_comb = node.children.end(); + for (; it_comb != ite_comb; ++it_comb) + dump_chained_recursive(selector, it_comb->first, it_comb->second); + } +} + +void css_document_tree::swap(css_document_tree& other) noexcept +{ + mp_impl.swap(other.mp_impl); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/css_document_tree_test.cpp b/src/liborcus/css_document_tree_test.cpp new file mode 100644 index 0000000..085ae14 --- /dev/null +++ b/src/liborcus/css_document_tree_test.cpp @@ -0,0 +1,690 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/css_document_tree.hpp> +#include <orcus/css_types.hpp> +#include <orcus/css_parser_base.hpp> +#include <orcus/stream.hpp> + +#include <cstdlib> +#include <cassert> +#include <iostream> +#include <sstream> +#include <iterator> + +#include "filesystem_env.hpp" + +using namespace orcus; + +bool check_prop(const css_properties_t& props, std::string_view key, std::string_view val) +{ + css_properties_t::const_iterator it = props.find(key); + if (it == props.end()) + { + std::cout << "property '" << key << "' not found" << std::endl; + return false; + } + + // Chain all property values into a single string delimited by a " ". + const std::vector<css_property_value_t>& vals = it->second; + std::ostringstream os; + if (vals.size() > 1) + { + auto it_end = vals.end(); + std::advance(it_end, -1); + std::copy(vals.begin(), it_end, std::ostream_iterator<css_property_value_t>(os, " ")); + } + os << vals.back(); + + std::string val_stored = os.str(); + if (val != val_stored) + { + std::cout << "property '" << key << "' is expected to have value '" + << val << "' but '" << val_stored << "' is found." << std::endl; + return false; + } + + return true; +} + +using check_properties_type = std::vector<std::pair<std::string, std::string>>; + +bool check_props(const css_properties_t& props, check_properties_type expected) +{ + bool pass = true; + + for (const auto& [key, value] : expected) + { + bool res = check_prop(props, key, value); + if (!res) + pass = false; + } + + return pass; +} + +css_document_tree load_document(const fs::path& path) +{ + std::cout << path << std::endl; + file_content content(path.string()); + css_document_tree doc; + doc.load(content.str()); + + return doc; +} + +void test_css_invalids() +{ + // Get all yaml files in this directory. + fs::path dirpath(SRCDIR"/test/css/invalids/"); + fs::directory_iterator it_end; + + size_t file_count = 0; + + for (fs::directory_iterator it(dirpath); it != it_end; ++it) + { + fs::path path = it->path(); + if (!fs::is_regular_file(path)) + continue; + + if (path.extension().string() != ".css") + continue; + + std::cout << "parsing invalid file " << path.filename().string() << "..." << std::endl; + + ++file_count; + + file_content content(path.string().data()); + css_document_tree doc; + + try + { + doc.load(content.str()); + assert(!"css::parse_error was not thrown, but expected to be."); + } + catch (const parse_error&) + { + // This is expected. + } + } + + assert(file_count > 0); +} + +void test_css_simple_selector_equality() +{ + css_simple_selector_t left; + css_simple_selector_t right; + assert(left == right); + + left.classes.insert("one"); + assert(left != right); + right.classes.insert("one"); + assert(left == right); + + left.classes.insert("two"); + assert(left != right); + right.classes.insert("two"); + assert(left == right); + + left.classes.insert("three"); + assert(left != right); + right.classes.insert("three"); + assert(left == right); +} + +void test_css_empty() +{ + fs::path path = SRCDIR"/test/css/empty.css"; + std::cout << path << std::endl; + + file_content content(path.string()); + css_document_tree doc; + doc.load(content.str()); +} + +void test_css_parse_basic1() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/basic1.css"); + + css_selector_t selector; + selector.first.name = "table"; + + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 2); + assert(check_prop(*props, "width", "auto")); + assert(check_prop(*props, "height", "500px")); + + selector.first.name = "td"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 2); + assert(check_prop(*props, "color", "gray")); + assert(check_prop(*props, "background-color", "yellow")); + + // This selector doesn't exist in the document tree. + selector.first.name = "tr"; + props = doc.get_properties(selector, 0); + assert(!props); +} + +void test_css_parse_basic2() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/basic2.css"); + + css_selector_t selector; + selector.first.name = "div"; + selector.first.classes.insert("foo"); + + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "border", "solid 1px")); + + selector.clear(); + selector.first.classes.insert("warning"); + + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 2); + assert(check_prop(*props, "background-color", "red")); + assert(check_prop(*props, "font-weight", "900")); +} + +void test_css_parse_basic3() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/basic3.css"); + + css_selector_t selector; + selector.first.name = "html"; + + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "height", "100%")); + + selector.first.name = "body"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "height", "100%")); + + { + // h1, h2, h3 and h4 all have identical set of properties. + const char* names[] = { "h1", "h2", "h3", "h4" }; + std::size_t n = std::size(names); + + for (size_t i = 0; i < n; ++i) + { + selector.first.name = names[i]; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 2); + assert(check_prop(*props, "font-variant", "small-caps")); + assert(check_prop(*props, "padding", "2.5em")); + } + } +} + +void test_css_parse_basic4() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/basic4.css"); + + css_selector_t selector; + selector.first.name = "h1"; + + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "margin", "0.5in")); + + selector.first.name = "h2"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "line-height", "3cm")); + + selector.first.name = "h3"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "word-spacing", "4mm")); + + selector.first.name = "h4"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "font-size", "1pc")); + + selector.first.name = "p"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "font-size", "12px")); +} + +void test_css_parse_basic5() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/basic5.css"); + + css_selector_t selector; + selector.first.classes.insert("info"); + + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "word-spacing", "normal")); +} + +void test_css_parse_basic6() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/basic6.css"); + + css_selector_t selector; + selector.first.name = "h1"; + selector.first.id = "chapter1"; + + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "text-align", "center")); + + selector.first.id = "z98y"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "letter-spacing", "0.5em")); + + selector.clear(); + selector.first.id = "id_global"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "margin", "10px")); +} + +void test_css_parse_basic7() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/basic7.css"); + + css_selector_t selector; + selector.first.classes.insert("one"); + selector.first.classes.insert("two"); + selector.first.classes.insert("three"); + + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "color", "blue")); + + selector.first.classes.clear(); + selector.first.classes.insert("one"); + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "color", "aqua")); + + selector.first.classes.clear(); + selector.first.classes.insert("two"); + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "color", "azure")); + + selector.first.classes.insert("one"); // one two + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "color", "brown")); + + selector.first.clear(); + selector.first.name = "span"; + selector.first.classes.insert("button"); + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "border", "solid 1px gray")); + + selector.first.classes.insert("selected"); // button selected + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "border", "solid 4px red")); +} + +void test_css_parse_basic8() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/basic8.css"); + + css_selector_t selector; + selector.first.classes.insert("ribbon"); + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-color", "#5BC8F7")); + + props = doc.get_properties(selector, css::pseudo_element_after); + assert(props); + assert(props->size() == 4); + assert(check_prop(*props, "content", "Look at this orange box.")); + assert(check_prop(*props, "background-color", "#FFBA10")); + assert(check_prop(*props, "border-color", "black")); + assert(check_prop(*props, "border-style", "dotted")); + + props = doc.get_properties(selector, css::pseudo_element_before); + assert(!props); // it doesn't exist for this pseudo element. + + props = doc.get_properties( + selector, + css::pseudo_element_after|css::pseudo_element_selection); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "content", "Selected orange box.")); + + // Get all properties for all pseudo element flag combos. + const css_pseudo_element_properties_t* all_props = doc.get_all_properties(selector); + assert(all_props); + assert(all_props->size() == 3); + + // Check the properties for no pseudo element flag. + css_pseudo_element_properties_t::const_iterator it = all_props->find(0); + assert(it != all_props->end()); + props = &it->second; + assert(props->size() == 1); + assert(check_prop(*props, "background-color", "#5BC8F7")); + + // ::after pseudo element + it = all_props->find(css::pseudo_element_after); + assert(it != all_props->end()); + props = &it->second; + assert(props->size() == 4); + assert(check_prop(*props, "content", "Look at this orange box.")); + assert(check_prop(*props, "background-color", "#FFBA10")); + assert(check_prop(*props, "border-color", "black")); + assert(check_prop(*props, "border-style", "dotted")); + + // ::after::selection pseudo element pair. + it = all_props->find(css::pseudo_element_after|css::pseudo_element_selection); + assert(it != all_props->end()); + props = &it->second; + assert(check_prop(*props, "content", "Selected orange box.")); +} + +void test_css_parse_basic9() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/basic9.css"); + + css_selector_t selector; + selector.first.name = "a"; + selector.first.pseudo_classes = css::pseudo_class_link; + + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "color", "#FF0000")); + + selector.first.pseudo_classes = css::pseudo_class_visited; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "color", "#00FF00")); + + selector.first.pseudo_classes = css::pseudo_class_hover; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "color", "#FF00FF")); + + selector.first.pseudo_classes = css::pseudo_class_active; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "color", "#0000FF")); +} + +void test_css_parse_basic10() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/basic10.css"); + + css_selector_t selector; + selector.first.classes.insert("foo"); + + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 2); + assert(check_prop(*props, "background-color", "rgb(12,230,222)")); + assert(check_prop(*props, "border", "solid 5px rgba(30,12,0,0.79)")); +} + +void test_css_parse_basic11() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/basic11.css"); + + css_selector_t selector; + selector.first.classes.insert("callout"); + + const css_properties_t* props = doc.get_properties(selector, css::pseudo_element_before); + assert(props); + assert(props->size() == 5); + assert(check_prop(*props, "content", "")); + assert(check_prop(*props, "width", "0px")); + assert(check_prop(*props, "height", "0px")); + assert(check_prop(*props, "border", "0.8em solid transparent")); + assert(check_prop(*props, "position", "absolute")); +} + +void test_css_parse_basic12() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/basic12.css"); + + css_selector_t selector; + selector.first.name = "div"; + + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-image", "url(https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png)")); + + selector.first.name = "p"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-image", "none")); + + selector.first.name = "div"; + selector.first.classes.insert("img1"); + + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-image", "url(http://www.rabiakhan.com/Gallery/background.jpg)")); + + selector.first.classes.clear(); + selector.first.classes.insert("img2"); + + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-image", "url(http://www.tgraphic.com/userimages/Gallery/Backgrounds/TGraphic_com-Full-Wallpapers-Backgrounds_Colorful_C_1920_33.jpg)")); +} + +void test_css_parse_basic13() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/basic13.css"); + + css_selector_t selector; + selector.first.id = "p1"; + + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-color", "hsl(120,100,50)")); + + selector.first.id = "p2"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-color", "hsl(120,100,75)")); + + selector.first.id = "p3"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-color", "hsl(120,100,25)")); + + selector.first.id = "p4"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-color", "hsl(120,60,70)")); +} + +void test_css_parse_basic14() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/basic14.css"); + + css_selector_t selector; + selector.first.id = "p1"; + + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-color", "hsla(120,100,50,0.3)")); + + selector.first.id = "p2"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-color", "hsla(120,100,75,0.3)")); + + selector.first.id = "p3"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-color", "hsla(120,100,25,0.3)")); + + selector.first.id = "p4"; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-color", "hsla(120,60,70,0.3)")); +} + +void test_css_parse_chained1() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/chained1.css"); + + css_selector_t selector; + selector.first.name = "div"; + css_simple_selector_t ss; + ss.name = "p"; + selector.chained.push_back(ss); + + // div p + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-color", "yellow")); + + // div > p + selector.chained.back().combinator = css::combinator_t::direct_child; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-color", "blue")); + + // div + p + selector.chained.back().combinator = css::combinator_t::next_sibling; + props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 1); + assert(check_prop(*props, "background-color", "red")); +} + +void test_css_parse_chained2() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/chained2.css"); + + // Build selector '#id1 table.data td'. + css_selector_t selector; + selector.first.id = "id1"; + + css_simple_selector_t ss; + ss.name = "table"; + ss.classes.insert("data"); + selector.chained.push_back(ss); + + ss.clear(); + ss.name = "td"; + selector.chained.push_back(ss); + + const css_properties_t* props = doc.get_properties(selector, 0); + assert(props); + assert(props->size() == 2); + assert(check_prop(*props, "background-color", "aquamarine")); + assert(check_prop(*props, "border", "solid 2px")); +} + +void test_css_parse_utf8_1() +{ + css_document_tree doc = load_document(SRCDIR"/test/css/utf8-1.css"); + + css_document_tree doc2; + doc2 = std::move(doc); // test the move assignment operator. + + css_selector_t selector; + selector.first.classes.insert("style17"); + + const css_properties_t* props = doc2.get_properties(selector, 0); + assert(props); + assert(props->size() == 11); + + check_properties_type expected = { + { "mso-pattern", "auto none" }, + { "background", "#EDEDED" }, + { "mso-style-name", "20% - 强调文å—颜色 3" }, + { "color", "#000000" }, + { "font-size", "11.0pt" }, + { "font-weight", "400" }, + { "font-style", "normal" }, + { "font-family", "宋体" }, + { "text-decoration", "none" }, + { "mso-generic-font-family", "auto" }, + { "mso-font-charset", "0" }, + }; + + assert(check_props(*props, expected)); +} + +int main() +{ + test_css_invalids(); + test_css_simple_selector_equality(); + test_css_empty(); + test_css_parse_basic1(); + test_css_parse_basic2(); + test_css_parse_basic3(); + test_css_parse_basic4(); + test_css_parse_basic5(); + test_css_parse_basic6(); + test_css_parse_basic7(); + test_css_parse_basic8(); + test_css_parse_basic9(); + test_css_parse_basic10(); + test_css_parse_basic11(); + test_css_parse_basic12(); + test_css_parse_basic13(); + test_css_parse_basic14(); + test_css_parse_chained1(); + test_css_parse_chained2(); + test_css_parse_utf8_1(); + + return EXIT_SUCCESS; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/css_selector.cpp b/src/liborcus/css_selector.cpp new file mode 100644 index 0000000..b7b63f3 --- /dev/null +++ b/src/liborcus/css_selector.cpp @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/css_selector.hpp" + +namespace orcus { + +css_simple_selector_t::css_simple_selector_t() : + pseudo_classes(0) {} + +void css_simple_selector_t::clear() +{ + name = std::string_view{}; + id = std::string_view{}; + classes.clear(); + pseudo_classes = 0; +} + +bool css_simple_selector_t::empty() const +{ + return name.empty() && id.empty() && classes.empty() && !pseudo_classes; +} + +bool css_simple_selector_t::operator== (const css_simple_selector_t& r) const +{ + if (name != r.name) + return false; + + if (id != r.id) + return false; + + if (classes != r.classes) + return false; + + return pseudo_classes == r.pseudo_classes; +} + +bool css_simple_selector_t::operator!= (const css_simple_selector_t& r) const +{ + return !operator==(r); +} + +size_t css_simple_selector_t::hash::operator() (const css_simple_selector_t& ss) const +{ + std::hash<std::string_view> h; + + size_t val = h(ss.name); + val += h(ss.id); + + for (std::string_view s : ss.classes) + val += h(s); + + val += ss.pseudo_classes; + + return val; +} + +bool css_chained_simple_selector_t::operator== (const css_chained_simple_selector_t& r) const +{ + return combinator == r.combinator && simple_selector == r.simple_selector; +} + +css_chained_simple_selector_t::css_chained_simple_selector_t() : + combinator(css::combinator_t::descendant) {} + +css_chained_simple_selector_t::css_chained_simple_selector_t(const css_simple_selector_t& ss) : + combinator(css::combinator_t::descendant), simple_selector(ss) {} + +css_chained_simple_selector_t::css_chained_simple_selector_t( + css::combinator_t op, const css_simple_selector_t& ss) : + combinator(op), simple_selector(ss) {} + +void css_selector_t::clear() +{ + first.clear(); + chained.clear(); +} + +bool css_selector_t::operator== (const css_selector_t& r) const +{ + return first == r.first && chained == r.chained; +} + +css_property_value_t::css_property_value_t() : + type(css::property_value_t::none), value{std::string_view{}} {} + +css_property_value_t::css_property_value_t(const css_property_value_t& r) : + type(r.type), value(r.value) +{ +} + +css_property_value_t::css_property_value_t(std::string_view _str) : + type(css::property_value_t::string), value(_str) {} + +css_property_value_t& css_property_value_t::operator= (const css_property_value_t& r) +{ + type = r.type; + value = r.value; + return *this; +} + +void css_property_value_t::swap(css_property_value_t& r) +{ + std::swap(type, r.type); + std::swap(value, r.value); +} + +std::ostream& operator<< (std::ostream& os, const css_simple_selector_t& v) +{ + os << v.name; + css_simple_selector_t::classes_type::const_iterator it = v.classes.begin(), ite = v.classes.end(); + for (; it != ite; ++it) + os << '.' << *it; + if (!v.id.empty()) + os << '#' << v.id; + if (v.pseudo_classes) + os << css::pseudo_class_to_string(v.pseudo_classes); + return os; +} + +std::ostream& operator<< (std::ostream& os, const css_selector_t& v) +{ + os << v.first; + css_selector_t::chained_type::const_iterator it = v.chained.begin(), ite = v.chained.end(); + for (; it != ite; ++it) + { + const css_chained_simple_selector_t& css = *it; + os << ' '; + switch (css.combinator) + { + case css::combinator_t::direct_child: + os << "> "; + break; + case css::combinator_t::next_sibling: + os << "+ "; + break; + case css::combinator_t::descendant: + default: + ; + } + os << css.simple_selector; + } + return os; +} + +std::ostream& operator<< (std::ostream& os, const css_property_value_t& v) +{ + const char* sep = ","; + + switch (v.type) + { + case css::property_value_t::hsl: + { + auto c = std::get<css::hsla_color_t>(v.value); + os << "hsl(" + << (int)c.hue << sep + << (int)c.saturation << sep + << (int)c.lightness + << ")"; + break; + } + case css::property_value_t::hsla: + { + auto c = std::get<css::hsla_color_t>(v.value); + os << "hsla(" + << (int)c.hue << sep + << (int)c.saturation << sep + << (int)c.lightness << sep + << c.alpha + << ")"; + break; + } + case css::property_value_t::rgb: + { + auto c = std::get<css::rgba_color_t>(v.value); + os << "rgb(" + << (int)c.red << sep + << (int)c.green << sep + << (int)c.blue + << ")"; + break; + } + case css::property_value_t::rgba: + { + auto c = std::get<css::rgba_color_t>(v.value); + os << "rgba(" + << (int)c.red << sep + << (int)c.green << sep + << (int)c.blue << sep + << c.alpha + << ")"; + break; + } + case css::property_value_t::string: + os << std::get<std::string_view>(v.value); + break; + case css::property_value_t::url: + os << "url(" << std::get<std::string_view>(v.value) << ")"; + break; + case css::property_value_t::none: + default: + ; + } + + return os; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/detection_result.cpp b/src/liborcus/detection_result.cpp new file mode 100644 index 0000000..b49f645 --- /dev/null +++ b/src/liborcus/detection_result.cpp @@ -0,0 +1,20 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "detection_result.hpp" + +namespace orcus { + +detection_result::detection_result(bool result) : m_result(result) {} + +bool detection_result::get_result() const +{ + return m_result; +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/detection_result.hpp b/src/liborcus/detection_result.hpp new file mode 100644 index 0000000..bb87941 --- /dev/null +++ b/src/liborcus/detection_result.hpp @@ -0,0 +1,26 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_DETECTION_RESULT_HPP +#define ORCUS_DETECTION_RESULT_HPP + +namespace orcus { + +class detection_result +{ + bool m_result; + +public: + detection_result(bool result); + + bool get_result() const; +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/dom_tree.cpp b/src/liborcus/dom_tree.cpp new file mode 100644 index 0000000..9e7a764 --- /dev/null +++ b/src/liborcus/dom_tree.cpp @@ -0,0 +1,741 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/dom_tree.hpp> +#include <orcus/exception.hpp> +#include <orcus/xml_namespace.hpp> +#include <orcus/sax_ns_parser.hpp> +#include <orcus/string_pool.hpp> + +#include <iostream> +#include <sstream> +#include <cassert> +#include <unordered_map> +#include <vector> +#include <algorithm> +#include <deque> + +namespace orcus { + +namespace dom { + +namespace { + +/** + * Escape certain characters with backslash (\). + */ +void escape(std::ostream& os, std::string_view val) +{ + if (val.empty()) + return; + + const char* p = val.data(); + const char* p_end = p + val.size(); + for (; p != p_end; ++p) + { + if (*p == '"') + os << "\\\""; + else if (*p == '\\') + os << "\\\\"; + else + os << *p; + } +} + +struct attr +{ + dom::entity_name name; + std::string_view value; + + attr(xmlns_id_t _ns, std::string_view _name, std::string_view _value); +}; + +struct entity_name_hash +{ + std::size_t operator()(const entity_name& v) const + { + return std::hash<std::string_view>{}(v.name) ^ reinterpret_cast<std::size_t>(v.ns); + } +}; + +using attrs_type = std::vector<attr>; +using attr_map_type = std::unordered_map<entity_name, size_t, entity_name_hash>; + +struct declaration +{ + attrs_type attrs; + attr_map_type attr_map; +}; + +enum class node_type { element, content }; + +struct element; + +struct node +{ + const element* parent; + node_type type; + + node(node_type _type) : parent(nullptr), type(_type) {} + + virtual ~node() = 0; + virtual void print(std::ostream& os, const xmlns_context& cxt) const = 0; +}; + +typedef std::vector<std::unique_ptr<node>> nodes_type; + +struct element : public node +{ + entity_name name; + attrs_type attrs; + attr_map_type attr_map; + nodes_type child_nodes; + std::vector<size_t> child_elem_positions; + + element() = delete; + element(xmlns_id_t _ns, std::string_view _name); + virtual void print(std::ostream& os, const xmlns_context& cxt) const; + virtual ~element(); +}; + +struct content : public node +{ + std::string_view value; + + content(std::string_view _value); + virtual void print(std::ostream& os, const xmlns_context& cxt) const; + virtual ~content(); +}; + +void print(std::ostream& os, const entity_name& name, const xmlns_context& cxt) +{ + if (name.ns) + { + size_t index = cxt.get_index(name.ns); + if (index != INDEX_NOT_FOUND) + os << "ns" << index << ':'; + } + os << name.name; +} + +void print(std::ostream& os, const attr& at, const xmlns_context& cxt) +{ + dom::print(os, at.name, cxt); + os << "=\""; + escape(os, at.value); + os << '"'; +} + +attr::attr(xmlns_id_t _ns, std::string_view _name, std::string_view _value) : + name(_ns, _name), value(_value) {} + +node::~node() {} + +element::element(xmlns_id_t _ns, std::string_view _name) : + node(node_type::element), name(_ns, _name) {} + +void element::print(std::ostream& os, const xmlns_context& cxt) const +{ + dom::print(os, name, cxt); +} + +element::~element() = default; + +content::content(std::string_view _value) : node(node_type::content), value(_value) {} + +void content::print(std::ostream& os, const xmlns_context& /*cxt*/) const +{ + os << '"'; + escape(os, value); + os << '"'; +} + +content::~content() = default; + +} // anonymous namespace + +entity_name::entity_name() : ns(XMLNS_UNKNOWN_ID) {} + +entity_name::entity_name(std::string_view _name) : + ns(XMLNS_UNKNOWN_ID), name(_name) {} + +entity_name::entity_name(xmlns_id_t _ns, std::string_view _name) : + ns(_ns), name(_name) {} + +bool entity_name::operator== (const entity_name& other) const +{ + return ns == other.ns && name == other.name; +} + +bool entity_name::operator!= (const entity_name& other) const +{ + return !operator==(other); +} + +struct const_node::impl +{ + node_t type; + + union + { + const dom::declaration* decl; + const dom::element* elem; + + struct + { + const char* p; + size_t n; + + } str; + + } value; + + impl() : type(node_t::unset) {} + + impl(const impl& other) : type(other.type) + { + switch (type) + { + case node_t::declaration: + value.decl = other.value.decl; + break; + case node_t::element: + value.elem = other.value.elem; + break; + case node_t::unset: + default: + ; + } + } + + impl(const dom::element* _elem) : type(node_t::element) + { + value.elem = _elem; + } + + impl(const dom::declaration* _decl) : type(node_t::declaration) + { + value.decl = _decl; + } +}; + +const_node::const_node(std::unique_ptr<impl>&& _impl) : mp_impl(std::move(_impl)) {} +const_node::const_node() : mp_impl(std::make_unique<impl>()) {} +const_node::const_node(const const_node& other) : mp_impl(std::make_unique<impl>(*other.mp_impl)) {} +const_node::const_node(const_node&& other) : mp_impl(std::move(other.mp_impl)) {} +const_node::~const_node() {} + +node_t const_node::type() const +{ + return mp_impl->type; +} + +size_t const_node::child_count() const +{ + switch (mp_impl->type) + { + case node_t::element: + { + const dom::element* p = mp_impl->value.elem; + return p->child_elem_positions.size(); + } + default: + ; + } + + return 0; +} + +const_node const_node::child(size_t index) const +{ + switch (mp_impl->type) + { + case node_t::element: + { + const dom::element* p = mp_impl->value.elem; + + size_t elem_pos = p->child_elem_positions.at(index); + assert(elem_pos < p->child_nodes.size()); + + const dom::node* child_node = p->child_nodes[elem_pos].get(); + assert(child_node->type == node_type::element); + + auto v = std::make_unique<impl>(static_cast<const dom::element*>(child_node)); + return const_node(std::move(v)); + } + default: + ; + } + return const_node(); +} + +entity_name const_node::name() const +{ + switch (mp_impl->type) + { + case node_t::element: + { + const dom::element* p = mp_impl->value.elem; + return p->name; + } + default: + ; + } + + return entity_name(); +} + +std::string_view const_node::attribute(const entity_name& name) const +{ + switch (mp_impl->type) + { + case node_t::element: + { + const dom::element* p = mp_impl->value.elem; + auto it = p->attr_map.find(name); + if (it == p->attr_map.end()) + break; + + size_t pos = it->second; + assert(pos < p->attrs.size()); + return p->attrs[pos].value; + } + default: + ; + } + + return std::string_view(); +} + +std::string_view const_node::attribute(std::string_view name) const +{ + switch (mp_impl->type) + { + case node_t::declaration: + { + const dom::declaration* p = mp_impl->value.decl; + auto it = p->attr_map.find(name); + if (it == p->attr_map.end()) + return std::string_view(); + + size_t pos = it->second; + assert(pos < p->attrs.size()); + return p->attrs[pos].value; + } + default: + ; + } + + return attribute(entity_name(name)); +} + +size_t const_node::attribute_count() const +{ + switch (mp_impl->type) + { + case node_t::declaration: + { + const dom::declaration* p = mp_impl->value.decl; + return p->attrs.size(); + } + case node_t::element: + { + const dom::element* p = mp_impl->value.elem; + return p->attrs.size(); + } + default: + ; + } + return 0; +} + +const_node const_node::parent() const +{ + if (mp_impl->type != node_t::element) + return const_node(); + + const dom::element* p = mp_impl->value.elem->parent; + if (!p) + return const_node(); + + auto v = std::make_unique<impl>(p); + return const_node(std::move(v)); +} + +void const_node::swap(const_node& other) +{ + mp_impl.swap(other.mp_impl); +} + +const_node& const_node::operator= (const const_node& other) +{ + const_node tmp(other); + swap(tmp); + return *this; +} + +bool const_node::operator== (const const_node& other) const +{ + if (mp_impl->type != other.mp_impl->type) + return false; + + switch (mp_impl->type) + { + case node_t::unset: + return true; + case node_t::declaration: + return mp_impl->value.decl == other.mp_impl->value.decl; + case node_t::element: + return mp_impl->value.elem == other.mp_impl->value.elem; + default: + ; + } + + return false; +} + +bool const_node::operator!= (const const_node& other) const +{ + return !operator==(other); +} + +/** + * This impl class also serves as the handler for the sax_ns_parser. + */ +struct document_tree::impl +{ + typedef std::vector<dom::element*> element_stack_type; + typedef std::unordered_map<std::string_view, dom::declaration> declarations_type; + + xmlns_context& m_ns_cxt; + string_pool m_pool; + + std::unique_ptr<sax::doctype_declaration> m_doctype; + + std::string_view m_cur_decl_name; + declarations_type m_decls; + dom::attrs_type m_doc_attrs; + dom::attrs_type m_cur_attrs; + dom::attr_map_type m_cur_attr_map; + element_stack_type m_elem_stack; + std::unique_ptr<dom::element> m_root; + + impl(xmlns_context& cxt) : m_ns_cxt(cxt) {} + + void start_declaration(std::string_view name) + { + m_cur_decl_name = name; + } + + void end_declaration(std::string_view name); + void start_element(const sax_ns_parser_element& elem); + void end_element(const sax_ns_parser_element& elem); + void characters(std::string_view val, bool transient); + void doctype(const sax::doctype_declaration& dtd); + + void attribute(std::string_view name, std::string_view val) + { + set_attribute(XMLNS_UNKNOWN_ID, name, val); + } + + void attribute(const sax_ns_parser_attribute& attr) + { + set_attribute(attr.ns, attr.name, attr.value); + } + + void set_attribute(xmlns_id_t ns, std::string_view name, std::string_view val); +}; + +void document_tree::impl::end_declaration(std::string_view name) +{ + assert(m_cur_decl_name == name); + + dom::declaration decl; + decl.attrs.swap(m_cur_attrs); + decl.attr_map.swap(m_cur_attr_map); + + declarations_type::iterator it = m_decls.find(name); + if (it == m_decls.end()) + { + // Insert a new entry for this name. + std::pair<declarations_type::iterator,bool> r = + m_decls.insert( + declarations_type::value_type( + m_pool.intern(name).first, std::move(decl))); + + if (!r.second) + // Insertion failed. + throw general_error("dom_tree::end_declaration: failed to insert a new declaration entry."); + } + else + it->second = std::move(decl); +} + +void document_tree::impl::start_element(const sax_ns_parser_element& elem) +{ + xmlns_id_t ns = elem.ns; + std::string_view name = elem.name; + + // These strings must be persistent. + std::string_view name_safe = m_pool.intern(name).first; + + dom::element* p = nullptr; + if (!m_root) + { + // This must be the root element! + m_root = std::make_unique<dom::element>(ns, name_safe); + m_elem_stack.push_back(m_root.get()); + p = m_elem_stack.back(); + p->attrs.swap(m_cur_attrs); + p->attr_map.swap(m_cur_attr_map); + return; + } + + // Append new element as a child element of the current element. + p = m_elem_stack.back(); + + size_t elem_pos = p->child_nodes.size(); + p->child_elem_positions.push_back(elem_pos); + + p->child_nodes.push_back(std::make_unique<dom::element>(ns, name_safe)); + const dom::element* parent = p; + p = static_cast<dom::element*>(p->child_nodes.back().get()); + p->parent = parent; + p->attrs.swap(m_cur_attrs); + p->attr_map.swap(m_cur_attr_map); + + m_elem_stack.push_back(p); +} + +void document_tree::impl::end_element(const sax_ns_parser_element& elem) +{ + xmlns_id_t ns = elem.ns; + std::string_view name = elem.name; + + const dom::element* p = m_elem_stack.back(); + if (p->name.ns != ns || p->name.name != name) + throw general_error("non-matching end element."); + + m_elem_stack.pop_back(); +} + +void document_tree::impl::characters(std::string_view val, bool /*transient*/) +{ + if (m_elem_stack.empty()) + // No root element has been encountered. Ignore this. + return; + + std::string_view val2 = trim(val); + if (val2.empty()) + return; + + dom::element* p = m_elem_stack.back(); + val2 = m_pool.intern(val2).first; // Make sure the string is persistent. + auto child = std::make_unique<dom::content>(val2); + child->parent = p; + p->child_nodes.push_back(std::move(child)); +} + +void document_tree::impl::set_attribute(xmlns_id_t ns, std::string_view name, std::string_view val) +{ + // These strings must be persistent. + std::string_view name2 = m_pool.intern(name).first; + std::string_view val2 = m_pool.intern(val).first; + + size_t pos = m_cur_attrs.size(); + m_cur_attrs.push_back(dom::attr(ns, name2, val2)); + m_cur_attr_map.insert({dom::entity_name(ns, name2), pos}); +} + +void document_tree::impl::doctype(const sax::doctype_declaration& dtd) +{ + m_doctype = std::make_unique<sax::doctype_declaration>(dtd); // make a copy. + + sax::doctype_declaration& this_dtd = *m_doctype; + string_pool& pool = m_pool; + + // Intern the strings. + this_dtd.root_element = pool.intern(dtd.root_element).first; + this_dtd.fpi = pool.intern(dtd.fpi).first; + this_dtd.uri = pool.intern(dtd.uri).first; +} + +document_tree::document_tree(xmlns_context& cxt) : + mp_impl(std::make_unique<impl>(cxt)) {} + +document_tree::document_tree(document_tree&& other) : + mp_impl(std::move(other.mp_impl)) +{ + other.mp_impl = std::make_unique<impl>(mp_impl->m_ns_cxt); +} + +document_tree::~document_tree() {} + +void document_tree::load(std::string_view strm) +{ + sax_ns_parser<impl> parser(strm, mp_impl->m_ns_cxt, *mp_impl); + parser.parse(); +} + +dom::const_node document_tree::root() const +{ + const dom::element* p = mp_impl->m_root.get(); + auto v = std::make_unique<const_node::impl>(p); + return dom::const_node(std::move(v)); +} + +dom::const_node document_tree::declaration(std::string_view name) const +{ + impl::declarations_type::const_iterator it = mp_impl->m_decls.find(name); + if (it == mp_impl->m_decls.end()) + return dom::const_node(); + + const dom::declaration* decl = &it->second; + auto v = std::make_unique<dom::const_node::impl>(decl); + return dom::const_node(std::move(v)); +} + +void document_tree::swap(document_tree& other) +{ + mp_impl.swap(other.mp_impl); +} + +const sax::doctype_declaration* document_tree::get_doctype() const +{ + return mp_impl->m_doctype.get(); +} + +namespace { + +struct scope +{ + typedef std::vector<const dom::node*> nodes_type; + std::string name; + nodes_type nodes; + nodes_type::const_iterator current_pos; + + scope(const scope&) = delete; + scope& operator=(const scope&) = delete; + + scope(const std::string& _name, dom::node* _node) : + name(_name) + { + nodes.push_back(_node); + current_pos = nodes.begin(); + } + + scope(const std::string& _name) : name(_name) {} +}; + +typedef std::deque<scope> scopes_type; + +void print_scope(std::ostream& os, const scopes_type& scopes) +{ + if (scopes.empty()) + throw general_error("scope stack shouldn't be empty while dumping tree."); + + // Skip the first scope which is root. + scopes_type::const_iterator it = scopes.begin(), it_end = scopes.end(); + for (++it; it != it_end; ++it) + os << "/" << it->name; +} + +} + +void document_tree::dump_compact(std::ostream& os) const +{ + if (!mp_impl->m_root) + return; + + // Dump namespaces first. + mp_impl->m_ns_cxt.dump(os); + + scopes_type scopes; + + scopes.emplace_back(std::string(), mp_impl->m_root.get()); + while (!scopes.empty()) + { + bool new_scope = false; + + // Iterate through all elements in the current scope. + scope& cur_scope = scopes.back(); + for (; cur_scope.current_pos != cur_scope.nodes.end(); ++cur_scope.current_pos) + { + const dom::node* this_node = *cur_scope.current_pos; + assert(this_node); + print_scope(os, scopes); + if (this_node->type == dom::node_type::content) + { + // This is a text content. + this_node->print(os, mp_impl->m_ns_cxt); + os << std::endl; + continue; + } + + assert(this_node->type == dom::node_type::element); + const dom::element* elem = static_cast<const dom::element*>(this_node); + os << "/"; + elem->print(os, mp_impl->m_ns_cxt); + os << std::endl; + + { + // Dump attributes. + dom::attrs_type attrs = elem->attrs; + std::sort(attrs.begin(), attrs.end(), + [](const dom::attr& left, const dom::attr& right) -> bool + { + return left.name.name < right.name.name; + } + ); + + for (const dom::attr& a : attrs) + { + print_scope(os, scopes); + os << "/"; + elem->print(os, mp_impl->m_ns_cxt); + os << "@"; + dom::print(os, a, mp_impl->m_ns_cxt); + os << std::endl; + } + } + + if (elem->child_nodes.empty()) + continue; + + // This element has child nodes. Push a new scope and populate it + // with all child elements, but skip content nodes. + scope::nodes_type nodes; + for (const std::unique_ptr<dom::node>& p : elem->child_nodes) + nodes.push_back(p.get()); + + assert(!nodes.empty()); + + // Push a new scope, and restart the loop with the new scope. + ++cur_scope.current_pos; + std::ostringstream elem_name; + elem->print(elem_name, mp_impl->m_ns_cxt); + scopes.emplace_back(elem_name.str()); + scope& child_scope = scopes.back(); + child_scope.nodes.swap(nodes); + child_scope.current_pos = child_scope.nodes.begin(); + + new_scope = true; + break; + } + + if (new_scope) + continue; + + scopes.pop_back(); + } +} + +} // namespace dom + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/dom_tree_test.cpp b/src/liborcus/dom_tree_test.cpp new file mode 100644 index 0000000..5ce5418 --- /dev/null +++ b/src/liborcus/dom_tree_test.cpp @@ -0,0 +1,123 @@ + +#include <orcus/dom_tree.hpp> +#include <orcus/stream.hpp> +#include <orcus/xml_namespace.hpp> +#include <cassert> +#include <iostream> + +using namespace orcus::dom; + +struct doctree +{ + orcus::xmlns_repository repo; + orcus::xmlns_context cxt; + orcus::dom::document_tree tree; + + doctree(std::string_view content) : repo(), cxt(repo.create_context()), tree(cxt) + { + tree.load(content); + } +}; + +std::unique_ptr<doctree> load_document_tree(std::string_view content) +{ + std::unique_ptr<doctree> ret = std::make_unique<doctree>(content); + return ret; +} + +std::unique_ptr<doctree> load_document_tree_from_file(const char* filepath) +{ + orcus::file_content content(filepath); + return load_document_tree(content.str()); +} + +void test_encoded_attr() +{ + std::string content = "<?xml version=\"1.0\"?><root attr=\"&;\"/>"; + auto doctree = load_document_tree(content); + const_node root = doctree->tree.root(); + doctree->tree.dump_compact(std::cout); + std::cout << __FILE__ << "#" << __LINE__ << " (:test_encoded_attr): " << root.attribute("attr") << std::endl; + assert(root.attribute("attr") == "&;"); +} + +void test_declaration() +{ + auto doctree = load_document_tree_from_file(SRCDIR"/test/xml/osm/street-in-aizu.osm"); + + const_node decl = doctree->tree.declaration("xml"); + assert(decl.type() == node_t::declaration); + assert(decl.attribute("version") == "1.0"); + assert(decl.attribute("encoding") == "UTF-8"); + + const_node copied = decl; + assert(copied == decl); +} + +void test_attributes() +{ + auto doctree = load_document_tree_from_file(SRCDIR"/test/xml/osm/street-in-aizu.osm"); + + const_node root = doctree->tree.root(); + assert(root.name() == entity_name("osm")); + assert(root.type() == node_t::element); + assert(root.attribute("version") == "0.6"); + assert(root.attribute("generator") == "CGImap 0.6.1 (1984 thorn-02.openstreetmap.org)"); + assert(root.attribute("copyright") == "OpenStreetMap and contributors"); + assert(root.attribute("attribution") == "http://www.openstreetmap.org/copyright"); + assert(root.attribute("license") == "http://opendatacommons.org/licenses/odbl/1-0/"); + assert(root.attribute("no-such-attribute").empty()); + assert(root.attribute_count() == 5); +} + +void test_element_hierarchy() +{ + auto doctree = load_document_tree_from_file(SRCDIR"/test/xml/osm/street-in-aizu.osm"); + + const_node root = doctree->tree.root(); + assert(root.name() == entity_name("osm")); + assert(root.child_count() > 0); + assert(root.parent().type() == node_t::unset); + + const_node elem = root.child(0); + assert(elem != root); + assert(elem.type() == node_t::element); + assert(elem.name() == entity_name("bounds")); + assert(elem.attribute("minlat") == "37.4793300"); + assert(elem.attribute("minlon") == "139.9158300"); + assert(elem.attribute("maxlat") == "37.4798000"); + assert(elem.attribute("maxlon") == "139.9162300"); + assert(elem.attribute_count() == 4); + assert(elem.child_count() == 0); + assert(elem.parent() == root); + + const_node copied_elem = elem; + assert(copied_elem == elem); + + elem = root.child(5); + assert(elem.name() == entity_name("node")); + assert(elem.attribute("user") == "jun_meguro"); + assert(elem.child_count() == 1); + elem = elem.child(0); + assert(elem.name() == entity_name("tag")); + assert(elem.attribute("k") == "highway"); + assert(elem.attribute("v") == "crossing"); + + // Make sure the number of child elements are accurate. + size_t n_elems = root.child_count(); + for (size_t i = 0; i < n_elems; ++i) + { + auto child = root.child(i); + assert(child.type() == node_t::element); + } +} + +int main() +{ + test_encoded_attr(); + test_declaration(); + test_attributes(); + test_element_hierarchy(); + + return EXIT_SUCCESS; +} diff --git a/src/liborcus/format_detection.cpp b/src/liborcus/format_detection.cpp new file mode 100644 index 0000000..e685362 --- /dev/null +++ b/src/liborcus/format_detection.cpp @@ -0,0 +1,135 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifdef __ORCUS_ODS +#define ODS_ENABLED 1 +#else +#define ODS_ENABLED 0 +#endif + +#ifdef __ORCUS_XLSX +#define XLSX_ENABLED 1 +#else +#define XLSX_ENABLED 0 +#endif + +#ifdef __ORCUS_GNUMERIC +#define GNUMERIC_ENABLED 1 +#else +#define GNUMERIC_ENABLED 0 +#endif + +#ifdef __ORCUS_XLS_XML +#define XLS_XML_ENABLED 1 +#else +#define XLS_XML_ENABLED 0 +#endif + +#ifdef __ORCUS_PARQUET +#define PARQUET_ENABLED 1 +#else +#define PARQUET_ENABLED 0 +#endif + +#include <orcus/format_detection.hpp> +#include <orcus/orcus_csv.hpp> + +#if ODS_ENABLED +#include <orcus/orcus_ods.hpp> +#endif +#if XLSX_ENABLED +#include <orcus/orcus_xlsx.hpp> +#endif +#if GNUMERIC_ENABLED +#include <orcus/orcus_gnumeric.hpp> +#endif +#if XLS_XML_ENABLED +#include <orcus/orcus_xls_xml.hpp> +#endif +#if PARQUET_ENABLED +#include <orcus/orcus_parquet.hpp> +#endif + +#include <stdexcept> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +format_t detect(std::string_view strm) try +{ + const auto* p = reinterpret_cast<const unsigned char*>(strm.data()); + +#if ODS_ENABLED + if (orcus_ods::detect(p, strm.size())) + return format_t::ods; +#endif +#if XLSX_ENABLED + if (orcus_xlsx::detect(p, strm.size())) + return format_t::xlsx; +#endif +#if GNUMERIC_ENABLED + if (orcus_gnumeric::detect(p, strm.size())) + return format_t::gnumeric; +#endif +#if XLS_XML_ENABLED + if (orcus_xls_xml::detect(p, strm.size())) + return format_t::xls_xml; +#endif +#if PARQUET_ENABLED + if (orcus_parquet::detect(p, strm.size())) + return format_t::parquet; +#endif + + return format_t::unknown; +} +catch (const std::exception&) +{ + return format_t::unknown; +} +catch (...) +{ + return format_t::unknown; +} + +std::shared_ptr<iface::import_filter> create_filter(format_t type, ss::iface::import_factory* factory) +{ + if (!factory) + throw std::invalid_argument("pointer to import factory instance must not be null"); + switch (type) + { +#if ODS_ENABLED + case format_t::ods: + return std::allocate_shared<orcus_ods>(std::allocator<orcus_ods>{}, factory); +#endif +#if XLSX_ENABLED + case format_t::xlsx: + return std::allocate_shared<orcus_xlsx>(std::allocator<orcus_xlsx>{}, factory); +#endif +#if GNUMERIC_ENABLED + case format_t::gnumeric: + return std::allocate_shared<orcus_gnumeric>(std::allocator<orcus_gnumeric>{}, factory); +#endif +#if XLS_XML_ENABLED + case format_t::xls_xml: + return std::allocate_shared<orcus_xls_xml>(std::allocator<orcus_xls_xml>{}, factory); +#endif +#if PARQUET_ENABLED + case format_t::parquet: + return std::allocate_shared<orcus_parquet>(std::allocator<orcus_parquet>{}, factory); +#endif + case format_t::csv: + return std::allocate_shared<orcus_csv>(std::allocator<orcus_csv>{}, factory); + case format_t::unknown: + default:; + } + return {}; +} + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/formula_result.cpp b/src/liborcus/formula_result.cpp new file mode 100644 index 0000000..bdde523 --- /dev/null +++ b/src/liborcus/formula_result.cpp @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "formula_result.hpp" + +#include <ostream> + +namespace orcus { + +formula_result::formula_result() : type(result_type::empty) {} +formula_result::formula_result(const formula_result& r) : + type(r.type) +{ + switch (type) + { + case result_type::numeric: + value_numeric = r.value_numeric; + break; + case result_type::boolean: + value_boolean = r.value_boolean; + break; + case result_type::string: + value_string.p = r.value_string.p; + value_string.n = r.value_string.n; + break; + case result_type::empty: + default: + ; + } +} + +formula_result::formula_result(double v) : type(result_type::numeric), value_numeric(v) {} +formula_result::formula_result(const char* p, size_t n) : + type(result_type::string) +{ + value_string.p = p; + value_string.n = n; +} + +formula_result::formula_result(bool b) : type(result_type::boolean), value_boolean(b) {} + +size_t range_formula_results::to_array_pos(size_t row, size_t col) const +{ + return row * m_cols + col; +} + +range_formula_results::range_formula_results(size_t rows, size_t cols) : + m_store(rows*cols), m_rows(rows), m_cols(cols) {} + +void range_formula_results::set(size_t row, size_t col, const formula_result& v) +{ + size_t pos = to_array_pos(row, col); + m_store[pos] = v; +} + +const formula_result& range_formula_results::get(size_t row, size_t col) const +{ + size_t pos = to_array_pos(row, col); + return m_store[pos]; +} + +size_t range_formula_results::row_size() const +{ + return m_rows; +} + +size_t range_formula_results::col_size() const +{ + return m_cols; +} + +std::ostream& operator<< (std::ostream& os, const formula_result& v) +{ + switch (v.type) + { + case formula_result::result_type::numeric: + os << v.value_numeric; + break; + case formula_result::result_type::boolean: + os << v.value_boolean; + break; + case formula_result::result_type::string: + os << std::string_view(v.value_string.p, v.value_string.n); + break; + case formula_result::result_type::empty: + break; + } + return os; +} + +std::ostream& operator<< (std::ostream& os, const orcus::range_formula_results& res) +{ + os << "{ "; + size_t col_pos = 0; + for (const formula_result& v : res.m_store) + { + if (col_pos == res.m_cols) + { + os << " | "; + col_pos = 0; + } + else if (col_pos > 0) + os << ", "; + + os << v; + ++col_pos; + } + + os << " }"; + + return os; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/formula_result.hpp b/src/liborcus/formula_result.hpp new file mode 100644 index 0000000..14665b3 --- /dev/null +++ b/src/liborcus/formula_result.hpp @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_FORMULA_RESULT_HPP +#define INCLUDED_ORCUS_FORMULA_RESULT_HPP + +#include <vector> +#include <cstdlib> +#include <iosfwd> + +namespace orcus { + +/** + * Stores cached formula result. Note that when the result is of string + * type, it only stores a pointer to the string buffer but the instance of + * this class does not own the buffer. + */ +struct formula_result +{ + enum class result_type { empty, numeric, string, boolean }; + + result_type type; + + union + { + double value_numeric; + bool value_boolean; + struct { const char* p; size_t n; } value_string; + }; + + formula_result(); + formula_result(const formula_result& r); + formula_result(double v); + formula_result(const char* p, size_t n); + formula_result(bool b); +}; + +class range_formula_results +{ + friend std::ostream& operator<< (std::ostream&, const range_formula_results&); + + std::vector<formula_result> m_store; + size_t m_rows; + size_t m_cols; + + size_t to_array_pos(size_t row, size_t col) const; + +public: + range_formula_results() = delete; + range_formula_results(const range_formula_results&) = delete; + range_formula_results(size_t rows, size_t cols); + + void set(size_t row, size_t col, const formula_result& v); + const formula_result& get(size_t row, size_t col) const; + + size_t row_size() const; + size_t col_size() const; +}; + +std::ostream& operator<< (std::ostream& os, const formula_result& v); +std::ostream& operator<< (std::ostream& os, const orcus::range_formula_results& res); + +} + + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_cell_context.cpp b/src/liborcus/gnumeric_cell_context.cpp new file mode 100644 index 0000000..07b82bc --- /dev/null +++ b/src/liborcus/gnumeric_cell_context.cpp @@ -0,0 +1,377 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gnumeric_token_constants.hpp" +#include "gnumeric_namespace_types.hpp" +#include "gnumeric_cell_context.hpp" +#include "gnumeric_value_format_parser.hpp" + +#include <orcus/spreadsheet/import_interface.hpp> +#include <orcus/measurement.hpp> + +#include <fstream> +#include <algorithm> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +gnumeric_cell_context::gnumeric_cell_context( + session_context& session_cxt, const tokens& tokens, ss::iface::import_factory* factory) : + xml_context_base(session_cxt, tokens), + mp_factory(factory), + mp_sheet(nullptr) +{ +} + +gnumeric_cell_context::~gnumeric_cell_context() = default; + +void gnumeric_cell_context::start_element( + xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) +{ + push_stack(ns, name); + + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Cell: + start_cell(attrs); + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool gnumeric_cell_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Cell: + end_cell(); + break; + default: + ; + } + } + return pop_stack(ns, name); +} + +void gnumeric_cell_context::characters(std::string_view str, bool transient) +{ + m_chars = str; + if (transient) + m_chars = intern(m_chars); +} + +void gnumeric_cell_context::reset(ss::iface::import_sheet* sheet) +{ + m_cell_data.reset(); + m_chars = std::string_view{}; + mp_sheet = sheet; + m_pool.clear(); +} + +void gnumeric_cell_context::start_cell(const xml_token_attrs_t& attrs) +{ + m_cell_data = cell_data{}; + m_cell_data->type = cell_type_formula; + m_format_segments.clear(); + + for (const auto& attr : attrs) + { + switch (attr.name) + { + case XML_Row: + m_cell_data->row = to_long(attr.value); + break; + case XML_Col: + m_cell_data->col = to_long(attr.value); + break; + case XML_ValueType: + { + auto v = to_long(attr.value); + m_cell_data->type = cell_type_value; + m_cell_data->value_type = static_cast<gnumeric_value_type>(v); + break; + } + case XML_ValueFormat: + { + auto v = attr.value; + if (attr.transient) + v = m_pool.intern(v).first; + + gnumeric_value_format_parser parser(v); + + try + { + parser.parse(); + } + catch (const parse_error& e) + { + std::ostringstream os; + os << "failed to parse a value format string: '" << v << "' (reason=" << e.what() << ")"; + warn(os.str()); + break; + } + + m_format_segments = parser.pop_segments(); + break; + } + case XML_ExprID: + m_cell_data->shared_formula_id = to_long(attr.value); + m_cell_data->type = cell_type_shared_formula; + break; + case XML_Rows: + m_cell_data->type = cell_type_value; + m_cell_data->value_type = vt_array; + m_cell_data->array_rows = to_long(attr.value); + break; + case XML_Cols: + m_cell_data->type = cell_type_value; + m_cell_data->value_type = vt_array; + m_cell_data->array_cols = to_long(attr.value); + break; + } + } +} + +void gnumeric_cell_context::end_cell() +{ + if (!m_cell_data) + return; + + if (!mp_sheet) + return; + + ss::col_t col = m_cell_data->col; + ss::row_t row = m_cell_data->row; + + switch (m_cell_data->type) + { + case cell_type_value: + { + if (!m_cell_data->value_type) + break; + + switch (*m_cell_data->value_type) + { + case vt_boolean: + { + bool val = to_bool(m_chars); + mp_sheet->set_bool(row, col, val); + break; + } + case vt_float: + { + double val = to_double(m_chars); + mp_sheet->set_value(row, col, val); + break; + } + case vt_string: + { + push_string(row, col); + break; + } + case vt_array: + { + ss::range_t range; + range.first.column = col; + range.first.row = row; + range.last.column = col + m_cell_data->array_cols - 1; + range.last.row = row + m_cell_data->array_rows - 1; + + ss::iface::import_array_formula* af = mp_sheet->get_array_formula(); + if (!af) + break; + + if (m_chars.empty() || m_chars[0] != '=') + // formula string should start with a '=' + break; + + af->set_range(range); + af->set_formula(ss::formula_grammar_t::gnumeric, m_chars.substr(1)); + af->commit(); + break; + } + default: + { + std::ostringstream os; + os << "unhandled cell value type (" << *m_cell_data->value_type << ")"; + warn(os.str()); + } + } + break; + } + case cell_type_formula: + { + ss::iface::import_formula* xformula = mp_sheet->get_formula(); + if (!xformula) + break; + + if (m_chars.empty() || m_chars[0] != '=') + // formula string should start with a '=' + break; + + xformula->set_position(row, col); + xformula->set_formula(ss::formula_grammar_t::gnumeric, m_chars.substr(1)); + xformula->commit(); + break; + } + case cell_type_shared_formula: + { + ss::iface::import_formula* xformula = mp_sheet->get_formula(); + if (!xformula) + break; + + xformula->set_position(row, col); + + if (!m_chars.empty() && m_chars[0] == '=') + xformula->set_formula(ss::formula_grammar_t::gnumeric, m_chars.substr(1)); + + xformula->set_shared_formula_index(m_cell_data->shared_formula_id); + xformula->commit(); + break; + } + case cell_type_unknown: + { + std::ostringstream os; + os << "cell type is unknown (row=" << row << "; col=" << col << ")"; + warn(os.str()); + break; + } + } + + m_cell_data.reset(); +} + +void gnumeric_cell_context::push_string(ss::row_t row, ss::col_t col) +{ + ss::iface::import_shared_strings* shared_strings = mp_factory->get_shared_strings(); + if (!shared_strings) + return; + + if (m_format_segments.empty()) + { + // unformatted text + std::size_t sid = shared_strings->add(m_chars); + mp_sheet->set_string(row, col, sid); + return; + } + + for (const auto& [start, end] : build_format_segment_ranges()) + { + assert(start < end); + + auto t = m_chars.substr(start, end - start); + + // TODO: use segment tree to eliminate this inner loop + for (const gnumeric_value_format_segment& vfs : m_format_segments) + { + if (vfs.value.empty()) + continue; + + if (start < vfs.start || vfs.end < end) + continue; + + // we have format information + switch (vfs.type) + { + case gnumeric_value_format_type::bold: + { + bool v = to_bool(vfs.value); + shared_strings->set_segment_bold(v); + break; + } + case gnumeric_value_format_type::italic: + { + bool v = to_bool(vfs.value); + shared_strings->set_segment_italic(v); + break; + } + case gnumeric_value_format_type::color: + { + // [red]x[green]x[blue] + auto color = parse_gnumeric_rgb_8x(vfs.value); + if (color) + shared_strings->set_segment_font_color(255, color->red, color->green, color->blue); + break; + } + case gnumeric_value_format_type::family: + { + if (!vfs.value.empty()) + shared_strings->set_segment_font_name(vfs.value); + break; + } + case gnumeric_value_format_type::size: + { + const char* p_end = nullptr; + double v = to_double(vfs.value, &p_end); + if (p_end > vfs.value.data()) + { + // font size here is stored in 1024ths of a point, likely coming from Pango + v /= 1024.0; + shared_strings->set_segment_font_size(v); + } + break; + } + default: + { + std::ostringstream os; + os << "unsupported format segment type (" << int(vfs.type) << ")"; + warn(os.str()); + } + } + } + + shared_strings->append_segment(t); + } + + std::size_t sid = shared_strings->commit_segments(); + mp_sheet->set_string(row, col, sid); +} + +std::vector<std::pair<std::size_t, std::size_t>> gnumeric_cell_context::build_format_segment_ranges() const +{ + if (m_format_segments.empty()) + return {}; + + std::vector<std::size_t> pts; + pts.push_back(0); + pts.push_back(m_chars.size()); + for (const auto& seg : m_format_segments) + { + pts.push_back(seg.start); + pts.push_back(seg.end); + } + + std::sort(pts.begin(), pts.end()); + auto last = std::unique(pts.begin(), pts.end()); + pts.erase(last, pts.end()); + assert(pts.size() > 2u); + + std::vector<std::pair<std::size_t, std::size_t>> ranges; + + auto it = pts.begin(); + auto start = *it; + for (++it; it != pts.end(); ++it) + { + auto end = *it; + ranges.emplace_back(start, end); + start = end; + } + + return ranges; +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_cell_context.hpp b/src/liborcus/gnumeric_cell_context.hpp new file mode 100644 index 0000000..b3c5f85 --- /dev/null +++ b/src/liborcus/gnumeric_cell_context.hpp @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_GNUMERIC_CELL_CONTEXT_HPP +#define INCLUDED_ORCUS_GNUMERIC_CELL_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "gnumeric_types.hpp" + +#include <orcus/spreadsheet/types.hpp> +#include <orcus/string_pool.hpp> + +#include <mdds/flat_segment_tree.hpp> + +#include <optional> + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_factory; +class import_sheet; + +}} + +struct gnumeric_cell_data; + +class gnumeric_cell_context : public xml_context_base +{ + enum cell_type + { + cell_type_unknown, + cell_type_value, + cell_type_formula, + cell_type_shared_formula, + }; + + struct cell_data + { + cell_type type = cell_type_unknown; + std::optional<gnumeric_value_type> value_type; + spreadsheet::row_t row = 0; + spreadsheet::col_t col = 0; + spreadsheet::row_t array_rows = 0; + spreadsheet::col_t array_cols = 0; + std::size_t shared_formula_id = 0; + }; + +public: + gnumeric_cell_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_factory* factory); + virtual ~gnumeric_cell_context() override; + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) override; + virtual bool end_element(xmlns_id_t ns, xml_token_t name) override; + virtual void characters(std::string_view str, bool transient) override; + + void reset(spreadsheet::iface::import_sheet* sheet); + +private: + void start_cell(const xml_token_attrs_t& attrs); + void end_cell(); + void push_string(spreadsheet::row_t row, spreadsheet::col_t col); + + std::vector<std::pair<std::size_t, std::size_t>> build_format_segment_ranges() const; + +private: + spreadsheet::iface::import_factory* mp_factory; + spreadsheet::iface::import_sheet* mp_sheet; + + std::vector<gnumeric_value_format_segment> m_format_segments; + std::optional<cell_data> m_cell_data; + std::string_view m_chars; + string_pool m_pool; +}; + +} // namespace orcus + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_cell_context_test.cpp b/src/liborcus/gnumeric_cell_context_test.cpp new file mode 100644 index 0000000..80d612c --- /dev/null +++ b/src/liborcus/gnumeric_cell_context_test.cpp @@ -0,0 +1,386 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gnumeric_cell_context.hpp" +#include "gnumeric_tokens.hpp" +#include "gnumeric_namespace_types.hpp" +#include "gnumeric_token_constants.hpp" +#include "mock_spreadsheet.hpp" +#include "session_context.hpp" +#include <orcus/types.hpp> + +#include <iostream> +#include <string> +#include <cstdlib> + +using namespace orcus; +using namespace std; +using namespace orcus::spreadsheet; +using namespace orcus::spreadsheet::mock; + +namespace { + +class mock_array_formula : public import_array_formula +{ +public: + virtual void set_range(const range_t& range) override + { + assert(range.first.row == 19); + assert(range.first.column == 111); + assert(range.last.row == 20); + assert(range.last.column == 113); + } + + virtual void set_formula(formula_grammar_t grammar, std::string_view formula) override + { + assert(grammar == formula_grammar_t::gnumeric); + assert(formula == "arrayFormula"); + } + + virtual void set_result_bool(row_t, col_t, bool) override + { + } + + virtual void set_result_empty(row_t, col_t) override + { + } + + virtual void set_result_string(row_t, col_t, std::string_view) override + { + } + + virtual void set_result_value(row_t, col_t, double) override + { + } + + virtual void commit() override + { + } +}; + +class mock_formula : public import_formula +{ +public: + virtual void set_position(row_t row, col_t col) override + { + assert(row == 9); + assert(col == 11); + } + + virtual void set_formula(formula_grammar_t grammar, std::string_view formula) override + { + assert(grammar == formula_grammar_t::gnumeric); + assert(formula == "formula"); + } + + virtual void set_shared_formula_index(size_t) override + { + } + + virtual void set_result_bool(bool) override + { + } + + virtual void set_result_empty() override + { + } + + virtual void set_result_string(std::string_view) override + { + } + + virtual void set_result_value(double) override + { + } + + virtual void commit() override + { + } +}; + +class mock_sheet : public import_sheet +{ + mock_formula m_formula; + mock_array_formula m_array_formula; +public: + virtual void set_value(row_t row, col_t col, double val) override + { + assert(row == 1); + assert(col == 2); + assert(val == 5.0); + } + + virtual void set_bool(row_t row, col_t col, bool val) override + { + assert(row == 31); + assert(col == 32); + assert(val == true); + } + + virtual void set_string(row_t row, col_t col, string_id_t id) override + { + assert(row == 10); + assert(col == 321); + assert(id == 2); + } + + virtual iface::import_array_formula* get_array_formula() override + { + return &m_array_formula; + } + + virtual iface::import_formula* get_formula() override + { + return &m_formula; + } +}; + +class mock_shared_strings : public import_shared_strings +{ +public: + virtual size_t add(std::string_view s) override + { + assert(s.size() == 14); + assert(s == "14 char string"); + return 2; + } +}; + +class mock_factory : public import_factory +{ +public: + virtual iface::import_shared_strings* get_shared_strings() + { + return &m_shared_strings; + } + +private: + mock_shared_strings m_shared_strings; +}; + +void test_cell_value() +{ + mock_sheet sheet; + import_factory factory; + session_context cxt; + + orcus::gnumeric_cell_context context(cxt, orcus::gnumeric_tokens, &factory); + context.reset(&sheet); + + orcus::xmlns_id_t ns = NS_gnumeric_gnm; + orcus::xml_token_t elem = XML_Cell; + orcus::xml_token_attrs_t attrs; + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Row, "1", false)); + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Col, "2", false)); + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_ValueType, "40", false)); + context.start_element(ns, elem, attrs); + context.characters("5", false); + context.end_element(ns, elem); +} + +void test_cell_bool() +{ + mock_sheet sheet; + import_factory factory; + session_context cxt; + + orcus::gnumeric_cell_context context(cxt, orcus::gnumeric_tokens, &factory); + context.reset(&sheet); + + orcus::xmlns_id_t ns = NS_gnumeric_gnm; + orcus::xml_token_t elem = XML_Cell; + orcus::xml_token_attrs_t attrs; + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Row, "31", false)); + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Col, "32", false)); + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_ValueType, "20", false)); + context.start_element(ns, elem, attrs); + context.characters("TRUE", false); + context.end_element(ns, elem); +} + +void test_cell_string() +{ + mock_sheet sheet; + mock_factory factory; + session_context cxt; + + orcus::gnumeric_cell_context context(cxt, orcus::gnumeric_tokens, &factory); + context.reset(&sheet); + + orcus::xmlns_id_t ns = NS_gnumeric_gnm; + orcus::xml_token_t elem = XML_Cell; + orcus::xml_token_attrs_t attrs; + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Row, "10", false)); + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Col, "321", false)); + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_ValueType, "60", false)); + context.start_element(ns, elem, attrs); + context.characters("14 char string", false); + context.end_element(ns, elem); +} + +void test_shared_formula_with_string() +{ + class mock_formula_local : public import_formula + { + public: + void set_position(row_t row, col_t col) override + { + assert(row == 5); + assert(col == 15); + } + + void set_formula(formula_grammar_t grammar, std::string_view formula) override + { + assert(grammar == formula_grammar_t::gnumeric); + assert(formula == "basicFormulaString"); + } + + void set_shared_formula_index(size_t index) override + { + assert(index == 2); + } + + void commit() override + { + } + }; + + class mock_sheet_local : public import_sheet + { + mock_formula_local m_formula; + public: + virtual iface::import_formula* get_formula() + { + return &m_formula; + } + }; + + mock_sheet_local sheet; + mock_factory factory; + session_context cxt; + + orcus::gnumeric_cell_context context(cxt, orcus::gnumeric_tokens, &factory); + context.reset(&sheet); + + orcus::xmlns_id_t ns = NS_gnumeric_gnm; + orcus::xml_token_t elem = XML_Cell; + orcus::xml_token_attrs_t attrs; + + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Row, "5", false)); + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Col, "15", false)); + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_ExprID, "2", false)); + + context.start_element(ns, elem, attrs); + context.characters("=basicFormulaString", false); + context.end_element(ns, elem); +} + +void test_shared_formula_without_string() +{ + class mock_formula_local : public import_formula + { + public: + void set_position(row_t row, col_t col) override + { + assert(row == 6); + assert(col == 16); + } + + void set_shared_formula_index(size_t index) override + { + assert(index == 3); + } + + void commit() override + { + } + }; + + class mock_sheet_local : public import_sheet + { + mock_formula_local m_formula; + public: + virtual iface::import_formula* get_formula() + { + return &m_formula; + } + }; + + mock_sheet_local sheet; + mock_factory factory; + session_context cxt; + + orcus::gnumeric_cell_context context(cxt, orcus::gnumeric_tokens, &factory); + context.reset(&sheet); + + orcus::xmlns_id_t ns = NS_gnumeric_gnm; + orcus::xml_token_t elem = XML_Cell; + orcus::xml_token_attrs_t attrs; + + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Row, "6", false)); + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Col, "16", false)); + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_ExprID, "3", false)); + + context.start_element(ns, elem, attrs); + context.end_element(ns, elem); +} + +void test_cell_formula() +{ + mock_sheet sheet; + mock_factory factory; + session_context cxt; + + orcus::gnumeric_cell_context context(cxt, orcus::gnumeric_tokens, &factory); + context.reset(&sheet); + + orcus::xmlns_id_t ns = NS_gnumeric_gnm; + orcus::xml_token_t elem = XML_Cell; + orcus::xml_token_attrs_t attrs; + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Row, "9", false)); + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Col, "11", false)); + context.start_element(ns, elem, attrs); + context.characters("=formula", false); + context.end_element(ns, elem); +} + +void test_cell_array_formula() +{ + mock_sheet sheet; + mock_factory factory; + session_context cxt; + + orcus::gnumeric_cell_context context(cxt, orcus::gnumeric_tokens, &factory); + context.reset(&sheet); + + orcus::xmlns_id_t ns = NS_gnumeric_gnm; + orcus::xml_token_t elem = XML_Cell; + orcus::xml_token_attrs_t attrs; + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Row, "19", false)); + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Col, "111", false)); + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Rows, "2", false)); + attrs.push_back(xml_token_attr_t(NS_gnumeric_gnm, XML_Cols, "3", false)); + context.start_element(ns, elem, attrs); + context.characters("arrayFormula", false); + context.end_element(ns, elem); +} + +} + +int main() +{ + test_cell_value(); + test_cell_bool(); + test_cell_string(); + test_shared_formula_with_string(); + test_shared_formula_without_string(); + test_cell_formula(); + test_cell_array_formula(); + + return EXIT_SUCCESS; +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_context.cpp b/src/liborcus/gnumeric_context.cpp new file mode 100644 index 0000000..33c8d44 --- /dev/null +++ b/src/liborcus/gnumeric_context.cpp @@ -0,0 +1,453 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gnumeric_context.hpp" +#include "gnumeric_token_constants.hpp" +#include "gnumeric_namespace_types.hpp" +#include "gnumeric_sheet_context.hpp" +#include "impl_utils.hpp" + +#include <orcus/spreadsheet/import_interface.hpp> +#include <orcus/spreadsheet/import_interface_styles.hpp> + +#include <fstream> +#include <algorithm> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace { + +std::size_t import_font_style(ss::iface::import_styles& istyles, const gnumeric_style& style) +{ + ss::iface::import_font_style* ifont = istyles.start_font_style(); + ENSURE_INTERFACE(ifont, import_font_style); + + if (style.font_name) + ifont->set_name(*style.font_name); + + if (style.font_unit) + ifont->set_size(*style.font_unit); + + if (style.bold) + ifont->set_bold(*style.bold); + + if (style.italic) + ifont->set_italic(*style.italic); + + if (style.underline) + { + if (*style.underline) + ifont->set_underline(ss::underline_t::single_line); + else + ifont->set_underline(ss::underline_t::none); + } + + if (style.strikethrough) + { + if (*style.strikethrough) + { + ifont->set_strikethrough_style(ss::strikethrough_style_t::solid); + ifont->set_strikethrough_type(ss::strikethrough_type_t::single_type); + ifont->set_strikethrough_width(ss::strikethrough_width_t::width_auto); + } + else + { + ifont->set_strikethrough_style(ss::strikethrough_style_t::none); + ifont->set_strikethrough_type(ss::strikethrough_type_t::none); + } + } + + if (style.fore) + ifont->set_color(255, style.fore->red, style.fore->green, style.fore->blue); + + return ifont->commit(); +} + +std::optional<std::size_t> import_fill_style( + ss::iface::import_styles& istyles, const gnumeric_style& style) +{ + if (style.pattern == ss::fill_pattern_t::none) + return {}; + + ss::iface::import_fill_style* ifill = istyles.start_fill_style(); + ENSURE_INTERFACE(ifill, import_fill_style); + + ifill->set_pattern_type(style.pattern); + + if (style.back) + ifill->set_fg_color( + 255, + style.back->red, + style.back->green, + style.back->blue); + + if (style.pattern_color) + ifill->set_bg_color( + 255, + style.pattern_color->red, + style.pattern_color->green, + style.pattern_color->blue); + + return ifill->commit(); +} + +std::optional<std::size_t> import_border_styles( + ss::iface::import_styles& istyles, const gnumeric_style& style) +{ + ss::iface::import_border_style* iborder = istyles.start_border_style(); + ENSURE_INTERFACE(iborder, import_border_style); + + auto func_import_border = [&iborder](ss::border_direction_t dir, const gnumeric_style::border_type& border) + { + bool has_style = false; + + if (border.style) + { + iborder->set_style(dir, to_standard_type(*border.style)); + has_style = true; + } + + if (border.color) + { + iborder->set_color( + dir, 255, border.color->red, border.color->green, border.color->blue); + has_style = true; + } + + return has_style; + }; + + bool has_style = false; + + if (func_import_border(ss::border_direction_t::top, style.border_top)) + has_style = true; + + if (func_import_border(ss::border_direction_t::bottom, style.border_bottom)) + has_style = true; + + if (func_import_border(ss::border_direction_t::left, style.border_left)) + has_style = true; + + if (func_import_border(ss::border_direction_t::right, style.border_right)) + has_style = true; + + if (func_import_border(ss::border_direction_t::diagonal_bl_tr, style.border_bl_tr)) + has_style = true; + + if (func_import_border(ss::border_direction_t::diagonal_tl_br, style.border_br_tl)) + has_style = true; + + if (!has_style) + return {}; + + return iborder->commit(); +} + +std::optional<std::size_t> import_number_format( + ss::iface::import_styles& istyles, const gnumeric_style& style) +{ + if (!style.number_format) + return {}; + + ss::iface::import_number_format* inumfmt = istyles.start_number_format(); + ENSURE_INTERFACE(inumfmt, import_number_format); + + inumfmt->set_code(*style.number_format); + return inumfmt->commit(); +} + +} // anonymous namespace + +gnumeric_content_xml_context::gnumeric_content_xml_context( + session_context& session_cxt, const tokens& tokens, spreadsheet::iface::import_factory* factory) : + xml_context_base(session_cxt, tokens), + mp_factory(factory), + m_sheet_pos(0), + m_cxt_names(session_cxt, tokens, factory), + m_cxt_sheet(session_cxt, tokens, factory) +{ + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_gnumeric_gnm, XML_Workbook }, // root element + { NS_gnumeric_gnm, XML_SheetNameIndex, NS_gnumeric_gnm, XML_SheetName }, + { NS_gnumeric_gnm, XML_Sheets, NS_gnumeric_gnm, XML_Sheet }, + { NS_gnumeric_gnm, XML_Workbook, NS_gnumeric_gnm, XML_Names }, + { NS_gnumeric_gnm, XML_Workbook, NS_gnumeric_gnm, XML_SheetNameIndex }, + { NS_gnumeric_gnm, XML_Workbook, NS_gnumeric_gnm, XML_Sheets }, + }; + + init_element_validator(rules, std::size(rules)); + + register_child(&m_cxt_names); + register_child(&m_cxt_sheet); +} + +gnumeric_content_xml_context::~gnumeric_content_xml_context() = default; + +xml_context_base* gnumeric_content_xml_context::create_child_context(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Sheet: + { + m_cxt_sheet.reset(m_sheet_pos++); + return &m_cxt_sheet; + } + case XML_Names: + { + m_cxt_names.reset(); + return &m_cxt_names; + } + } + } + + return nullptr; +} + +void gnumeric_content_xml_context::end_child_context( + xmlns_id_t ns, xml_token_t name, xml_context_base* child) +{ + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Sheet: + { + assert(child == &m_cxt_sheet); + end_sheet(); + break; + } + case XML_Names: + { + assert(child == &m_cxt_names); + end_names(); + break; + } + } + } +} + +void gnumeric_content_xml_context::start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& /*attrs*/) +{ + push_stack(ns, name); + + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_SheetNameIndex: + m_sheet_pos = 0; + break; + case XML_SheetName: + break; + case XML_Sheets: + m_sheet_pos = 0; + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool gnumeric_content_xml_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Sheets: + end_sheets(); + break; + } + } + return pop_stack(ns, name); +} + +void gnumeric_content_xml_context::characters(std::string_view str, bool /*transient*/) +{ + if (str.empty()) + return; + + const auto [ns, name] = get_current_element(); + + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_SheetName: + { + auto* p = mp_factory->append_sheet(m_sheet_pos++, str); + if (!p) + { + std::ostringstream os; + os << "failed to append a new sheet named '" << str << "'"; + warn(os.str()); + } + + break; + } + } + } +} + +void gnumeric_content_xml_context::end_names() +{ + ss::iface::import_named_expression* named_exp = mp_factory->get_named_expression(); + if (!named_exp) + return; + + for (const auto& name : m_cxt_names.get_names()) + { + try + { + named_exp->set_base_position(name.position); + named_exp->set_named_expression(name.name, name.value); + named_exp->commit(); + } + catch (const std::exception& e) + { + std::ostringstream os; + os << "failed to commit a named expression named '" << name.name + << "': (reason='" << e.what() << "'; value='" << name.value << "')"; + warn(os.str()); + } + } +} + +void gnumeric_content_xml_context::end_sheet() +{ + m_styles.push_back(m_cxt_sheet.pop_styles()); +} + +void gnumeric_content_xml_context::end_sheets() +{ + import_styles(); +} + +void gnumeric_content_xml_context::import_styles() +{ + ss::iface::import_styles* istyles = mp_factory->get_styles(); + if (!istyles) + return; + + std::size_t xf_count = 1; // one for the default style + for (const auto& sheet_styles : m_styles) + xf_count += sheet_styles.size(); + + istyles->set_xf_count(ss::xf_category_t::cell, xf_count); + + import_default_styles(istyles); + import_cell_styles(istyles); +} + +void gnumeric_content_xml_context::import_default_styles(ss::iface::import_styles* istyles) +{ + assert(istyles); + + ss::iface::import_font_style* ifont = istyles->start_font_style(); + ENSURE_INTERFACE(ifont, imort_font_style); + std::size_t id = ifont->commit(); + assert(id == 0); + + ss::iface::import_fill_style* ifill = istyles->start_fill_style(); + ENSURE_INTERFACE(ifill, imort_fill_style); + id = ifill->commit(); + assert(id == 0); + + ss::iface::import_border_style* iborder = istyles->start_border_style(); + ENSURE_INTERFACE(iborder, imort_border_style); + id = iborder->commit(); + assert(id == 0); + + ss::iface::import_cell_protection* iprotection = istyles->start_cell_protection(); + ENSURE_INTERFACE(iprotection, imort_cell_protection); + id = iprotection->commit(); + assert(id == 0); + + ss::iface::import_number_format* inumfmt = istyles->start_number_format(); + ENSURE_INTERFACE(inumfmt, import_number_format); + id = inumfmt->commit(); + assert(id == 0); + + ss::iface::import_xf* ixf = istyles->start_xf(ss::xf_category_t::cell); + ENSURE_INTERFACE(ixf, import_xf); + id = ixf->commit(); + assert(id == 0); + + ss::iface::import_cell_style* xstyle = istyles->start_cell_style(); + ENSURE_INTERFACE(xstyle, import_cell_style); + xstyle->set_xf(0); + xstyle->commit(); +} + +void gnumeric_content_xml_context::import_cell_styles(ss::iface::import_styles* istyles) +{ + assert(istyles); + + for (const auto& sheet_styles : m_styles) + { + for (const gnumeric_style& style : sheet_styles) + { + assert(style.valid()); // should be validated before insertion + + ss::iface::import_sheet* isheet = mp_factory->get_sheet(style.sheet); + if (!isheet) + continue; + + std::size_t id_font = import_font_style(*istyles, style); + auto id_fill = import_fill_style(*istyles, style); + auto id_border = import_border_styles(*istyles, style); + auto id_numfmt = import_number_format(*istyles, style); + + ss::iface::import_xf* ixf = istyles->start_xf(ss::xf_category_t::cell); + ENSURE_INTERFACE(ixf, import_xf); + + ixf->set_font(id_font); + + if (id_fill) + ixf->set_fill(*id_fill); + + if (id_border) + ixf->set_border(*id_border); + + if (id_numfmt) + ixf->set_number_format(*id_numfmt); + + bool apply_alignment = + style.hor_align != ss::hor_alignment_t::unknown || + style.ver_align != ss::ver_alignment_t::unknown || + style.wrap_text; + + ixf->set_apply_alignment(apply_alignment); + + if (style.hor_align != ss::hor_alignment_t::unknown) + ixf->set_horizontal_alignment(style.hor_align); + + if (style.ver_align != ss::ver_alignment_t::unknown) + ixf->set_vertical_alignment(style.ver_align); + + if (style.wrap_text) + ixf->set_wrap_text(*style.wrap_text); + + std::size_t xfid = ixf->commit(); + isheet->set_format( + style.region.first.row, style.region.first.column, + style.region.last.row, style.region.last.column, + xfid); + } + } +} + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_context.hpp b/src/liborcus/gnumeric_context.hpp new file mode 100644 index 0000000..f6d066c --- /dev/null +++ b/src/liborcus/gnumeric_context.hpp @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_GNUMERICCONTEXT_HPP +#define INCLUDED_ORCUS_GNUMERICCONTEXT_HPP + +#include "xml_context_base.hpp" +#include "gnumeric_sheet_context.hpp" +#include "gnumeric_names_context.hpp" +#include "gnumeric_types.hpp" + +#include <orcus/spreadsheet/types.hpp> + +#include <vector> + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_factory; +class import_sheet; +class import_styles; + +}} + +class gnumeric_content_xml_context : public xml_context_base +{ +public: + gnumeric_content_xml_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_factory* factory); + + virtual ~gnumeric_content_xml_context() override; + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name) override; + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) override; + virtual void start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) override; + virtual bool end_element(xmlns_id_t ns, xml_token_t name) override; + virtual void characters(std::string_view str, bool transient) override; + +private: + void end_names(); + void end_sheet(); + void end_sheets(); + + void import_styles(); + void import_default_styles(spreadsheet::iface::import_styles* istyles); + void import_cell_styles(spreadsheet::iface::import_styles* istyles); + +private: + spreadsheet::iface::import_factory* mp_factory; + spreadsheet::sheet_t m_sheet_pos; + + gnumeric_names_context m_cxt_names; + gnumeric_sheet_context m_cxt_sheet; + + std::vector<std::vector<gnumeric_style>> m_styles; +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_detection_handler.cpp b/src/liborcus/gnumeric_detection_handler.cpp new file mode 100644 index 0000000..1f0606e --- /dev/null +++ b/src/liborcus/gnumeric_detection_handler.cpp @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gnumeric_detection_handler.hpp" +#include "gnumeric_namespace_types.hpp" +#include "gnumeric_token_constants.hpp" +#include "xml_context_base.hpp" +#include "detection_result.hpp" + +namespace orcus { + +namespace { + +/** + * Check the xml structure up to the first <gnm:Sheet> element. If all the + * structure check passes up to that point, we call it "detected". + */ +class gnumeric_detection_context : public xml_context_base +{ +public: + gnumeric_detection_context(session_context& session_cxt, const tokens& tokens) : + xml_context_base(session_cxt, tokens) {} + + virtual xml_context_base* create_child_context(xmlns_id_t, xml_token_t) { return nullptr; } + virtual void characters(std::string_view, bool) {} + virtual void end_child_context(xmlns_id_t, xml_token_t, xml_context_base*) {} + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& /*attrs*/) + { + xml_token_pair_t parent = push_stack(ns, name); + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Workbook: + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + break; + case XML_Version: + case XML_Attributes: + case XML_Calculation: + case XML_SheetNameIndex: + case XML_Geometry: + case XML_Sheets: + xml_element_expected(parent, NS_gnumeric_gnm, XML_Workbook); + break; + case XML_Attribute: + xml_element_expected(parent, NS_gnumeric_gnm, XML_Attributes); + break; + case XML_SheetName: + xml_element_expected(parent, NS_gnumeric_gnm, XML_SheetNameIndex); + break; + case XML_Sheet: + xml_element_expected(parent, NS_gnumeric_gnm, XML_Sheets); + throw detection_result(true); + break; + default: + ; + } + } + } + + virtual bool end_element(xmlns_id_t ns, xml_token_t name) + { + return pop_stack(ns, name); + } +}; + +} + +gnumeric_detection_handler::gnumeric_detection_handler(session_context& session_cxt, const tokens& t) : + xml_stream_handler(session_cxt, t, std::make_unique<gnumeric_detection_context>(session_cxt, t)) {} + +gnumeric_detection_handler::~gnumeric_detection_handler() {} + +void gnumeric_detection_handler::start_document() {} +void gnumeric_detection_handler::end_document() {} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_detection_handler.hpp b/src/liborcus/gnumeric_detection_handler.hpp new file mode 100644 index 0000000..e7644a3 --- /dev/null +++ b/src/liborcus/gnumeric_detection_handler.hpp @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_GNUMERIC_DETECTION_HANDLER_HPP +#define ORCUS_GNUMERIC_DETECTION_HANDLER_HPP + +#include "xml_stream_handler.hpp" + +namespace orcus { + +struct session_context; +class tokens; + +class gnumeric_detection_handler : public xml_stream_handler +{ +public: + gnumeric_detection_handler(session_context& session_cxt, const tokens& t); + virtual ~gnumeric_detection_handler(); + + virtual void start_document(); + virtual void end_document(); +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_filter_context.cpp b/src/liborcus/gnumeric_filter_context.cpp new file mode 100644 index 0000000..f15d2a0 --- /dev/null +++ b/src/liborcus/gnumeric_filter_context.cpp @@ -0,0 +1,256 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gnumeric_filter_context.hpp" +#include "gnumeric_token_constants.hpp" +#include "gnumeric_namespace_types.hpp" + +#include <orcus/spreadsheet/import_interface.hpp> +#include <orcus/measurement.hpp> + +#include <iostream> +#include <optional> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace { + +enum gnumeric_filter_field_op_t +{ + filter_equal, + filter_greaterThan, + filter_lessThan, + filter_greaterThanEqual, + filter_lessThanEqual, + filter_notEqual, + filter_op_invalid +}; + +enum gnumeric_filter_field_type_t +{ + filter_expr, + filter_blanks, + filter_nonblanks, + filter_type_invalid +}; + +} // anonymous namespace + +gnumeric_filter_context::gnumeric_filter_context( + session_context& session_cxt, const tokens& tokens, + ss::iface::import_factory* factory) : + xml_context_base(session_cxt, tokens), + mp_factory(factory) +{ + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_gnumeric_gnm, XML_Filter }, // root element + { NS_gnumeric_gnm, XML_Filter, NS_gnumeric_gnm, XML_Field }, + }; + + init_element_validator(rules, std::size(rules)); +} + +gnumeric_filter_context::~gnumeric_filter_context() = default; + +void gnumeric_filter_context::start_element( + xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) +{ + push_stack(ns, name); + + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Filter: + { + start_filter(attrs); + break; + } + case XML_Field: + { + start_field(attrs); + break; + } + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool gnumeric_filter_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Filter: + end_filter(); + break; + case XML_Field: + end_field(); + break; + } + } + + return pop_stack(ns, name); +} + +void gnumeric_filter_context::reset(spreadsheet::iface::import_sheet* sheet) +{ + mp_sheet = sheet; + mp_auto_filter = nullptr; +} + +void gnumeric_filter_context::start_filter(const xml_token_attrs_t& attrs) +{ + if (!mp_sheet) + return; + + ss::iface::import_reference_resolver* resolver = + mp_factory->get_reference_resolver(ss::formula_ref_context_t::global); + + if (!resolver) + return; + + mp_auto_filter = mp_sheet->get_auto_filter(); + if (!mp_auto_filter) + return; + + std::optional<spreadsheet::range_t> area; + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_Area: + area = to_rc_range(resolver->resolve_range(attr.value)); + break; + default: + ; + } + } + + if (!area) + { + mp_auto_filter = nullptr; + return; + } + + mp_auto_filter->set_range(*area); +} + +void gnumeric_filter_context::start_field(const xml_token_attrs_t& attrs) +{ + if (!mp_auto_filter) + return; + + gnumeric_filter_field_type_t filter_field_type = filter_type_invalid; + gnumeric_filter_field_op_t filter_op = filter_op_invalid; + + ss::col_t col = -1; + std::string_view filter_value_type; + std::string_view filter_value; + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_Index: + { + col = to_long(attr.value.data()); + break; + } + case XML_Type: + { + if (attr.value == "expr") + filter_field_type = filter_expr; + else if (attr.value == "blanks") + filter_field_type = filter_blanks; + else if (attr.value == "nonblanks") + filter_field_type = filter_nonblanks; + break; + } + case XML_Op0: + { + if (attr.value == "eq") + filter_op = filter_equal; + else if (attr.value == "gt") + filter_op = filter_greaterThan; + else if (attr.value == "lt") + filter_op = filter_lessThan; + else if (attr.value == "gte") + filter_op = filter_greaterThanEqual; + else if (attr.value == "lte") + filter_op = filter_lessThanEqual; + else if (attr.value == "ne") + filter_op = filter_notEqual; + break; + } + case XML_Value0: + { + filter_value_type = attr.value; + break; + } + case XML_ValueType0: + { + filter_value = attr.value; + break; + } + } + } + + if (col < 0) + return; + + mp_auto_filter->set_column(col); + + switch (filter_field_type) + { + case filter_expr: + { + // only equal supported in API yet + if (filter_op != filter_equal) + return; + + // import condition for integer (30), double(40) and string (60) + if (filter_value_type == "30" || + filter_value_type == "40" || + filter_value_type == "60" ) + { + mp_auto_filter->append_column_match_value(filter_value); + } + break; + } + case filter_blanks: + break; + case filter_nonblanks: + break; + case filter_type_invalid: + break; + } +} + +void gnumeric_filter_context::end_filter() +{ + if (mp_auto_filter) + mp_auto_filter->commit(); +} + +void gnumeric_filter_context::end_field() +{ + if (mp_auto_filter) + mp_auto_filter->commit_column(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_filter_context.hpp b/src/liborcus/gnumeric_filter_context.hpp new file mode 100644 index 0000000..b8c794b --- /dev/null +++ b/src/liborcus/gnumeric_filter_context.hpp @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "xml_context_base.hpp" + +#include <orcus/spreadsheet/types.hpp> + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_factory; +class import_sheet; +class import_auto_filter; + +}} + +class gnumeric_filter_context : public xml_context_base +{ +public: + gnumeric_filter_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_factory* factory); + virtual ~gnumeric_filter_context() override; + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) override; + + virtual bool end_element(xmlns_id_t ns, xml_token_t name) override; + + void reset(spreadsheet::iface::import_sheet* sheet); + +private: + void start_filter(const xml_token_attrs_t& attrs); + void start_field(const xml_token_attrs_t& attrs); + + void end_filter(); + void end_field(); + + +private: + spreadsheet::iface::import_factory* mp_factory = nullptr; + spreadsheet::iface::import_sheet* mp_sheet = nullptr; + spreadsheet::iface::import_auto_filter* mp_auto_filter = nullptr; +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_handler.cpp b/src/liborcus/gnumeric_handler.cpp new file mode 100644 index 0000000..67e428f --- /dev/null +++ b/src/liborcus/gnumeric_handler.cpp @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gnumeric_handler.hpp" +#include "gnumeric_context.hpp" + +namespace orcus { + +gnumeric_content_xml_handler::gnumeric_content_xml_handler( + session_context& session_cxt, const tokens& t, spreadsheet::iface::import_factory* factory) : + xml_stream_handler(session_cxt, t, std::make_unique<gnumeric_content_xml_context>(session_cxt, t, factory)) +{ +} + +gnumeric_content_xml_handler::~gnumeric_content_xml_handler() +{ +} + +void gnumeric_content_xml_handler::start_document() +{ +} + +void gnumeric_content_xml_handler::end_document() +{ +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_handler.hpp b/src/liborcus/gnumeric_handler.hpp new file mode 100644 index 0000000..1c389c3 --- /dev/null +++ b/src/liborcus/gnumeric_handler.hpp @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef __ORCUS_GNUMERICHANDLER_HPP__ +#define __ORCUS_GNUMERICHANDLER_HPP__ + +#include "xml_stream_handler.hpp" + +namespace orcus { + +struct session_context; +class tokens; + +namespace spreadsheet { namespace iface { class import_factory; }} + +/** + * Handler for parsing the content.xml part. + */ +class gnumeric_content_xml_handler : public xml_stream_handler +{ +public: + gnumeric_content_xml_handler(session_context& session_cxt, const tokens& t, spreadsheet::iface::import_factory* factory); + virtual ~gnumeric_content_xml_handler(); + + virtual void start_document(); + virtual void end_document(); +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_names_context.cpp b/src/liborcus/gnumeric_names_context.cpp new file mode 100644 index 0000000..9c008af --- /dev/null +++ b/src/liborcus/gnumeric_names_context.cpp @@ -0,0 +1,110 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gnumeric_names_context.hpp" +#include "gnumeric_token_constants.hpp" +#include "gnumeric_namespace_types.hpp" + +#include <orcus/spreadsheet/import_interface.hpp> + +#include <iostream> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +gnumeric_names_context::gnumeric_names_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_factory* factory) : + xml_context_base(session_cxt, tokens), + mp_factory(factory) +{ + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_gnumeric_gnm, XML_Names }, // root element + { NS_gnumeric_gnm, XML_Names, NS_gnumeric_gnm, XML_Name }, + { NS_gnumeric_gnm, XML_Name, NS_gnumeric_gnm, XML_name }, + { NS_gnumeric_gnm, XML_Name, NS_gnumeric_gnm, XML_value }, + { NS_gnumeric_gnm, XML_Name, NS_gnumeric_gnm, XML_position }, + }; + + init_element_validator(rules, std::size(rules)); +} + +gnumeric_names_context::~gnumeric_names_context() = default; + +void gnumeric_names_context::start_element( + xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& /*attrs*/) +{ + push_stack(ns, name); + + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Name: + m_current_name.reset(); + break; + } + } +} + +bool gnumeric_names_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Name: + m_named_exps.push_back(m_current_name); + break; + } + } + return pop_stack(ns, name); +} + +void gnumeric_names_context::characters(std::string_view str, bool transient) +{ + const auto [ns, name] = get_current_element(); + + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_name: + m_current_name.name = transient ? intern(str) : str; + break; + case XML_value: + m_current_name.value = transient ? intern(str) : str; + break; + case XML_position: + { + ss::iface::import_reference_resolver* resolver = + mp_factory->get_reference_resolver(ss::formula_ref_context_t::global); + + if (resolver) + m_current_name.position = resolver->resolve_address(str); + + break; + } + } + } +} + +void gnumeric_names_context::reset() +{ + m_named_exps.clear(); +} + +const std::vector<gnumeric_named_exp>& gnumeric_names_context::get_names() const +{ + return m_named_exps; +} + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_names_context.hpp b/src/liborcus/gnumeric_names_context.hpp new file mode 100644 index 0000000..1fb0416 --- /dev/null +++ b/src/liborcus/gnumeric_names_context.hpp @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "xml_context_base.hpp" +#include "gnumeric_types.hpp" + +#include <vector> + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_factory; + +}} + +class gnumeric_names_context : public xml_context_base +{ +public: + gnumeric_names_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_factory* factory); + + virtual ~gnumeric_names_context() override; + + virtual void start_element( + xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) override; + virtual bool end_element(xmlns_id_t ns, xml_token_t name) override; + virtual void characters(std::string_view str, bool transient) override; + + void reset(); + + const std::vector<gnumeric_named_exp>& get_names() const; + +private: + spreadsheet::iface::import_factory* mp_factory = nullptr; + std::vector<gnumeric_named_exp> m_named_exps; + gnumeric_named_exp m_current_name; +}; + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_namespace_types.cpp b/src/liborcus/gnumeric_namespace_types.cpp new file mode 100644 index 0000000..1ff0ec9 --- /dev/null +++ b/src/liborcus/gnumeric_namespace_types.cpp @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gnumeric_namespace_types.hpp" +#include "odf_namespace_types.hpp" + +namespace orcus { + +const xmlns_id_t NS_gnumeric_dc = "http://purl.org/dc/elements/1.1/"; +const xmlns_id_t NS_gnumeric_gnm = "http://www.gnumeric.org/v10.dtd"; +const xmlns_id_t NS_gnumeric_ooo = "http://openoffice.org/2004/office"; +const xmlns_id_t NS_gnumeric_xlink = "http://www.w3.org/1999/xlink"; +const xmlns_id_t NS_gnumeric_xsi = "http://www.w3.org/2001/XMLSchema-instance"; + +namespace { + +xmlns_id_t gnumeric_ns[] = { + NS_gnumeric_dc, + NS_gnumeric_gnm, + NS_gnumeric_ooo, + NS_gnumeric_xlink, + NS_gnumeric_xsi, + + NS_odf_meta, + NS_odf_office, + nullptr +}; + +} + +const xmlns_id_t* NS_gnumeric_all = gnumeric_ns; + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_namespace_types.hpp b/src/liborcus/gnumeric_namespace_types.hpp new file mode 100644 index 0000000..2d6b7ab --- /dev/null +++ b/src/liborcus/gnumeric_namespace_types.hpp @@ -0,0 +1,26 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef __ORCUS_GNUMERIC_NAMESPACE_TYPES_HPP__ +#define __ORCUS_GNUMERIC_NAMESPACE_TYPES_HPP__ + +#include "orcus/types.hpp" + +namespace orcus { + +extern const xmlns_id_t NS_gnumeric_dc; +extern const xmlns_id_t NS_gnumeric_gnm; +extern const xmlns_id_t NS_gnumeric_ooo; +extern const xmlns_id_t NS_gnumeric_xlink; +extern const xmlns_id_t NS_gnumeric_xsi; + +extern const xmlns_id_t* NS_gnumeric_all; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_sheet_context.cpp b/src/liborcus/gnumeric_sheet_context.cpp new file mode 100644 index 0000000..aecca4c --- /dev/null +++ b/src/liborcus/gnumeric_sheet_context.cpp @@ -0,0 +1,819 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gnumeric_sheet_context.hpp" +#include "gnumeric_cell_context.hpp" +#include "gnumeric_token_constants.hpp" +#include "gnumeric_namespace_types.hpp" +#include "impl_utils.hpp" + +#include <orcus/spreadsheet/import_interface.hpp> +#include <orcus/spreadsheet/import_interface_styles.hpp> +#include <orcus/measurement.hpp> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace { + +ss::condition_operator_t get_condition_operator(int val) +{ + switch (val) + { + case 0: + return ss::condition_operator_t::between; + case 1: + return ss::condition_operator_t::not_between; + case 2: + return ss::condition_operator_t::equal; + case 3: + return ss::condition_operator_t::not_equal; + case 4: + return ss::condition_operator_t::greater; + case 5: + return ss::condition_operator_t::less; + case 6: + return ss::condition_operator_t::greater_equal; + case 7: + return ss::condition_operator_t::less_equal; + case 8: + return ss::condition_operator_t::expression; + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + break; + case 16: + return ss::condition_operator_t::contains; + case 17: + return ss::condition_operator_t::not_contains; + case 18: + return ss::condition_operator_t::begins_with; + case 19: + break; + case 20: + return ss::condition_operator_t::ends_with; + case 21: + break; + case 22: + return ss::condition_operator_t::contains_error; + case 23: + return ss::condition_operator_t::contains_no_error; + default: + break; + } + return ss::condition_operator_t::unknown; +} + +} // anonymous namespace + +gnumeric_sheet_context::gnumeric_sheet_context( + session_context& session_cxt, const tokens& tokens, ss::iface::import_factory* factory) : + xml_context_base(session_cxt, tokens), + mp_factory(factory), + m_cxt_cell(session_cxt, tokens, factory), + m_cxt_filter(session_cxt, tokens, factory), + m_cxt_names(session_cxt, tokens, factory), + m_cxt_styles(session_cxt, tokens, factory) +{ + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_gnumeric_gnm, XML_Sheet }, // root element + { NS_gnumeric_gnm, XML_Cells, NS_gnumeric_gnm, XML_Cell }, + { NS_gnumeric_gnm, XML_Cols, NS_gnumeric_gnm, XML_ColInfo }, + { NS_gnumeric_gnm, XML_MergedRegions, NS_gnumeric_gnm, XML_Merge }, + { NS_gnumeric_gnm, XML_Rows, NS_gnumeric_gnm, XML_RowInfo }, + { NS_gnumeric_gnm, XML_Sheet, NS_gnumeric_gnm, XML_Cells }, + { NS_gnumeric_gnm, XML_Sheet, NS_gnumeric_gnm, XML_Cols }, + { NS_gnumeric_gnm, XML_Sheet, NS_gnumeric_gnm, XML_Filters }, + { NS_gnumeric_gnm, XML_Sheet, NS_gnumeric_gnm, XML_MergedRegions }, + { NS_gnumeric_gnm, XML_Sheet, NS_gnumeric_gnm, XML_Name }, + { NS_gnumeric_gnm, XML_Sheet, NS_gnumeric_gnm, XML_Names }, + { NS_gnumeric_gnm, XML_Sheet, NS_gnumeric_gnm, XML_Rows }, + { NS_gnumeric_gnm, XML_Sheet, NS_gnumeric_gnm, XML_Selections }, + { NS_gnumeric_gnm, XML_Sheet, NS_gnumeric_gnm, XML_SheetLayout }, + { NS_gnumeric_gnm, XML_Sheet, NS_gnumeric_gnm, XML_Styles }, + }; + + init_element_validator(rules, std::size(rules)); + + register_child(&m_cxt_cell); + register_child(&m_cxt_filter); + register_child(&m_cxt_names); + register_child(&m_cxt_styles); +} + +gnumeric_sheet_context::~gnumeric_sheet_context() = default; + +xml_context_base* gnumeric_sheet_context::create_child_context(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Cells: + { + m_cxt_cell.reset(mp_sheet); + return &m_cxt_cell; + } + case XML_Filter: + { + m_cxt_filter.reset(mp_sheet); + return &m_cxt_filter; + } + case XML_Names: + { + m_cxt_names.reset(); + return &m_cxt_names; + } + case XML_Styles: + { + m_cxt_styles.reset(m_sheet); + return &m_cxt_styles; + } + } + } + + return nullptr; +} + +void gnumeric_sheet_context::end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) +{ + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Names: + { + assert(child == &m_cxt_names); + end_names(); + break; + } + case XML_Styles: + { + assert(child == &m_cxt_styles); + end_styles(); + break; + } + } + } +} + +void gnumeric_sheet_context::start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) +{ + push_stack(ns, name); + + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Font: + start_font(attrs); + break; + case XML_Merge: + m_merge_area = std::string_view{}; + break; + case XML_Name: + start_name(attrs); + break; + case XML_Style: + start_style(attrs); + break; + case XML_StyleRegion: + start_style_region(attrs); + break; + case XML_ColInfo: + start_col(attrs); + break; + case XML_RowInfo: + start_row(attrs); + break; + case XML_Condition: + { + if (!m_region_data->contains_conditional_format) + { + m_region_data->contains_conditional_format = true; + end_style(false); + } + start_condition(attrs); + break; + } + case XML_Expression0: + case XML_Expression1: + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool gnumeric_sheet_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_gnumeric_gnm) + { + switch(name) + { + case XML_Font: + end_font(); + break; + case XML_Merge: + end_merge(); + break; + case XML_Name: + end_name(); + break; + case XML_Style: + { + xml_token_pair_t parent = get_parent_element(); + if (parent.second == XML_Condition) + { + end_style(true); + } + else + { + // The conditional format entry contains a mandatory style element + // Therefore when we have a conditional format the end_style method + // is already called in start_element of the XML_Condition case. + if (!m_region_data->contains_conditional_format) + { + end_style(false); + } + } + break; + } + case XML_StyleRegion: + end_style_region(); + break; + case XML_Condition: + end_condition(); + break; + case XML_Expression0: + case XML_Expression1: + end_expression(); + break; + } + } + + return pop_stack(ns, name); +} + +void gnumeric_sheet_context::characters(std::string_view str, bool transient) +{ + const auto [ns, name] = get_current_element(); + + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Merge: + { + m_merge_area = transient ? intern(str) : str; + break; + } + case XML_Name: + { + m_name = transient ? intern(str) : str; + break; + } + default: + m_chars = transient ? intern(str) : str; + } + } + else + { + m_chars = transient ? intern(str) : str; + } +} + +void gnumeric_sheet_context::reset(ss::sheet_t sheet) +{ + mp_sheet = nullptr; + mp_xf = nullptr; + m_sheet = sheet; + + m_region_data.reset(); + + m_front_color.red = 0; + m_front_color.green = 0; + m_front_color.blue = 0; + + m_chars = std::string_view{}; + m_name = std::string_view{}; + m_merge_area = std::string_view{}; +} + +std::vector<gnumeric_style> gnumeric_sheet_context::pop_styles() +{ + return std::move(m_styles); +} + +void gnumeric_sheet_context::start_font(const xml_token_attrs_t& attrs) +{ + auto* styles = mp_factory->get_styles(); + if (!styles) + return; + + auto* font_style = styles->start_font_style(); + ENSURE_INTERFACE(font_style, import_font_style); + + for (const auto& attr : attrs) + { + switch (attr.name) + { + case XML_Unit: + { + double n = atoi(attr.value.data()); + font_style->set_size(n); + break; + } + case XML_Bold: + { + bool b = atoi(attr.value.data()) != 0; + font_style->set_bold(b); + break; + } + case XML_Italic: + { + bool b = atoi(attr.value.data()) != 0; + font_style->set_italic(b); + break; + } + case XML_Underline: + { + int n = atoi(attr.value.data()); + switch (n) + { + case 0: + font_style->set_underline(ss::underline_t::none); + break; + case 1: + font_style->set_underline(ss::underline_t::single_line); + break; + case 2: + font_style->set_underline(ss::underline_t::double_line); + break; + } + break; + } + } + } +} + +void gnumeric_sheet_context::start_col(const xml_token_attrs_t& attrs) +{ + if (!mp_sheet) + return; + + ss::iface::import_sheet_properties* sheet_props = mp_sheet->get_sheet_properties(); + if (!sheet_props) + return; + + long col = 0; + long col_span = 1; + double col_width = 0.0; + bool col_hidden = false; + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_No: + { + col = to_long(attr.value); + break; + } + case XML_Unit: + { + col_width = to_double(attr.value); + break; + } + case XML_Count: + { + col_span = to_long(attr.value); + break; + } + case XML_Hidden: + { + col_hidden = to_bool(attr.value); + break; + } + } + } + + sheet_props->set_column_width(col, col_span, col_width, length_unit_t::point); + sheet_props->set_column_hidden(col, col_span, col_hidden); +} + +void gnumeric_sheet_context::start_row(const xml_token_attrs_t& attrs) +{ + if (!mp_sheet) + return; + + ss::iface::import_sheet_properties* sheet_props = mp_sheet->get_sheet_properties(); + if (!sheet_props) + return; + + long row = 0; + long row_span = 1; + double row_height = 0.0; + bool row_hidden = false; + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_No: + { + row = to_long(attr.value); + break; + } + case XML_Unit: + { + row_height = to_double(attr.value); + break; + } + case XML_Count: + { + row_span = to_long(attr.value); + break; + } + case XML_Hidden: + { + row_hidden = to_bool(attr.value); + break; + } + } + } + + for (long i = 0; i < row_span; ++i) + { + sheet_props->set_row_height(row + i, row_height, length_unit_t::point); + sheet_props->set_row_hidden(row + i, row_hidden); + } +} + +void gnumeric_sheet_context::start_style(const xml_token_attrs_t& attrs) +{ + auto* styles = mp_factory->get_styles(); + if (!styles) + return; + + auto* fill_style = styles->start_fill_style(); + ENSURE_INTERFACE(fill_style, import_fill_style); + + auto* cell_protection = styles->start_cell_protection(); + ENSURE_INTERFACE(cell_protection, import_cell_protection); + + auto* number_format = styles->start_number_format(); + ENSURE_INTERFACE(number_format, import_number_format); + + mp_xf = styles->start_xf(ss::xf_category_t::cell); + ENSURE_INTERFACE(mp_xf, import_xf); + + bool fill_set = false; + bool protection_set = false; + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_Fore: + { + auto color = parse_gnumeric_rgb(attr.value); + if (!color) + break; + + fill_style->set_fg_color(255, color->red, color->green, color->blue); + fill_set = true; + m_front_color = *color; + break; + } + case XML_Back: + { + auto color = parse_gnumeric_rgb(attr.value); + if (!color) + break; + + fill_style->set_bg_color(255, color->red, color->green, color->blue); + fill_set = true; + break; + } + case XML_Hidden: + { + bool b = atoi(attr.value.data()); + cell_protection->set_hidden(b); + + protection_set = true; + break; + } + case XML_Locked: + { + bool b = atoi(attr.value.data()); + cell_protection->set_locked(b); + + protection_set = true; + break; + } + case XML_Format: + { + if (attr.value != "General") + { + number_format->set_code(attr.value); + std::size_t index = number_format->commit(); + mp_xf->set_number_format(index); + } + break; + } + case XML_HAlign: + { + ss::hor_alignment_t hor_alignment = ss::hor_alignment_t::unknown; + if (attr.value == "GNM_HALIGN_CENTER") + hor_alignment = ss::hor_alignment_t::center; + else if (attr.value == "GNM_HALIGN_RIGHT") + hor_alignment = ss::hor_alignment_t::right; + else if (attr.value == "GNM_HALIGN_LEFT") + hor_alignment = ss::hor_alignment_t::left; + else if (attr.value == "GNM_HALIGN_JUSTIFY") + hor_alignment = ss::hor_alignment_t::justified; + else if (attr.value == "GNM_HALIGN_DISTRIBUTED") + hor_alignment = ss::hor_alignment_t::distributed; + else if (attr.value == "GNM_HALIGN_FILL") + hor_alignment = ss::hor_alignment_t::filled; + + if (hor_alignment != ss::hor_alignment_t::unknown) + mp_xf->set_apply_alignment(true); + mp_xf->set_horizontal_alignment(hor_alignment); + break; + } + case XML_VAlign: + { + ss::ver_alignment_t ver_alignment = ss::ver_alignment_t::unknown; + if (attr.value == "GNM_VALIGN_BOTTOM") + ver_alignment = ss::ver_alignment_t::bottom; + else if (attr.value == "GNM_VALIGN_TOP") + ver_alignment = ss::ver_alignment_t::top; + else if (attr.value == "GNM_VALIGN_CENTER") + ver_alignment = ss::ver_alignment_t::middle; + else if (attr.value == "GNM_VALIGN_JUSTIFY") + ver_alignment = ss::ver_alignment_t::justified; + else if (attr.value == "GNM_VALIGN_DISTRIBUTED") + ver_alignment = ss::ver_alignment_t::distributed; + + if (ver_alignment != ss::ver_alignment_t::unknown) + mp_xf->set_apply_alignment(true); + mp_xf->set_vertical_alignment(ver_alignment); + break; + } + } + } + + if (fill_set) + { + size_t fill_id = fill_style->commit(); + mp_xf->set_fill(fill_id); + } + if (protection_set) + { + size_t protection_id = cell_protection->commit(); + mp_xf->set_protection(protection_id); + } +} + +void gnumeric_sheet_context::start_style_region(const xml_token_attrs_t& attrs) +{ + m_region_data = style_region{}; + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_startCol: + { + size_t n = atoi(attr.value.data()); + m_region_data->start_col = n; + break; + } + case XML_startRow: + { + size_t n = atoi(attr.value.data()); + m_region_data->start_row = n; + break; + } + case XML_endCol: + { + size_t n = atoi(attr.value.data()); + m_region_data->end_col = n; + break; + } + case XML_endRow: + { + size_t n = atoi(attr.value.data()); + m_region_data->end_row = n; + break; + } + default: + ; + } + } +} + +void gnumeric_sheet_context::start_condition(const xml_token_attrs_t& attrs) +{ + if (!mp_sheet) + return; + + ss::iface::import_conditional_format* cond_format = + mp_sheet->get_conditional_format(); + + if (!cond_format) + return; + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_Operator: + { + int val = atoi(attr.value.data()); + ss::condition_operator_t op = get_condition_operator(val); + cond_format->set_operator(op); + break; + } + } + } +} + +void gnumeric_sheet_context::start_name(const xml_token_attrs_t& /*attrs*/) +{ + m_name = std::string_view{}; +} + +void gnumeric_sheet_context::end_font() +{ + ss::iface::import_styles* styles = mp_factory->get_styles(); + if (!styles) + return; + + auto* font_style = styles->start_font_style(); + ENSURE_INTERFACE(font_style, import_font_style); + + font_style->set_color(0, m_front_color.red, m_front_color.green, m_front_color.blue); + font_style->set_name(m_chars); + size_t font_id = font_style->commit(); + + assert(mp_xf); + mp_xf->set_font(font_id); +} + +void gnumeric_sheet_context::end_style(bool conditional_format) +{ + ss::iface::import_styles* styles = mp_factory->get_styles(); + if (!styles) + return; + + assert(mp_xf); + size_t xf_id = mp_xf->commit(); + if (!conditional_format) + { + m_region_data->xf_id = xf_id; + } + else if (mp_sheet) + { + ss::iface::import_conditional_format* cond_format = + mp_sheet->get_conditional_format(); + if (cond_format) + { + cond_format->set_xf_id(xf_id); + } + } +} + +void gnumeric_sheet_context::end_style_region() +{ + if (!mp_sheet) + return; + + mp_sheet->set_format(m_region_data->start_row, m_region_data->start_col, + m_region_data->end_row, m_region_data->end_col, m_region_data->xf_id); + + if (m_region_data->contains_conditional_format) + { + ss::iface::import_conditional_format* cond_format = + mp_sheet->get_conditional_format(); + if (cond_format) + { + cond_format->set_range(m_region_data->start_row, m_region_data->start_col, + m_region_data->end_row, m_region_data->end_col); + cond_format->commit_format(); + } + } + m_region_data.reset(); +} + +void gnumeric_sheet_context::end_condition() +{ + if (!mp_sheet) + return; + + ss::iface::import_conditional_format* cond_format = + mp_sheet->get_conditional_format(); + if (cond_format) + { + cond_format->commit_entry(); + } +} + +void gnumeric_sheet_context::end_expression() +{ + if (!mp_sheet) + return; + + ss::iface::import_conditional_format* cond_format = + mp_sheet->get_conditional_format(); + if (cond_format) + { + cond_format->set_formula(m_chars); + cond_format->commit_condition(); + } +} + +void gnumeric_sheet_context::end_merge() +{ + if (!mp_sheet || m_merge_area.empty()) + return; + + auto* sp = mp_sheet->get_sheet_properties(); + if (!sp) + return; + + auto* resolver = mp_factory->get_reference_resolver(ss::formula_ref_context_t::global); + if (!resolver) + return; + + try + { + ss::range_t range = to_rc_range(resolver->resolve_range(m_merge_area)); + sp->set_merge_cell_range(range); + } + catch (const invalid_arg_error& e) + { + std::ostringstream os; + os << "failed to parse a merged area '" << m_merge_area << "': " << e.what(); + warn(os.str()); + } +} + +void gnumeric_sheet_context::end_name() +{ + if (m_name.empty()) + return; + + mp_sheet = mp_factory->get_sheet(m_name); + m_name = std::string_view{}; +} + +void gnumeric_sheet_context::end_names() +{ + if (!mp_sheet) + return; + + ss::iface::import_named_expression* named_exp = mp_sheet->get_named_expression(); + if (!named_exp) + return; + + for (const auto& name : m_cxt_names.get_names()) + { + try + { + named_exp->set_base_position(name.position); + named_exp->set_named_expression(name.name, name.value); + named_exp->commit(); + } + catch (const std::exception& e) + { + std::ostringstream os; + os << "failed to commit a named expression named '" << name.name + << "': (reason='" << e.what() << "'; value='" << name.value << "')"; + warn(os.str()); + } + } +} + +void gnumeric_sheet_context::end_styles() +{ + m_styles = m_cxt_styles.pop_styles(); +} + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_sheet_context.hpp b/src/liborcus/gnumeric_sheet_context.hpp new file mode 100644 index 0000000..70b8f89 --- /dev/null +++ b/src/liborcus/gnumeric_sheet_context.hpp @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_GNUMERIC_SHEET_CONTEXT_HPP +#define INCLUDED_ORCUS_GNUMERIC_SHEET_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "gnumeric_cell_context.hpp" +#include "gnumeric_filter_context.hpp" +#include "gnumeric_names_context.hpp" +#include "gnumeric_styles_context.hpp" +#include "gnumeric_types.hpp" + +#include <orcus/spreadsheet/types.hpp> + +#include <memory> +#include <optional> + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_factory; +class import_sheet; +class import_auto_filter; +class import_xf; + +}} + +class gnumeric_sheet_context : public xml_context_base +{ + struct style_region + { + spreadsheet::row_t start_row = 0; + spreadsheet::row_t end_row = 0; + spreadsheet::col_t start_col = 0; + spreadsheet::col_t end_col = 0; + + std::size_t xf_id = 0; + bool contains_conditional_format = false; + }; + +public: + gnumeric_sheet_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_factory* factory); + + virtual ~gnumeric_sheet_context() override; + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name) override; + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) override; + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) override; + virtual bool end_element(xmlns_id_t ns, xml_token_t name) override; + virtual void characters(std::string_view str, bool transient) override; + + void reset(spreadsheet::sheet_t sheet); + + std::vector<gnumeric_style> pop_styles(); + +private: + void start_style_region(const xml_token_attrs_t& attrs); + void start_style(const xml_token_attrs_t& attrs); + void start_font(const xml_token_attrs_t& attrs); + void start_col(const xml_token_attrs_t& attrs); + void start_row(const xml_token_attrs_t& attrs); + void start_condition(const xml_token_attrs_t& attrs); + void start_name(const xml_token_attrs_t& attrs); + + void end_style(bool conditional_format); + void end_font(); + void end_style_region(); + void end_condition(); + void end_expression(); + void end_merge(); + void end_name(); + void end_names(); + void end_styles(); + +private: + spreadsheet::iface::import_factory* mp_factory = nullptr; + spreadsheet::iface::import_sheet* mp_sheet = nullptr; + spreadsheet::iface::import_xf* mp_xf = nullptr; + spreadsheet::sheet_t m_sheet = -1; + + std::optional<style_region> m_region_data; + + spreadsheet::color_rgb_t m_front_color; + + /** + * Used for temporary storage of characters + */ + std::string_view m_chars; + std::string_view m_name; + std::string_view m_merge_area; + + gnumeric_cell_context m_cxt_cell; + gnumeric_filter_context m_cxt_filter; + gnumeric_names_context m_cxt_names; + gnumeric_styles_context m_cxt_styles; + + std::vector<gnumeric_style> m_styles; +}; + +} // namespace orcus + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_sheet_context_test.cpp b/src/liborcus/gnumeric_sheet_context_test.cpp new file mode 100644 index 0000000..685357d --- /dev/null +++ b/src/liborcus/gnumeric_sheet_context_test.cpp @@ -0,0 +1,119 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gnumeric_sheet_context.hpp" +#include "gnumeric_tokens.hpp" +#include "gnumeric_namespace_types.hpp" +#include "gnumeric_token_constants.hpp" +#include "mock_spreadsheet.hpp" +#include "session_context.hpp" +#include "orcus/types.hpp" + +#include <iostream> +#include <string> +#include <cstdlib> + +using namespace orcus; +using namespace std; +using namespace orcus::spreadsheet; +using namespace orcus::spreadsheet::mock; + +class mock_sheet_properties : public import_sheet_properties +{ +public: + virtual void set_column_width(col_t col, col_t col_span, double size, length_unit_t unit) + { + assert(col == 2); + assert(col_span == 1); + assert(size == 37.3); + assert(unit == length_unit_t::point); + } + + virtual void set_column_hidden(col_t, col_t, bool) + { + } + + virtual void set_row_height(row_t row, double size, length_unit_t unit) + { + assert(row == 4); + assert(size == 7.3); + assert(unit == length_unit_t::point); + } + + virtual void set_row_hidden(row_t, bool) + { + } +}; + +class mock_sheet : public import_sheet +{ +public: + virtual iface::import_sheet_properties* get_sheet_properties() + { + return &m_mock_properties; + } + + virtual range_size_t get_sheet_size() const + { + range_size_t ret; + ret.rows = ret.columns = 0; + return ret; + } + +private: + mock_sheet_properties m_mock_properties; +}; + +class mock_factory : public import_factory +{ +public: + virtual iface::import_sheet* get_sheet(std::string_view) override + { + return &m_mock_sheet; + } + +private: + mock_sheet m_mock_sheet; +}; + +void test_column_width() +{ + mock_factory factory; + session_context cxt; + + orcus::gnumeric_sheet_context context(cxt, orcus::gnumeric_tokens, &factory); + context.reset(0); + orcus::xmlns_id_t ns = NS_gnumeric_gnm; + orcus::xml_token_t parent = XML_Sheet; + orcus::xml_token_attrs_t parent_attr; + context.start_element(ns, parent, parent_attr); + { + orcus::xml_token_t elem = XML_Name; + orcus::xml_token_attrs_t attrs; + context.start_element(ns, elem, attrs); + context.characters("test", false); + context.end_element(ns, elem); + } + { + orcus::xml_token_t elem = XML_ColInfo; + orcus::xml_token_attrs_t attrs; + attrs.push_back(xml_token_attr_t(ns, XML_No, "2", false)); + attrs.push_back(xml_token_attr_t(ns, XML_Unit, "37.3", false)); + attrs.push_back(xml_token_attr_t(ns, XML_Unit, "37.3", false)); + context.start_element(ns, elem, attrs); + context.end_element(ns, elem); + } + context.end_element(ns, parent); +} + +int main() +{ + test_column_width(); + + return EXIT_SUCCESS; +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_styles_context.cpp b/src/liborcus/gnumeric_styles_context.cpp new file mode 100644 index 0000000..b2c6058 --- /dev/null +++ b/src/liborcus/gnumeric_styles_context.cpp @@ -0,0 +1,342 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gnumeric_styles_context.hpp" +#include "gnumeric_token_constants.hpp" +#include "gnumeric_namespace_types.hpp" + +#include <orcus/measurement.hpp> +#include <mdds/sorted_string_map.hpp> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace { + +namespace hor_align { + +using map_type = mdds::sorted_string_map<ss::hor_alignment_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "GNM_HALIGN_CENTER", ss::hor_alignment_t::center }, + { "GNM_HALIGN_DISTRIBUTED", ss::hor_alignment_t::distributed }, + { "GNM_HALIGN_GENERAL", ss::hor_alignment_t::unknown }, + { "GNM_HALIGN_JUSTIFY", ss::hor_alignment_t::justified }, + { "GNM_HALIGN_LEFT", ss::hor_alignment_t::left }, + { "GNM_HALIGN_RIGHT", ss::hor_alignment_t::right }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::hor_alignment_t::unknown); + return mt; +} + +} // namespace hor_align + +namespace ver_align { + +using map_type = mdds::sorted_string_map<ss::ver_alignment_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "GNM_VALIGN_BOTTOM", ss::ver_alignment_t::bottom }, + { "GNM_VALIGN_CENTER", ss::ver_alignment_t::middle }, + { "GNM_VALIGN_DISTRIBUTED", ss::ver_alignment_t::distributed }, + { "GNM_VALIGN_JUSTIFY", ss::ver_alignment_t::justified }, + { "GNM_VALIGN_TOP", ss::ver_alignment_t::top }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::ver_alignment_t::unknown); + return mt; +} + +} // namespace ver_align + +ss::fill_pattern_t to_fill_pattern(std::size_t v) +{ + constexpr ss::fill_pattern_t patterns[] = { + ss::fill_pattern_t::none, + ss::fill_pattern_t::solid, + // TODO: add more as we establish more mapping rules + }; + + return (v < std::size(patterns)) ? patterns[v] : ss::fill_pattern_t::none; +} + +gnumeric_style::border_type parse_border_attributes(const xml_token_attrs_t& attrs) +{ + gnumeric_style::border_type ret; + + for (const auto& attr : attrs) + { + if (attr.ns == XMLNS_UNKNOWN_ID) + { + switch (attr.name) + { + case XML_Style: + { + const char* p_end = nullptr; + long v = to_long(attr.value, &p_end); + if (attr.value.data() < p_end) + ret.style = static_cast<gnumeric_border_type>(v); + break; + } + case XML_Color: + { + ret.color = parse_gnumeric_rgb(attr.value); + break; + } + } + } + } + + return ret; +} + +} // anonymous namespace + +gnumeric_styles_context::gnumeric_styles_context( + session_context& session_cxt, const tokens& tokens, + ss::iface::import_factory* factory) : + xml_context_base(session_cxt, tokens), + mp_factory(factory) +{ + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_gnumeric_gnm, XML_Styles }, // root element + { NS_gnumeric_gnm, XML_Style, NS_gnumeric_gnm, XML_Font }, + { NS_gnumeric_gnm, XML_Style, NS_gnumeric_gnm, XML_StyleBorder }, + { NS_gnumeric_gnm, XML_StyleBorder, NS_gnumeric_gnm, XML_Bottom }, + { NS_gnumeric_gnm, XML_StyleBorder, NS_gnumeric_gnm, XML_Diagonal }, + { NS_gnumeric_gnm, XML_StyleBorder, NS_gnumeric_gnm, XML_Left }, + { NS_gnumeric_gnm, XML_StyleBorder, NS_gnumeric_gnm, XML_Rev_Diagonal }, + { NS_gnumeric_gnm, XML_StyleBorder, NS_gnumeric_gnm, XML_Right }, + { NS_gnumeric_gnm, XML_StyleBorder, NS_gnumeric_gnm, XML_Top }, + { NS_gnumeric_gnm, XML_StyleRegion, NS_gnumeric_gnm, XML_Style }, + { NS_gnumeric_gnm, XML_Styles, NS_gnumeric_gnm, XML_StyleRegion }, + }; + + init_element_validator(rules, std::size(rules)); +} + +gnumeric_styles_context::~gnumeric_styles_context() = default; + +void gnumeric_styles_context::start_element( + xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) +{ + push_stack(ns, name); + + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_StyleRegion: + start_style_region(attrs); + break; + case XML_StyleBorder: + break; + case XML_Style: + start_style(attrs); + break; + case XML_Top: + { + m_current_style.border_top = parse_border_attributes(attrs); + break; + } + case XML_Bottom: + { + m_current_style.border_bottom = parse_border_attributes(attrs); + break; + } + case XML_Left: + { + m_current_style.border_left = parse_border_attributes(attrs); + break; + } + case XML_Right: + { + m_current_style.border_right = parse_border_attributes(attrs); + break; + } + case XML_Diagonal: + { + m_current_style.border_bl_tr = parse_border_attributes(attrs); + break; + } + case XML_Rev_Diagonal: + { + m_current_style.border_br_tl = parse_border_attributes(attrs); + break; + } + case XML_Font: + start_font(attrs); + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool gnumeric_styles_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_StyleRegion: + end_style_region(); + break; + } + } + return pop_stack(ns, name); +} + +void gnumeric_styles_context::characters(std::string_view str, bool transient) +{ + const auto [ns, name] = get_current_element(); + + if (ns == NS_gnumeric_gnm) + { + switch (name) + { + case XML_Font: + { + if (transient) + str = intern(str); + m_current_style.font_name = str; + break; + } + } + } +} + +void gnumeric_styles_context::reset(ss::sheet_t sheet) +{ + m_sheet = sheet; + m_styles.clear(); + m_current_style = gnumeric_style{}; +} + +std::vector<gnumeric_style> gnumeric_styles_context::pop_styles() +{ + return std::move(m_styles); +} + +void gnumeric_styles_context::start_style_region(const std::vector<xml_token_attr_t>& attrs) +{ + m_current_style = gnumeric_style{}; + m_current_style.sheet = m_sheet; + + for (const auto& attr : attrs) + { + switch (attr.name) + { + case XML_startCol: + m_current_style.region.first.column = to_long(attr.value); + break; + case XML_startRow: + m_current_style.region.first.row = to_long(attr.value); + break; + case XML_endCol: + m_current_style.region.last.column = to_long(attr.value); + break; + case XML_endRow: + m_current_style.region.last.row = to_long(attr.value); + break; + } + } +} + +void gnumeric_styles_context::start_style(const std::vector<xml_token_attr_t>& attrs) +{ + for (const auto& attr : attrs) + { + switch (attr.name) + { + case XML_HAlign: + m_current_style.hor_align = hor_align::get().find(attr.value); + break; + case XML_VAlign: + m_current_style.ver_align = ver_align::get().find(attr.value); + break; + case XML_WrapText: + m_current_style.wrap_text = to_bool(attr.value); + break; + case XML_Fore: + m_current_style.fore = parse_gnumeric_rgb(attr.value); + break; + case XML_Back: + m_current_style.back = parse_gnumeric_rgb(attr.value); + break; + case XML_PatternColor: + m_current_style.pattern_color = parse_gnumeric_rgb(attr.value); + break; + case XML_Shade: + m_current_style.pattern = to_fill_pattern(to_long(attr.value)); + break; + case XML_Format: + { + auto v = attr.transient ? intern(attr.value) : attr.value; + m_current_style.number_format = v; + break; + } + } + } +} + +void gnumeric_styles_context::start_font(const std::vector<xml_token_attr_t>& attrs) +{ + for (const auto& attr : attrs) + { + switch (attr.name) + { + case XML_Unit: + { + const char* p_end = nullptr; + double v = to_double(attr.value, &p_end); + if (attr.value.data() < p_end) + m_current_style.font_unit = v; + break; + } + case XML_Bold: + m_current_style.bold = to_bool(attr.value); + break; + case XML_Italic: + m_current_style.italic = to_bool(attr.value); + break; + case XML_Underline: + m_current_style.underline = to_bool(attr.value); + break; + case XML_StrikeThrough: + m_current_style.strikethrough = to_bool(attr.value); + break; + case XML_Script: + { + auto v = to_long(attr.value); + m_current_style.script = static_cast<gnumeric_script_type>(v); + break; + } + } + } +} + +void gnumeric_styles_context::end_style_region() +{ + if (m_current_style.valid()) + m_styles.push_back(m_current_style); +} + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_styles_context.hpp b/src/liborcus/gnumeric_styles_context.hpp new file mode 100644 index 0000000..1675b48 --- /dev/null +++ b/src/liborcus/gnumeric_styles_context.hpp @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "xml_context_base.hpp" +#include "gnumeric_types.hpp" + +#include <orcus/spreadsheet/types.hpp> + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_factory; + +}} + +class gnumeric_styles_context : public xml_context_base +{ +public: + gnumeric_styles_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_factory* factory); + virtual ~gnumeric_styles_context() override; + + virtual void start_element( + xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) override; + + virtual bool end_element(xmlns_id_t ns, xml_token_t name) override; + + virtual void characters(std::string_view str, bool transient) override; + + void reset(spreadsheet::sheet_t sheet); + + std::vector<gnumeric_style> pop_styles(); + +private: + void start_style_region(const std::vector<xml_token_attr_t>& attrs); + void start_style(const std::vector<xml_token_attr_t>& attrs); + void start_font(const std::vector<xml_token_attr_t>& attrs); + + void end_style_region(); + +private: + spreadsheet::iface::import_factory* mp_factory = nullptr; + spreadsheet::sheet_t m_sheet = -1; + + std::vector<gnumeric_style> m_styles; + gnumeric_style m_current_style; +}; + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_token_constants.hpp b/src/liborcus/gnumeric_token_constants.hpp new file mode 100644 index 0000000..7e94fb5 --- /dev/null +++ b/src/liborcus/gnumeric_token_constants.hpp @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef __ORCUS_GNUMERIC_TOKEN_CONSTANTS_HPP__ +#define __ORCUS_GNUMERIC_TOKEN_CONSTANTS_HPP__ + +#include "orcus/types.hpp" + +namespace orcus { + +#include "gnumeric_token_constants.inl" + +} + + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_token_constants.inl b/src/liborcus/gnumeric_token_constants.inl new file mode 100644 index 0000000..4043f22 --- /dev/null +++ b/src/liborcus/gnumeric_token_constants.inl @@ -0,0 +1,258 @@ +// This file has been auto-generated. Do not hand-edit this. + +const xml_token_t XML_AllowBlank = 1; +const xml_token_t XML_AnswerR = 2; +const xml_token_t XML_Area = 3; +const xml_token_t XML_ArrowShapeA = 4; +const xml_token_t XML_ArrowShapeB = 5; +const xml_token_t XML_ArrowShapeC = 6; +const xml_token_t XML_Attribute = 7; +const xml_token_t XML_Attributes = 8; +const xml_token_t XML_Author = 9; +const xml_token_t XML_AutoScale = 10; +const xml_token_t XML_Back = 11; +const xml_token_t XML_Bold = 12; +const xml_token_t XML_Bottom = 13; +const xml_token_t XML_Calculation = 14; +const xml_token_t XML_Cell = 15; +const xml_token_t XML_CellComment = 16; +const xml_token_t XML_Cells = 17; +const xml_token_t XML_CellsStr = 18; +const xml_token_t XML_Col = 19; +const xml_token_t XML_ColInfo = 20; +const xml_token_t XML_Collapsed = 21; +const xml_token_t XML_Color = 22; +const xml_token_t XML_Cols = 23; +const xml_token_t XML_Comment = 24; +const xml_token_t XML_Condition = 25; +const xml_token_t XML_Constr = 26; +const xml_token_t XML_Content = 27; +const xml_token_t XML_Count = 28; +const xml_token_t XML_CursorCol = 29; +const xml_token_t XML_CursorRow = 30; +const xml_token_t XML_DateConvention = 31; +const xml_token_t XML_DefaultSizePts = 32; +const xml_token_t XML_Diagonal = 33; +const xml_token_t XML_Direction = 34; +const xml_token_t XML_Discr = 35; +const xml_token_t XML_DisplayFormulas = 36; +const xml_token_t XML_DisplayOutlines = 37; +const xml_token_t XML_EnableIteration = 38; +const xml_token_t XML_Epoch = 39; +const xml_token_t XML_ExprConvention = 40; +const xml_token_t XML_ExprID = 41; +const xml_token_t XML_Expression0 = 42; +const xml_token_t XML_Expression1 = 43; +const xml_token_t XML_Field = 44; +const xml_token_t XML_FillColor = 45; +const xml_token_t XML_Filter = 46; +const xml_token_t XML_Filters = 47; +const xml_token_t XML_FloatDigits = 48; +const xml_token_t XML_FloatRadix = 49; +const xml_token_t XML_Font = 50; +const xml_token_t XML_Footer = 51; +const xml_token_t XML_Fore = 52; +const xml_token_t XML_Format = 53; +const xml_token_t XML_FreezePanes = 54; +const xml_token_t XML_FrozenTopLeft = 55; +const xml_token_t XML_Full = 56; +const xml_token_t XML_Geometry = 57; +const xml_token_t XML_GogObject = 58; +const xml_token_t XML_GridColor = 59; +const xml_token_t XML_HAlign = 60; +const xml_token_t XML_HardSize = 61; +const xml_token_t XML_Header = 62; +const xml_token_t XML_Height = 63; +const xml_token_t XML_Hidden = 64; +const xml_token_t XML_HideColHeader = 65; +const xml_token_t XML_HideGrid = 66; +const xml_token_t XML_HideRowHeader = 67; +const xml_token_t XML_HideZero = 68; +const xml_token_t XML_HyperLink = 69; +const xml_token_t XML_Inc = 70; +const xml_token_t XML_Indent = 71; +const xml_token_t XML_Index = 72; +const xml_token_t XML_Input = 73; +const xml_token_t XML_InputMessage = 74; +const xml_token_t XML_Inputs = 75; +const xml_token_t XML_Italic = 76; +const xml_token_t XML_IterationTolerance = 77; +const xml_token_t XML_Label = 78; +const xml_token_t XML_LabelFormat = 79; +const xml_token_t XML_Lcol = 80; +const xml_token_t XML_Left = 81; +const xml_token_t XML_LimitsR = 82; +const xml_token_t XML_Locked = 83; +const xml_token_t XML_Lrow = 84; +const xml_token_t XML_Major = 85; +const xml_token_t XML_ManualRecalc = 86; +const xml_token_t XML_MarginA = 87; +const xml_token_t XML_MarginB = 88; +const xml_token_t XML_Margins = 89; +const xml_token_t XML_Max = 90; +const xml_token_t XML_MaxCol = 91; +const xml_token_t XML_MaxIter = 92; +const xml_token_t XML_MaxIterations = 93; +const xml_token_t XML_MaxRow = 94; +const xml_token_t XML_MaxTime = 95; +const xml_token_t XML_Merge = 96; +const xml_token_t XML_MergedRegions = 97; +const xml_token_t XML_Message = 98; +const xml_token_t XML_Middle = 99; +const xml_token_t XML_Min = 100; +const xml_token_t XML_Minor = 101; +const xml_token_t XML_ModelType = 102; +const xml_token_t XML_Name = 103; +const xml_token_t XML_Names = 104; +const xml_token_t XML_No = 105; +const xml_token_t XML_NonNeg = 106; +const xml_token_t XML_ObjectAnchorType = 107; +const xml_token_t XML_ObjectBound = 108; +const xml_token_t XML_ObjectOffset = 109; +const xml_token_t XML_Objects = 110; +const xml_token_t XML_Op0 = 111; +const xml_token_t XML_Op1 = 112; +const xml_token_t XML_Operator = 113; +const xml_token_t XML_Orient = 114; +const xml_token_t XML_OutlineColor = 115; +const xml_token_t XML_OutlineLevel = 116; +const xml_token_t XML_OutlineSymbolsBelow = 117; +const xml_token_t XML_OutlineSymbolsRight = 118; +const xml_token_t XML_Output = 119; +const xml_token_t XML_Page = 120; +const xml_token_t XML_PatternColor = 121; +const xml_token_t XML_PerformR = 122; +const xml_token_t XML_Points = 123; +const xml_token_t XML_PrefUnit = 124; +const xml_token_t XML_Print = 125; +const xml_token_t XML_PrintInformation = 126; +const xml_token_t XML_ProblemType = 127; +const xml_token_t XML_ProgramR = 128; +const xml_token_t XML_Protected = 129; +const xml_token_t XML_RTL_Layout = 130; +const xml_token_t XML_Rcol = 131; +const xml_token_t XML_Rev_Diagonal = 132; +const xml_token_t XML_Right = 133; +const xml_token_t XML_Rotation = 134; +const xml_token_t XML_Row = 135; +const xml_token_t XML_RowInfo = 136; +const xml_token_t XML_Rows = 137; +const xml_token_t XML_Rrow = 138; +const xml_token_t XML_Scale = 139; +const xml_token_t XML_Scenario = 140; +const xml_token_t XML_Scenarios = 141; +const xml_token_t XML_Script = 142; +const xml_token_t XML_SelectedTab = 143; +const xml_token_t XML_Selection = 144; +const xml_token_t XML_Selections = 145; +const xml_token_t XML_SensitivityR = 146; +const xml_token_t XML_Shade = 147; +const xml_token_t XML_Sheet = 148; +const xml_token_t XML_SheetLayout = 149; +const xml_token_t XML_SheetName = 150; +const xml_token_t XML_SheetNameIndex = 151; +const xml_token_t XML_SheetObjectBonobo = 152; +const xml_token_t XML_SheetObjectFilled = 153; +const xml_token_t XML_SheetObjectGraph = 154; +const xml_token_t XML_SheetObjectImage = 155; +const xml_token_t XML_SheetWidgetButton = 156; +const xml_token_t XML_SheetWidgetCheckbox = 157; +const xml_token_t XML_SheetWidgetCombo = 158; +const xml_token_t XML_SheetWidgetFrame = 159; +const xml_token_t XML_SheetWidgetLabel = 160; +const xml_token_t XML_SheetWidgetList = 161; +const xml_token_t XML_SheetWidgetScrollbar = 162; +const xml_token_t XML_SheetWidgetSlider = 163; +const xml_token_t XML_SheetWidgetSpinbutton = 164; +const xml_token_t XML_SheetWidgetToggleButton = 165; +const xml_token_t XML_Sheets = 166; +const xml_token_t XML_ShowIter = 167; +const xml_token_t XML_ShrinkToFit = 168; +const xml_token_t XML_Solver = 169; +const xml_token_t XML_StrikeThrough = 170; +const xml_token_t XML_Style = 171; +const xml_token_t XML_StyleBorder = 172; +const xml_token_t XML_StyleRegion = 173; +const xml_token_t XML_Styles = 174; +const xml_token_t XML_TabColor = 175; +const xml_token_t XML_TabTextColor = 176; +const xml_token_t XML_TargetCol = 177; +const xml_token_t XML_TargetRow = 178; +const xml_token_t XML_Text = 179; +const xml_token_t XML_TextFormat = 180; +const xml_token_t XML_Title = 181; +const xml_token_t XML_Top = 182; +const xml_token_t XML_TopLeft = 183; +const xml_token_t XML_Type = 184; +const xml_token_t XML_UIData = 185; +const xml_token_t XML_Underline = 186; +const xml_token_t XML_UnfrozenTopLeft = 187; +const xml_token_t XML_Unit = 188; +const xml_token_t XML_UseDropdown = 189; +const xml_token_t XML_VAlign = 190; +const xml_token_t XML_Validation = 191; +const xml_token_t XML_Value = 192; +const xml_token_t XML_Value0 = 193; +const xml_token_t XML_Value1 = 194; +const xml_token_t XML_ValueFormat = 195; +const xml_token_t XML_ValueType = 196; +const xml_token_t XML_ValueType0 = 197; +const xml_token_t XML_ValueType1 = 198; +const xml_token_t XML_Version = 199; +const xml_token_t XML_Visibility = 200; +const xml_token_t XML_Width = 201; +const xml_token_t XML_Workbook = 202; +const xml_token_t XML_WrapText = 203; +const xml_token_t XML_Zoom = 204; +const xml_token_t XML_bottom = 205; +const xml_token_t XML_break = 206; +const xml_token_t XML_cols = 207; +const xml_token_t XML_count = 208; +const xml_token_t XML_crop_bottom = 209; +const xml_token_t XML_crop_left = 210; +const xml_token_t XML_crop_right = 211; +const xml_token_t XML_crop_top = 212; +const xml_token_t XML_data = 213; +const xml_token_t XML_dimension = 214; +const xml_token_t XML_do_not_print = 215; +const xml_token_t XML_draft = 216; +const xml_token_t XML_endCol = 217; +const xml_token_t XML_endRow = 218; +const xml_token_t XML_even_if_only_styles = 219; +const xml_token_t XML_footer = 220; +const xml_token_t XML_grid = 221; +const xml_token_t XML_hPageBreaks = 222; +const xml_token_t XML_hcenter = 223; +const xml_token_t XML_header = 224; +const xml_token_t XML_id = 225; +const xml_token_t XML_image_type = 226; +const xml_token_t XML_items = 227; +const xml_token_t XML_left = 228; +const xml_token_t XML_monochrome = 229; +const xml_token_t XML_name = 230; +const xml_token_t XML_order = 231; +const xml_token_t XML_orientation = 232; +const xml_token_t XML_paper = 233; +const xml_token_t XML_percentage = 234; +const xml_token_t XML_pos = 235; +const xml_token_t XML_position = 236; +const xml_token_t XML_print_to_uri = 237; +const xml_token_t XML_print_range = 238; +const xml_token_t XML_property = 239; +const xml_token_t XML_repeat_left = 240; +const xml_token_t XML_repeat_top = 241; +const xml_token_t XML_right = 242; +const xml_token_t XML_role = 243; +const xml_token_t XML_rows = 244; +const xml_token_t XML_size_bytes = 245; +const xml_token_t XML_startCol = 246; +const xml_token_t XML_startRow = 247; +const xml_token_t XML_target = 248; +const xml_token_t XML_tip = 249; +const xml_token_t XML_titles = 250; +const xml_token_t XML_top = 251; +const xml_token_t XML_type = 252; +const xml_token_t XML_vPageBreaks = 253; +const xml_token_t XML_value = 254; +const xml_token_t XML_vcenter = 255; + diff --git a/src/liborcus/gnumeric_tokens.cpp b/src/liborcus/gnumeric_tokens.cpp new file mode 100644 index 0000000..99eaa1d --- /dev/null +++ b/src/liborcus/gnumeric_tokens.cpp @@ -0,0 +1,20 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gnumeric_tokens.hpp" + +namespace orcus { + +namespace { + +#include "gnumeric_tokens.inl" + +} + +tokens gnumeric_tokens = tokens(token_names, token_name_count); + +}/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_tokens.hpp b/src/liborcus/gnumeric_tokens.hpp new file mode 100644 index 0000000..2ce6016 --- /dev/null +++ b/src/liborcus/gnumeric_tokens.hpp @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef __ORCUS_GNUMERIC_TOKENS_HPP__ +#define __ORCUS_GNUMERIC_TOKENS_HPP__ + +#include "orcus/tokens.hpp" + +namespace orcus { + +/** + * Singleton instance containing all GNUMERIC tokens. + */ +extern tokens gnumeric_tokens; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_tokens.inl b/src/liborcus/gnumeric_tokens.inl new file mode 100644 index 0000000..297065b --- /dev/null +++ b/src/liborcus/gnumeric_tokens.inl @@ -0,0 +1,263 @@ +// This file has been auto-generated. Do not hand-edit this. + +const char* token_names[] = { + "??", // 0 + "AllowBlank", // 1 + "AnswerR", // 2 + "Area", // 3 + "ArrowShapeA", // 4 + "ArrowShapeB", // 5 + "ArrowShapeC", // 6 + "Attribute", // 7 + "Attributes", // 8 + "Author", // 9 + "AutoScale", // 10 + "Back", // 11 + "Bold", // 12 + "Bottom", // 13 + "Calculation", // 14 + "Cell", // 15 + "CellComment", // 16 + "Cells", // 17 + "CellsStr", // 18 + "Col", // 19 + "ColInfo", // 20 + "Collapsed", // 21 + "Color", // 22 + "Cols", // 23 + "Comment", // 24 + "Condition", // 25 + "Constr", // 26 + "Content", // 27 + "Count", // 28 + "CursorCol", // 29 + "CursorRow", // 30 + "DateConvention", // 31 + "DefaultSizePts", // 32 + "Diagonal", // 33 + "Direction", // 34 + "Discr", // 35 + "DisplayFormulas", // 36 + "DisplayOutlines", // 37 + "EnableIteration", // 38 + "Epoch", // 39 + "ExprConvention", // 40 + "ExprID", // 41 + "Expression0", // 42 + "Expression1", // 43 + "Field", // 44 + "FillColor", // 45 + "Filter", // 46 + "Filters", // 47 + "FloatDigits", // 48 + "FloatRadix", // 49 + "Font", // 50 + "Footer", // 51 + "Fore", // 52 + "Format", // 53 + "FreezePanes", // 54 + "FrozenTopLeft", // 55 + "Full", // 56 + "Geometry", // 57 + "GogObject", // 58 + "GridColor", // 59 + "HAlign", // 60 + "HardSize", // 61 + "Header", // 62 + "Height", // 63 + "Hidden", // 64 + "HideColHeader", // 65 + "HideGrid", // 66 + "HideRowHeader", // 67 + "HideZero", // 68 + "HyperLink", // 69 + "Inc", // 70 + "Indent", // 71 + "Index", // 72 + "Input", // 73 + "InputMessage", // 74 + "Inputs", // 75 + "Italic", // 76 + "IterationTolerance", // 77 + "Label", // 78 + "LabelFormat", // 79 + "Lcol", // 80 + "Left", // 81 + "LimitsR", // 82 + "Locked", // 83 + "Lrow", // 84 + "Major", // 85 + "ManualRecalc", // 86 + "MarginA", // 87 + "MarginB", // 88 + "Margins", // 89 + "Max", // 90 + "MaxCol", // 91 + "MaxIter", // 92 + "MaxIterations", // 93 + "MaxRow", // 94 + "MaxTime", // 95 + "Merge", // 96 + "MergedRegions", // 97 + "Message", // 98 + "Middle", // 99 + "Min", // 100 + "Minor", // 101 + "ModelType", // 102 + "Name", // 103 + "Names", // 104 + "No", // 105 + "NonNeg", // 106 + "ObjectAnchorType", // 107 + "ObjectBound", // 108 + "ObjectOffset", // 109 + "Objects", // 110 + "Op0", // 111 + "Op1", // 112 + "Operator", // 113 + "Orient", // 114 + "OutlineColor", // 115 + "OutlineLevel", // 116 + "OutlineSymbolsBelow", // 117 + "OutlineSymbolsRight", // 118 + "Output", // 119 + "Page", // 120 + "PatternColor", // 121 + "PerformR", // 122 + "Points", // 123 + "PrefUnit", // 124 + "Print", // 125 + "PrintInformation", // 126 + "ProblemType", // 127 + "ProgramR", // 128 + "Protected", // 129 + "RTL_Layout", // 130 + "Rcol", // 131 + "Rev-Diagonal", // 132 + "Right", // 133 + "Rotation", // 134 + "Row", // 135 + "RowInfo", // 136 + "Rows", // 137 + "Rrow", // 138 + "Scale", // 139 + "Scenario", // 140 + "Scenarios", // 141 + "Script", // 142 + "SelectedTab", // 143 + "Selection", // 144 + "Selections", // 145 + "SensitivityR", // 146 + "Shade", // 147 + "Sheet", // 148 + "SheetLayout", // 149 + "SheetName", // 150 + "SheetNameIndex", // 151 + "SheetObjectBonobo", // 152 + "SheetObjectFilled", // 153 + "SheetObjectGraph", // 154 + "SheetObjectImage", // 155 + "SheetWidgetButton", // 156 + "SheetWidgetCheckbox", // 157 + "SheetWidgetCombo", // 158 + "SheetWidgetFrame", // 159 + "SheetWidgetLabel", // 160 + "SheetWidgetList", // 161 + "SheetWidgetScrollbar", // 162 + "SheetWidgetSlider", // 163 + "SheetWidgetSpinbutton", // 164 + "SheetWidgetToggleButton", // 165 + "Sheets", // 166 + "ShowIter", // 167 + "ShrinkToFit", // 168 + "Solver", // 169 + "StrikeThrough", // 170 + "Style", // 171 + "StyleBorder", // 172 + "StyleRegion", // 173 + "Styles", // 174 + "TabColor", // 175 + "TabTextColor", // 176 + "TargetCol", // 177 + "TargetRow", // 178 + "Text", // 179 + "TextFormat", // 180 + "Title", // 181 + "Top", // 182 + "TopLeft", // 183 + "Type", // 184 + "UIData", // 185 + "Underline", // 186 + "UnfrozenTopLeft", // 187 + "Unit", // 188 + "UseDropdown", // 189 + "VAlign", // 190 + "Validation", // 191 + "Value", // 192 + "Value0", // 193 + "Value1", // 194 + "ValueFormat", // 195 + "ValueType", // 196 + "ValueType0", // 197 + "ValueType1", // 198 + "Version", // 199 + "Visibility", // 200 + "Width", // 201 + "Workbook", // 202 + "WrapText", // 203 + "Zoom", // 204 + "bottom", // 205 + "break", // 206 + "cols", // 207 + "count", // 208 + "crop-bottom", // 209 + "crop-left", // 210 + "crop-right", // 211 + "crop-top", // 212 + "data", // 213 + "dimension", // 214 + "do_not_print", // 215 + "draft", // 216 + "endCol", // 217 + "endRow", // 218 + "even_if_only_styles", // 219 + "footer", // 220 + "grid", // 221 + "hPageBreaks", // 222 + "hcenter", // 223 + "header", // 224 + "id", // 225 + "image-type", // 226 + "items", // 227 + "left", // 228 + "monochrome", // 229 + "name", // 230 + "order", // 231 + "orientation", // 232 + "paper", // 233 + "percentage", // 234 + "pos", // 235 + "position", // 236 + "print-to-uri", // 237 + "print_range", // 238 + "property", // 239 + "repeat_left", // 240 + "repeat_top", // 241 + "right", // 242 + "role", // 243 + "rows", // 244 + "size-bytes", // 245 + "startCol", // 246 + "startRow", // 247 + "target", // 248 + "tip", // 249 + "titles", // 250 + "top", // 251 + "type", // 252 + "vPageBreaks", // 253 + "value", // 254 + "vcenter" // 255 +}; + +size_t token_name_count = 256; + diff --git a/src/liborcus/gnumeric_types.cpp b/src/liborcus/gnumeric_types.cpp new file mode 100644 index 0000000..c02627a --- /dev/null +++ b/src/liborcus/gnumeric_types.cpp @@ -0,0 +1,174 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gnumeric_types.hpp" +#include "number_utils.hpp" + +#include <mdds/sorted_string_map.hpp> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace value_format_type { + +using map_type = mdds::sorted_string_map<gnumeric_value_format_type, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "bold", gnumeric_value_format_type::bold }, + { "color", gnumeric_value_format_type::color }, + { "family", gnumeric_value_format_type::family }, + { "italic", gnumeric_value_format_type::italic }, + { "size", gnumeric_value_format_type::size }, + { "strikethrough", gnumeric_value_format_type::strikethrough }, + { "subscript", gnumeric_value_format_type::subscript }, + { "superscript", gnumeric_value_format_type::superscript }, + { "underline", gnumeric_value_format_type::underline }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), gnumeric_value_format_type::unknown); + return mt; +} + +} // namespace value_format_type + +ss::border_style_t to_standard_type(gnumeric_border_type v) +{ + switch (v) + { + case gnumeric_border_type::border_none: + return ss::border_style_t::none; + case gnumeric_border_type::border_thin: + return ss::border_style_t::thin; + case gnumeric_border_type::border_medium: + return ss::border_style_t::medium; + case gnumeric_border_type::border_dashed: + return ss::border_style_t::dashed; + case gnumeric_border_type::border_dotted: + return ss::border_style_t::dotted; + case gnumeric_border_type::border_thick: + return ss::border_style_t::thick; + case gnumeric_border_type::border_double: + return ss::border_style_t::double_border; + case gnumeric_border_type::border_hair: + return ss::border_style_t::hair; + case gnumeric_border_type::border_medium_dash: + return ss::border_style_t::medium_dashed; + case gnumeric_border_type::border_dash_dot: + return ss::border_style_t::dash_dot; + case gnumeric_border_type::border_medium_dash_dot: + return ss::border_style_t::medium_dash_dot; + case gnumeric_border_type::border_dash_dot_dot: + return ss::border_style_t::dash_dot_dot; + case gnumeric_border_type::border_medium_dash_dot_dot: + return ss::border_style_t::medium_dash_dot_dot; + case gnumeric_border_type::border_slanted_dash_dot: + return ss::border_style_t::slant_dash_dot; + } + + return ss::border_style_t::unknown; +} + +gnumeric_value_format_type to_gnumeric_value_format_type(std::string_view s) +{ + return value_format_type::get().find(s); +} + +void gnumeric_named_exp::reset() +{ + name = std::string_view{}; + value = std::string_view{}; + position = {0, 0, 0}; +} + +bool gnumeric_style::valid() const +{ + if (sheet < 0) + return false; + + if (region.first.column < 0 || region.first.row < 0 || region.last.column < 0 || region.last.row < 0) + return false; + + return true; +} + +std::optional<spreadsheet::color_rgb_t> parse_gnumeric_rgb(std::string_view v) +{ + ss::color_rgb_t color; + + auto pos = v.find(':'); + if (pos == v.npos) + return {}; + + std::string_view seg = v.substr(0, pos); + + std::optional<std::uint16_t> elem = hex_to_uint16(seg); + if (!elem) + return {}; + + color.red = *elem >> 8; // 16-bit to 8-bit + v = v.substr(pos + 1); + pos = v.find(':'); + if (pos == v.npos) + return {}; + + seg = v.substr(0, pos); + elem = hex_to_uint16(seg); + if (!elem) + return {}; + + color.green = *elem >> 8; + v = v.substr(pos + 1); + elem = hex_to_uint16(v); + if (!elem) + return {}; + + color.blue = *elem >> 8; + return color; +} + +std::optional<spreadsheet::color_rgb_t> parse_gnumeric_rgb_8x(std::string_view v) +{ + ss::color_rgb_t color; + + auto pos = v.find('x'); + if (pos == v.npos) + return {}; + + std::string_view seg = v.substr(0, pos); + + std::optional<std::uint16_t> elem = hex_to_uint8(seg); + if (!elem) + return {}; + + color.red = *elem; + v = v.substr(pos + 1); + pos = v.find('x'); + if (pos == v.npos) + return {}; + + seg = v.substr(0, pos); + elem = hex_to_uint8(seg); + if (!elem) + return {}; + + color.green = *elem; + v = v.substr(pos + 1); + elem = hex_to_uint8(v); + if (!elem) + return {}; + + color.blue = *elem; + return color; +} + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_types.hpp b/src/liborcus/gnumeric_types.hpp new file mode 100644 index 0000000..1d8b928 --- /dev/null +++ b/src/liborcus/gnumeric_types.hpp @@ -0,0 +1,149 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <orcus/spreadsheet/types.hpp> + +#include <string_view> +#include <optional> + +namespace orcus { + +/** + * Values are as specified in the Gnumeric source code. + */ +enum gnumeric_value_type +{ + vt_empty = 10, + vt_boolean = 20, + vt_float = 40, + vt_error = 50, + vt_string = 60, + vt_cellrange = 70, + vt_array = 80 +}; + +/** + * Values are as specified in the Gnumeric source code (see + * GnmStyleBorderType). + */ +enum class gnumeric_border_type +{ + border_none = 0x0, + border_thin = 0x1, + border_medium = 0x2, + border_dashed = 0x3, + border_dotted = 0x4, + border_thick = 0x5, + border_double = 0x6, + border_hair = 0x7, + border_medium_dash = 0x8, + border_dash_dot = 0x9, + border_medium_dash_dot = 0xA, + border_dash_dot_dot = 0xB, + border_medium_dash_dot_dot = 0xC, + border_slanted_dash_dot = 0xD, +}; + +spreadsheet::border_style_t to_standard_type(gnumeric_border_type v); + +enum class gnumeric_value_format_type +{ + unknown, + bold, + color, + family, + italic, + size, + strikethrough, + subscript, + superscript, + underline, +}; + +gnumeric_value_format_type to_gnumeric_value_format_type(std::string_view s); + +struct gnumeric_value_format_segment +{ + gnumeric_value_format_type type = gnumeric_value_format_type::unknown; + std::string_view value; + std::size_t start = 0; + std::size_t end = 0; +}; + +enum gnumeric_script_type +{ + gnm_script_none = 0, + gnm_script_super = 1, + gnm_script_sub = -1 +}; + +struct gnumeric_named_exp +{ + std::string_view name; + std::string_view value; + spreadsheet::src_address_t position = {0, 0, 0}; + + void reset(); +}; + +struct gnumeric_style +{ + struct border_type + { + std::optional<gnumeric_border_type> style; + std::optional<spreadsheet::color_rgb_t> color; + }; + + spreadsheet::sheet_t sheet = -1; + spreadsheet::range_t region = {{-1, -1}, {-1, -1}}; + spreadsheet::hor_alignment_t hor_align = spreadsheet::hor_alignment_t::unknown; + spreadsheet::ver_alignment_t ver_align = spreadsheet::ver_alignment_t::unknown; + + std::optional<std::string_view> font_name; + std::optional<double> font_unit; + + std::optional<bool> wrap_text; + std::optional<bool> bold; + std::optional<bool> italic; + std::optional<bool> underline; + std::optional<bool> strikethrough; + std::optional<gnumeric_script_type> script; // TODO : not supported yet + + std::optional<spreadsheet::color_rgb_t> fore; + std::optional<spreadsheet::color_rgb_t> back; + std::optional<spreadsheet::color_rgb_t> pattern_color; + spreadsheet::fill_pattern_t pattern = spreadsheet::fill_pattern_t::none; + + std::optional<std::string_view> number_format; + + border_type border_top; + border_type border_bottom; + border_type border_left; + border_type border_right; + border_type border_bl_tr; // bottom-left to top-right (diagonal) + border_type border_br_tl; // top-left to bottom-right (rev-diagonal) + + bool valid() const; +}; + +/** + * Parse an RGB color encoded as 'RRRR:GGGG:BBBB', each element being a 16-bit + * hex value. + */ +std::optional<spreadsheet::color_rgb_t> parse_gnumeric_rgb(std::string_view v); + +/** + * Parse an RGB color encoded as 'RRxGGxBB', each element being an 8-bit hex + * value. + */ +std::optional<spreadsheet::color_rgb_t> parse_gnumeric_rgb_8x(std::string_view v); + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_value_format_parser.cpp b/src/liborcus/gnumeric_value_format_parser.cpp new file mode 100644 index 0000000..014068e --- /dev/null +++ b/src/liborcus/gnumeric_value_format_parser.cpp @@ -0,0 +1,131 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "gnumeric_value_format_parser.hpp" +#include <orcus/exception.hpp> +#include <orcus/measurement.hpp> + +#include <cassert> +#include <sstream> + +#include <boost/numeric/conversion/cast.hpp> + +using boost::numeric_cast; + +namespace orcus { + +std::size_t gnumeric_value_format_parser::get_pos() const +{ + return std::distance(m_head, m_cur); +} + +void gnumeric_value_format_parser::segment() +{ + // segment: [type=value:start:end] + + assert(*m_cur == '['); + const char* p0 = nullptr; + std::size_t pos = 0; + + gnumeric_value_format_segment seg; + + for (++m_cur; m_cur != m_end; ++m_cur) + { + if (!p0) + p0 = m_cur; + + switch (*m_cur) + { + case ']': + { + if (pos != 2) + throw parse_error("value format segment is not formatted properly", get_pos()); + + auto n = std::distance(p0, m_cur); + std::string_view s{p0, numeric_cast<std::size_t>(n)}; + if (s.empty()) + throw parse_error("segment value is empty", get_pos()); + + seg.end = to_long(s); + m_segments.push_back(std::move(seg)); + return; + } + case '=': + { + auto n = std::distance(p0, m_cur); + std::string_view s{p0, numeric_cast<std::size_t>(n)}; + seg.type = to_gnumeric_value_format_type(s); + if (seg.type == gnumeric_value_format_type::unknown) + { + std::ostringstream os; + os << "invalid value format type '" << s << "'"; + throw parse_error(os.str(), get_pos()); + } + + p0 = nullptr; + break; + } + case ':': + { + auto n = std::distance(p0, m_cur); + std::string_view s{p0, numeric_cast<std::size_t>(n)}; + + switch (pos) + { + case 0: + seg.value = s; + break; + case 1: + seg.start = to_long(s); + break; + default: + throw parse_error("too many value partitions", get_pos()); + } + + p0 = nullptr; + ++pos; + break; + } + } + } + + throw parse_error("']' was never reached", get_pos()); +} + +gnumeric_value_format_parser::gnumeric_value_format_parser(std::string_view format) : + m_head(format.data()), m_cur(m_head), m_end(m_head + format.size()) +{ +} + +void gnumeric_value_format_parser::parse() +{ + if (m_cur == m_end) + return; + + // @[segment][segment][segment]... + + if (*m_cur++ != '@') + throw parse_error("first character must be '@'", get_pos()); + + for (; m_cur != m_end; ++m_cur) + { + if (*m_cur != '[') + throw parse_error("'[' was expected", get_pos()); + + segment(); + assert(*m_cur == ']'); + } +} + +std::vector<gnumeric_value_format_segment> gnumeric_value_format_parser::pop_segments() +{ + return std::move(m_segments); +} + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/gnumeric_value_format_parser.hpp b/src/liborcus/gnumeric_value_format_parser.hpp new file mode 100644 index 0000000..83cc6dd --- /dev/null +++ b/src/liborcus/gnumeric_value_format_parser.hpp @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <string_view> +#include <vector> + +#include "gnumeric_types.hpp" + +namespace orcus { + +class gnumeric_value_format_parser +{ + const char* m_head = nullptr; + const char* m_cur = nullptr; + const char* m_end = nullptr; + + std::vector<gnumeric_value_format_segment> m_segments; + +private: + std::size_t get_pos() const; + + void segment(); + +public: + /** + * Constructor. + * + * @param format Format string containing one or more format segments. Make + * sure the source of this string is persisent! + */ + gnumeric_value_format_parser(std::string_view format); + + void parse(); + + std::vector<gnumeric_value_format_segment> pop_segments(); +}; + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/impl_utils.hpp b/src/liborcus/impl_utils.hpp new file mode 100644 index 0000000..9b8cd2e --- /dev/null +++ b/src/liborcus/impl_utils.hpp @@ -0,0 +1,18 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#define ENSURE_INTERFACE(PTR, NAME) \ + do \ + { \ + if (!PTR) \ + throw orcus::interface_error( \ + "implementer must provide a concrete instance of " #NAME "."); \ + } while (false) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/info.cpp b/src/liborcus/info.cpp new file mode 100644 index 0000000..ae571f5 --- /dev/null +++ b/src/liborcus/info.cpp @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/info.hpp" + +#include "constants.inl" + +namespace orcus { + +int get_version_major() +{ + return ORCUS_MAJOR_VERSION; +} + +int get_version_minor() +{ + return ORCUS_MINOR_VERSION; +} + +int get_version_micro() +{ + return ORCUS_MICRO_VERSION; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/interface.cpp b/src/liborcus/interface.cpp new file mode 100644 index 0000000..2b743a2 --- /dev/null +++ b/src/liborcus/interface.cpp @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/interface.hpp" +#include "orcus/config.hpp" + +namespace orcus { namespace iface { + +struct import_filter::impl +{ + orcus::config m_config; + + impl(format_t input) : m_config(input) {} +}; + +import_filter::import_filter(format_t input) : mp_impl(std::make_unique<impl>(input)) {} + +import_filter::~import_filter() = default; + +void import_filter::set_config(const config& v) +{ + mp_impl->m_config = v; +} + +const config& import_filter::get_config() const +{ + return mp_impl->m_config; +} + +document_dumper::~document_dumper() = default; + +}} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/json_document_tree.cpp b/src/liborcus/json_document_tree.cpp new file mode 100644 index 0000000..009aa08 --- /dev/null +++ b/src/liborcus/json_document_tree.cpp @@ -0,0 +1,1777 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/json_document_tree.hpp> +#include <orcus/json_parser.hpp> +#include <orcus/config.hpp> +#include <orcus/stream.hpp> +#include <orcus/string_pool.hpp> + +#include "json_util.hpp" + +#include <string> +#include <vector> +#include <unordered_map> +#include <sstream> +#include <string_view> +#include <limits> +#include <iostream> +#include <deque> + +#include <boost/current_function.hpp> +#include <boost/pool/object_pool.hpp> + +#include "filesystem_env.hpp" + +namespace orcus { namespace json { + +namespace { + +struct json_value_object; +struct json_value_array; + +} + +struct document_resource +{ + string_pool str_pool; + boost::object_pool<json_value> obj_pool; + boost::object_pool<json_value_object> obj_pool_jvo; + boost::object_pool<json_value_array> obj_pool_jva; +}; + +namespace detail { + +enum class node_t : int +{ + // These must have the same values as their public counterparts. + unset = static_cast<int>(json::node_t::unset), + string = static_cast<int>(json::node_t::string), + number = static_cast<int>(json::node_t::number), + object = static_cast<int>(json::node_t::object), + array = static_cast<int>(json::node_t::array), + boolean_true = static_cast<int>(json::node_t::boolean_true), + boolean_false = static_cast<int>(json::node_t::boolean_false), + null = static_cast<int>(json::node_t::null), + + /** + * Value that represents a single key-value pair. This is an internal + * only type, and only to be used in the initializer. + */ + key_value = 10, + + /** + * Implicit array initialized with a {} instead of explicit array(). + */ + array_implicit = 11, +}; + +std::ostream& operator<< (std::ostream& os, node_t nt) +{ + static const char* unknown = "???"; + + static std::vector<const char*> values = + { + "unset", // 0 + "string", // 1 + "number", // 2 + "object", // 3 + "array", // 4 + "boolean_true", // 5 + "boolean_false", // 6 + "null", // 7 + unknown, // 8 + unknown, // 9 + "key_value", // 10 + "array_implicit", // 11 + }; + + size_t nt_value = size_t(nt); + + if (nt_value < values.size()) + os << values[nt_value]; + else + os << unknown; + + return os; +} + +} + +document_error::document_error(const std::string& msg) : + general_error("json::document_error", msg) {} + +document_error::~document_error() = default; + +key_value_error::key_value_error(const std::string& msg) : + document_error(msg) {} + +key_value_error::~key_value_error() = default; + +struct json_value final +{ + detail::node_t type; + json_value* parent; + + union + { + double numeric; + + struct + { + const char* p; + size_t n; + + } str; + + struct + { + const char* key; + size_t n_key; + json_value* value; + + } kvp; // key-value pair + + json_value_object* object; + json_value_array* array; + + } value; + + json_value(const json_value&) = delete; + json_value& operator= (const json_value&) = delete; + + json_value() : type(detail::node_t::unset), parent(nullptr) {} + json_value(detail::node_t _type) : type(_type), parent(nullptr) {} + ~json_value() {} +}; + +namespace { + +const char* tab = " "; +const char quote = '"'; + +const xmlns_id_t NS_orcus_json_xml = "http://schemas.kohei.us/orcus/2015/json"; + +struct json_value_array +{ + std::vector<json_value*> value_array; +}; + +struct json_value_object +{ + using object_type = std::unordered_map<std::string_view, json_value*>; + + std::vector<std::string_view> key_order; + object_type value_object; + + bool has_ref; + + json_value_object() : has_ref(false) {} + + void swap(json_value_object& src) + { + key_order.swap(src.key_order); + value_object.swap(src.value_object); + } +}; + +void dump_repeat(std::ostringstream& os, const char* s, int repeat) +{ + for (int i = 0; i < repeat; ++i) + os << s; +} + +void dump_item( + std::ostringstream& os, const std::string_view* key, const json_value* val, + int level, bool sep); + +void dump_value(std::ostringstream& os, const json_value* v, int level, const std::string_view* key = nullptr) +{ + dump_repeat(os, tab, level); + + if (key) + os << quote << *key << quote << ": "; + + switch (v->type) + { + case detail::node_t::array: + { + auto& vals = v->value.array->value_array; + os << "[" << std::endl; + size_t n = vals.size(); + size_t pos = 0; + for (auto it = vals.begin(), ite = vals.end(); it != ite; ++it, ++pos) + dump_item(os, nullptr, *it, level, pos < (n-1)); + + dump_repeat(os, tab, level); + os << "]"; + } + break; + case detail::node_t::boolean_false: + os << "false"; + break; + case detail::node_t::boolean_true: + os << "true"; + break; + case detail::node_t::null: + os << "null"; + break; + case detail::node_t::number: + os << v->value.numeric; + break; + case detail::node_t::object: + { + const std::vector<std::string_view>& key_order = v->value.object->key_order; + auto& vals = v->value.object->value_object; + os << "{" << std::endl; + size_t n = vals.size(); + + if (key_order.empty()) + { + // Dump object's children unordered. + size_t pos = 0; + for (auto it = vals.begin(), ite = vals.end(); it != ite; ++it, ++pos) + { + std::string_view this_key = it->first; + auto& this_val = it->second; + + dump_item(os, &this_key, this_val, level, pos < (n-1)); + } + } + else + { + // Dump them based on key's original ordering. + size_t pos = 0; + for (auto it = key_order.begin(), ite = key_order.end(); it != ite; ++it, ++pos) + { + std::string_view this_key = *it; + auto val_pos = vals.find(this_key); + assert(val_pos != vals.end()); + + dump_item(os, &this_key, val_pos->second, level, pos < (n-1)); + } + } + + dump_repeat(os, tab, level); + os << "}"; + } + break; + case detail::node_t::string: + json::dump_string( + os, + std::string(v->value.str.p, v->value.str.n)); + break; + case detail::node_t::unset: + default: + ; + } +} + +void dump_item( + std::ostringstream& os, const std::string_view* key, const json_value* val, + int level, bool sep) +{ + dump_value(os, val, level+1, key); + if (sep) + os << ","; + os << std::endl; +} + +std::string dump_json_tree(const json_value* root) +{ + if (root->type == detail::node_t::unset) + return std::string(); + + std::ostringstream os; + dump_value(os, root, 0); + return os.str(); +} + +void dump_string_xml(std::ostringstream& os, std::string_view s) +{ + const char* p = s.data(); + const char* p_end = p + s.size(); + for (; p != p_end; ++p) + { + char c = *p; + switch (c) + { + case '"': + os << """; + break; + case '<': + os << "<"; + break; + case '>': + os << ">"; + break; + case '&': + os << "&"; + break; + case '\'': + os << "'"; + break; + default: + os << c; + } + } +} + +void dump_object_item_xml( + std::ostringstream& os, std::string_view key, const json_value* val, int level); + +void dump_value_xml(std::ostringstream& os, const json_value* v, int level) +{ + switch (v->type) + { + case detail::node_t::array: + { + os << "<array"; + if (level == 0) + os << " xmlns=\"" << NS_orcus_json_xml << "\""; + os << ">"; + + auto& vals = v->value.array->value_array; + + for (auto it = vals.begin(), ite = vals.end(); it != ite; ++it) + { + os << "<item>"; + dump_value_xml(os, *it, level+1); + os << "</item>"; + } + + os << "</array>"; + } + break; + case detail::node_t::boolean_false: + os << "<false/>"; + break; + case detail::node_t::boolean_true: + os << "<true/>"; + break; + case detail::node_t::null: + os << "<null/>"; + break; + case detail::node_t::number: + os << "<number value=\""; + os << v->value.numeric; + os << "\"/>"; + break; + case detail::node_t::object: + { + os << "<object"; + if (level == 0) + os << " xmlns=\"" << NS_orcus_json_xml << "\""; + os << ">"; + + const json_value_object& jvo = *v->value.object; + auto& key_order = jvo.key_order; + auto& vals = jvo.value_object; + + if (key_order.empty()) + { + // Dump object's children unordered. + for (auto it = vals.begin(), ite = vals.end(); it != ite; ++it) + { + auto& key = it->first; + auto& val = it->second; + dump_object_item_xml(os, key, val, level); + } + } + else + { + // Dump them based on key's original ordering. + for (auto it = key_order.begin(), ite = key_order.end(); it != ite; ++it) + { + auto& key = *it; + auto val_pos = vals.find(key); + assert(val_pos != vals.end()); + + dump_object_item_xml(os, key, val_pos->second, level); + } + } + + os << "</object>"; + } + break; + case detail::node_t::string: + os << "<string value=\""; + dump_string_xml(os, std::string_view(v->value.str.p, v->value.str.n)); + os << "\"/>"; + break; + case detail::node_t::unset: + default: + ; + } +} + +class yaml_dumper +{ + enum class write_type { unspecified, indent, linebreak, value }; + + std::size_t m_indent_length = 0; + write_type m_last_write = write_type::unspecified; + + void reset() + { + m_indent_length = 0; + m_last_write = write_type::unspecified; + } + + static bool needs_quote(std::string_view s) + { + char c_prev = 0; + + for (char c : s) + { + switch (c) + { + case '#': + return true; + case ' ': + if (c_prev == ':') + return true; + } + + c_prev = c; + } + + return false; + } + +public: + std::string dump(const json_value* root) + { + if (!root || root->type == detail::node_t::unset) + return std::string(); + + reset(); + + std::ostringstream os; + os << "---" << std::endl; + write_value(os, root); + return os.str(); + } + +private: + void write_indent(std::ostringstream& os) + { + m_last_write = write_type::indent; + + for (std::size_t i = 0; i < m_indent_length; ++i) + os << ' '; + } + + void write_linebreak(std::ostringstream& os) + { + if (m_last_write == write_type::linebreak) + return; + + m_last_write = write_type::linebreak; + os << std::endl; + } + + void write_string(std::ostringstream& os, std::string_view s) + { + bool quote_value = needs_quote(s); + + if (quote_value) + os << '"'; + + os << s; + + if (quote_value) + os << '"'; + } + + void write_value(std::ostringstream& os, const json_value* v) + { + m_last_write = write_type::value; + detail::node_t parent_type = v->parent ? v->parent->type : detail::node_t::unset; + + switch (v->type) + { + case detail::node_t::array: + { + if (parent_type != detail::node_t::unset) + write_linebreak(os); + + for (const json_value* cv : v->value.array->value_array) + { + write_indent(os); + os << "- "; + m_indent_length += 2; + write_value(os, cv); + m_indent_length -= 2; + write_linebreak(os); + } + break; + } + case detail::node_t::boolean_false: + os << "false"; + break; + case detail::node_t::boolean_true: + os << "true"; + break; + case detail::node_t::null: + os << "null"; + break; + case detail::node_t::number: + { + os << v->value.numeric; + break; + } + case detail::node_t::object: + { + const json_value_object& jvo = *v->value.object; + const std::vector<std::string_view>& key_order = jvo.key_order; + const json_value_object::object_type& vals = jvo.value_object; + + std::deque<std::tuple<std::string_view, const json_value*>> key_values; + + if (key_order.empty()) + { + // Dump object's children unordered. + for (const auto& val : vals) + key_values.emplace_back(val.first, val.second); + } + else + { + // Dump them based on key's original ordering. + for (std::string_view key : key_order) + { + auto val_pos = vals.find(key); + assert(val_pos != vals.end()); + key_values.emplace_back(key, val_pos->second); + } + } + + if (key_values.empty()) + break; + + auto write_key_value = [this, &os](std::string_view key, const json_value* value) + { + std::size_t indent_add = 2; + write_string(os, key); + os << ": "; + m_indent_length += indent_add; + write_value(os, value); + m_indent_length -= indent_add; + write_linebreak(os); + }; + + if (parent_type == detail::node_t::array) + { + // Parent is an array. Continue on the "bullet" line. + write_key_value(std::get<0>(key_values[0]), std::get<1>(key_values[0])); + key_values.pop_front(); + } + else if (parent_type != detail::node_t::unset) + write_linebreak(os); + + for (auto& [key, value] : key_values) + { + write_indent(os); + write_key_value(key, value); + } + + break; + } + case detail::node_t::string: + { + write_string(os, {v->value.str.p, v->value.str.n}); + break; + } + case detail::node_t::unset: + default: + ; + } + } +}; + +void dump_object_item_xml( + std::ostringstream& os, std::string_view key, const json_value* val, int level) +{ + os << "<item name=\""; + dump_string_xml(os, key); + os << "\">"; + dump_value_xml(os, val, level+1); + os << "</item>"; +} + +std::string dump_xml_tree(const json_value* root) +{ + if (root->type == detail::node_t::unset) + return std::string(); + + std::ostringstream os; + os << "<?xml version=\"1.0\"?>" << std::endl; + dump_value_xml(os, root, 0); + os << std::endl; + return os.str(); +} + +struct parser_stack +{ + std::string_view key; + json_value* node; + + parser_stack(json_value* _node) : node(_node) {} +}; + +struct external_ref +{ + std::string_view path; + json_value_object* dest; + + external_ref(std::string_view _path, json_value_object* _dest) : + path(_path), dest(_dest) {} +}; + +class parser_handler +{ + json_value* m_root; + const json_config& m_config; + + std::vector<parser_stack> m_stack; + std::vector<external_ref> m_external_refs; + + document_resource& m_res; + + json_value* push_value(json_value* value) + { + assert(!m_stack.empty()); + parser_stack& cur = m_stack.back(); + + switch (cur.node->type) + { + case detail::node_t::array: + { + json_value_array* jva = cur.node->value.array; + value->parent = cur.node; + jva->value_array.push_back(value); + return jva->value_array.back(); + } + case detail::node_t::object: + { + std::string_view key = cur.key; + json_value_object* jvo = cur.node->value.object; + value->parent = cur.node; + + if (m_config.resolve_references && + key == "$ref" && value->type == detail::node_t::string) + { + std::string_view sv(value->value.str.p, value->value.str.n); + if (!jvo->has_ref && !sv.empty() && sv[0] != '#') + { + // Store the external reference path and the destination + // object for later processing. + m_external_refs.emplace_back(sv, jvo); + jvo->has_ref = true; + } + } + + if (m_config.preserve_object_order) + jvo->key_order.push_back(key); + + auto r = jvo->value_object.insert(std::make_pair(key, value)); + + if (!r.second) + throw document_error("adding the same key twice"); + + return r.first->second; + } + default: + break; + } + + std::ostringstream os; + os << BOOST_CURRENT_FUNCTION << ": unstackable JSON value type."; + throw document_error(os.str()); + } + +public: + parser_handler(const json_config& config, document_resource& res) : + m_root(nullptr), m_config(config), m_res(res) {} + + void begin_parse() + { + m_root = nullptr; + } + + void end_parse() + { + } + + void begin_array() + { + if (m_root) + { + json_value* jv = m_res.obj_pool.construct(detail::node_t::array); + jv->value.array = m_res.obj_pool_jva.construct(); + jv = push_value(jv); + assert(jv && jv->type == detail::node_t::array); + m_stack.push_back(parser_stack(jv)); + } + else + { + m_root = m_res.obj_pool.construct(detail::node_t::array); + m_root->value.array = m_res.obj_pool_jva.construct(); + m_stack.push_back(parser_stack(m_root)); + } + } + + void end_array() + { + assert(!m_stack.empty()); + m_stack.pop_back(); + } + + void begin_object() + { + if (m_root) + { + json_value* jv = m_res.obj_pool.construct(detail::node_t::object); + jv->value.object = m_res.obj_pool_jvo.construct(); + jv = push_value(jv); + assert(jv && jv->type == detail::node_t::object); + m_stack.push_back(parser_stack(jv)); + } + else + { + m_root = m_res.obj_pool.construct(detail::node_t::object); + m_root->value.object = m_res.obj_pool_jvo.construct(); + m_stack.push_back(parser_stack(m_root)); + } + } + + void object_key(std::string_view key, bool transient) + { + parser_stack& cur = m_stack.back(); + cur.key = key; + if (m_config.persistent_string_values || transient) + // The tree manages the life cycle of this string value. + cur.key = m_res.str_pool.intern(cur.key).first; + } + + void end_object() + { + assert(!m_stack.empty()); + m_stack.pop_back(); + } + + void boolean_true() + { + push_value(m_res.obj_pool.construct(detail::node_t::boolean_true)); + } + + void boolean_false() + { + push_value(m_res.obj_pool.construct(detail::node_t::boolean_false)); + } + + void null() + { + push_value(m_res.obj_pool.construct(detail::node_t::null)); + } + + void string(std::string_view s, bool transient) + { + if (m_config.persistent_string_values || transient) + // The tree manages the life cycle of this string value. + s = m_res.str_pool.intern(s).first; + + json_value* jv = m_res.obj_pool.construct(detail::node_t::string); + jv->value.str.p = s.data(); + jv->value.str.n = s.size(); + push_value(jv); + } + + void number(double val) + { + json_value* jv = m_res.obj_pool.construct(detail::node_t::number); + jv->value.numeric = val; + push_value(jv); + } + + json_value* get_root() + { + return m_root; + } + + const std::vector<external_ref>& get_external_refs() const + { + return m_external_refs; + } +}; + +} // anonymous namespace + +struct const_node::impl +{ + const document_tree* m_doc; + json_value* m_node; + + impl(const document_tree* doc, json_value* jv) : m_doc(doc), m_node(jv) {} + impl(const impl& other) : m_doc(other.m_doc), m_node(other.m_node) {} +}; + +const_node::const_node(const document_tree* doc, json_value* jv) : mp_impl(std::make_unique<impl>(doc, jv)) {} +const_node::const_node(std::unique_ptr<impl>&& p) : mp_impl(std::move(p)) {} +const_node::const_node(const const_node& other) : mp_impl(std::make_unique<impl>(*other.mp_impl)) {} +const_node::const_node(const_node&& rhs) : mp_impl(std::move(rhs.mp_impl)) {} +const_node::~const_node() {} + +const_node& const_node::operator=(const const_node& other) +{ + if (this == &other) + return *this; + + const_node tmp(other); + mp_impl.swap(tmp.mp_impl); + return *this; +} + +const_node& const_node::operator=(const_node&& other) +{ + if (this == &other) + return *this; + + mp_impl = std::move(other.mp_impl); + return *this; +} + +uintptr_t const_node::identity() const +{ + return reinterpret_cast<uintptr_t>(mp_impl->m_node); +} + +const_node_iterator const_node::begin() const +{ + if (mp_impl->m_node->type != detail::node_t::array) + throw document_error("const_node::begin: this method only supports array nodes."); + + return const_node_iterator(mp_impl->m_doc, *this, true); +} + +const_node_iterator const_node::end() const +{ + if (mp_impl->m_node->type != detail::node_t::array) + throw document_error("const_node::end: this method only supports array nodes."); + + return const_node_iterator(mp_impl->m_doc, *this, false); +} + +node_t const_node::type() const +{ + // Convert it back to the public enum type. + return static_cast<node_t>(mp_impl->m_node->type); +} + +size_t const_node::child_count() const +{ + switch (mp_impl->m_node->type) + { + case detail::node_t::object: + return mp_impl->m_node->value.object->value_object.size(); + case detail::node_t::array: + return mp_impl->m_node->value.array->value_array.size(); + case detail::node_t::string: + case detail::node_t::number: + case detail::node_t::boolean_true: + case detail::node_t::boolean_false: + case detail::node_t::null: + case detail::node_t::unset: + default: + ; + } + return 0; +} + +std::vector<std::string_view> const_node::keys() const +{ + if (mp_impl->m_node->type != detail::node_t::object) + throw document_error("node::keys: this node is not of object type."); + + const json_value_object* jvo = mp_impl->m_node->value.object; + if (!jvo->key_order.empty()) + // Prefer to use key_order when it's populated. + return jvo->key_order; + + std::vector<std::string_view> keys; + + for (const auto& n : jvo->value_object) + keys.push_back(n.first); + + return keys; +} + +std::string_view const_node::key(size_t index) const +{ + if (mp_impl->m_node->type != detail::node_t::object) + throw document_error("node::key: this node is not of object type."); + + const json_value_object* jvo = mp_impl->m_node->value.object; + if (index >= jvo->key_order.size()) + throw std::out_of_range("node::key: index is out-of-range."); + + return jvo->key_order[index]; +} + +bool const_node::has_key(std::string_view key) const +{ + if (mp_impl->m_node->type != detail::node_t::object) + return false; + + const json_value_object* jvo = mp_impl->m_node->value.object; + const json_value_object::object_type& children = jvo->value_object; + + return children.count(key) != 0; +} + +const_node const_node::child(size_t index) const +{ + switch (mp_impl->m_node->type) + { + case detail::node_t::object: + { + // This works only when the key order is preserved. + const json_value_object* jvo = mp_impl->m_node->value.object; + if (index >= jvo->key_order.size()) + throw std::out_of_range("node::child: index is out-of-range"); + + std::string_view key = jvo->key_order[index]; + auto it = jvo->value_object.find(key); + assert(it != jvo->value_object.end()); + return const_node(mp_impl->m_doc, it->second); + } + break; + case detail::node_t::array: + { + const json_value_array* jva = mp_impl->m_node->value.array; + if (index >= jva->value_array.size()) + throw std::out_of_range("node::child: index is out-of-range"); + + return const_node(mp_impl->m_doc, jva->value_array[index]); + } + break; + case detail::node_t::string: + case detail::node_t::number: + case detail::node_t::boolean_true: + case detail::node_t::boolean_false: + case detail::node_t::null: + case detail::node_t::unset: + default: + throw document_error("node::child: this node cannot have child nodes."); + } +} + +const_node const_node::child(std::string_view key) const +{ + if (mp_impl->m_node->type != detail::node_t::object) + throw document_error("node::child: this node is not of object type."); + + const json_value_object* jvo = mp_impl->m_node->value.object; + auto it = jvo->value_object.find(key); + if (it == jvo->value_object.end()) + { + std::ostringstream os; + os << "node::child: this object does not have a key labeled '" << key << "'"; + throw document_error(os.str()); + } + + return const_node(mp_impl->m_doc, it->second); +} + +const_node const_node::parent() const +{ + if (!mp_impl->m_node->parent) + throw document_error("node::parent: this node has no parent."); + + return const_node(mp_impl->m_doc, mp_impl->m_node->parent); +} + +const_node const_node::back() const +{ + if (mp_impl->m_node->type != detail::node_t::array) + throw document_error("const_node::child: this node is not of array type."); + + const json_value_array* jva = mp_impl->m_node->value.array; + if (jva->value_array.empty()) + throw document_error("const_node::child: this node has no children."); + + return const_node(mp_impl->m_doc, jva->value_array.back()); +} + +std::string_view const_node::string_value() const +{ + if (mp_impl->m_node->type != detail::node_t::string) + throw document_error("node::key: current node is not of string type."); + + return std::string_view(mp_impl->m_node->value.str.p, mp_impl->m_node->value.str.n); +} + +double const_node::numeric_value() const +{ + if (mp_impl->m_node->type != detail::node_t::number) + throw document_error("node::key: current node is not of numeric type."); + + return mp_impl->m_node->value.numeric; +} + +node::node(const document_tree* doc, json_value* jv) : const_node(doc, jv) {} +node::node(const_node&& rhs) : const_node(std::move(rhs)) {} +node::node(const node& other) : const_node(other) {} +node::node(node&& rhs) : const_node(rhs) {} +node::~node() {} + +node& node::operator=(const node& other) +{ + if (this == &other) + return *this; + + node tmp(other); + mp_impl.swap(tmp.mp_impl); + return *this; +} + +node& node::operator=(const detail::init::node& v) +{ + document_resource& res = + const_cast<document_resource&>(mp_impl->m_doc->get_resource()); + + v.store_to_node(res, mp_impl->m_node); + + return *this; +} + +node node::operator[](std::string_view key) +{ + if (mp_impl->m_node->type != detail::node_t::object) + throw document_error("node::operator[]: the node must be of object type."); + + json_value_object* jvo = const_cast<json_value_object*>(mp_impl->m_node->value.object); + auto it = jvo->value_object.find(key); + if (it == jvo->value_object.end()) + { + // This object doesn't have the specified key. Create a new empty node + // on the fly. + document_resource& res = + const_cast<document_resource&>(mp_impl->m_doc->get_resource()); + json_value* jv = res.obj_pool.construct(detail::node_t::unset); + jv->parent = mp_impl->m_node; + auto r = jvo->value_object.insert(std::make_pair(key, jv)); + it = r.first; + } + + return node(mp_impl->m_doc, it->second); +} + +node node::child(size_t index) +{ + const_node cn = const_node::child(index); + return node(std::move(cn)); +} + +node node::child(std::string_view key) +{ + const_node cn = const_node::child(key); + return node(std::move(cn)); +} + +node node::parent() +{ + const_node cn = const_node::parent(); + return node(std::move(cn)); +} + +node node::back() +{ + const_node cn = const_node::back(); + return node(std::move(cn)); +} + +void node::push_back(const detail::init::node& v) +{ + if (mp_impl->m_node->type != detail::node_t::array) + { + std::ostringstream os; + os << "node::push_back: the node must be of array type, but the value of this node type is '" << mp_impl->m_node->type << "'."; + throw document_error(os.str()); + } + + json_value_array* jva = mp_impl->m_node->value.array; + const document_resource& res = mp_impl->m_doc->get_resource(); + jva->value_array.push_back(v.to_json_value(const_cast<document_resource&>(res))); +} + +struct const_node_iterator::impl +{ + const document_tree* m_doc; + std::vector<json_value*>::const_iterator m_pos; + std::vector<json_value*>::const_iterator m_end; + const_node m_current_node; + + impl() : m_doc(nullptr), m_current_node(nullptr, nullptr) {} + + impl(const impl& other) : + m_doc(other.m_doc), + m_pos(other.m_pos), + m_end(other.m_end), + m_current_node(other.m_current_node) {} + + impl(const document_tree* doc, const const_node& v, bool begin) : + m_doc(doc), m_current_node(nullptr, nullptr) + { + const json_value_array* jva = v.mp_impl->m_node->value.array; + m_pos = begin ? jva->value_array.cbegin() : jva->value_array.cend(); + m_end = jva->value_array.cend(); + + if (m_pos != m_end) + m_current_node = const_node(m_doc, *m_pos); + } + + void update_current() + { + m_current_node = const_node(m_doc, m_pos == m_end ? nullptr : *m_pos); + } +}; + +const_node_iterator::const_node_iterator() : + mp_impl(std::make_unique<impl>()) {} + +const_node_iterator::const_node_iterator(const const_node_iterator& other) : + mp_impl(std::make_unique<impl>(*other.mp_impl)) {} + +const_node_iterator::const_node_iterator(const document_tree* doc, const const_node& v, bool begin) : + mp_impl(std::make_unique<impl>(doc, v, begin)) {} + +const_node_iterator::~const_node_iterator() {} + +const const_node& const_node_iterator::operator*() const +{ + return mp_impl->m_current_node; +} + +const const_node* const_node_iterator::operator->() const +{ + return &mp_impl->m_current_node; +} + +const_node_iterator& const_node_iterator::operator++() +{ + ++mp_impl->m_pos; + mp_impl->update_current(); + return *this; +} + +const_node_iterator const_node_iterator::operator++(int) +{ + const_node_iterator tmp(*this); + ++mp_impl->m_pos; + mp_impl->update_current(); + return tmp; +} + +const_node_iterator& const_node_iterator::operator--() +{ + --mp_impl->m_pos; + mp_impl->update_current(); + return *this; +} + +const_node_iterator const_node_iterator::operator--(int) +{ + const_node_iterator tmp(*this); + --mp_impl->m_pos; + mp_impl->update_current(); + return tmp; +} + +bool const_node_iterator::operator== (const const_node_iterator& other) const +{ + return mp_impl->m_pos == other.mp_impl->m_pos && mp_impl->m_end == other.mp_impl->m_end; +} + +bool const_node_iterator::operator!= (const const_node_iterator& other) const +{ + return !operator==(other); +} + +const_node_iterator& const_node_iterator::operator= (const const_node_iterator& other) +{ + mp_impl->m_doc = other.mp_impl->m_doc; + mp_impl->m_pos = other.mp_impl->m_pos; + mp_impl->m_end = other.mp_impl->m_end; + mp_impl->update_current(); + + return *this; +} + +array::array() {} +array::array(array&& other) : m_vs(std::move(other.m_vs)) {} +array::array(std::initializer_list<detail::init::node> vs) +{ + for (const detail::init::node& v : vs) + m_vs.push_back(std::move(const_cast<detail::init::node&>(v))); +} + +array::~array() {} + +object::object() {} +object::object(object&& /*other*/) {} +object::~object() {} + +namespace { + +json_value* aggregate_nodes(document_resource& res, std::vector<json_value*> nodes, bool object) +{ + bool preserve_object_order = true; + + if (object) + { + json_value* jv = res.obj_pool.construct(detail::node_t::object); + jv->value.object = res.obj_pool_jvo.construct(); + json_value_object* jvo = jv->value.object; + + for (json_value* const_node : nodes) + { + if (const_node->type != detail::node_t::key_value) + throw document_error("key-value pair was expected."); + + auto& kvp = const_node->value.kvp; + + if (preserve_object_order) + jvo->key_order.emplace_back(kvp.key, kvp.n_key); + + kvp.value->parent = jv; + auto r = jvo->value_object.insert( + std::make_pair(std::string_view(kvp.key, kvp.n_key), kvp.value)); + + if (!r.second) + throw document_error("adding the same key twice"); + } + + return jv; + } + + json_value* jv = res.obj_pool.construct(detail::node_t::array); + jv->value.array = res.obj_pool_jva.construct(); + json_value_array* jva = jv->value.array; + + for (json_value* const_node : nodes) + { + if (const_node->type == detail::node_t::key_value) + throw document_error("key-value pair was not expected."); + + const_node->parent = jv; + jva->value_array.push_back(const_node); + } + + return jv; +} + +void aggregate_nodes_to_object( + document_resource& res, std::vector<json_value*> nodes, json_value* parent) +{ + bool preserve_object_order = true; + + json_value_object* jvo = res.obj_pool_jvo.construct(); + parent->value.object = jvo; + + for (json_value* const_node : nodes) + { + if (const_node->type != detail::node_t::key_value) + throw document_error("key-value pair was expected."); + + auto& kvp = const_node->value.kvp; + + if (preserve_object_order) + jvo->key_order.emplace_back(kvp.key, kvp.n_key); + + kvp.value->parent = parent; + auto r = jvo->value_object.insert( + std::make_pair(std::string_view(kvp.key, kvp.n_key), kvp.value)); + + if (!r.second) + throw document_error("adding the same key twice"); + } +} + +void aggregate_nodes_to_array( + document_resource& res, std::vector<json_value*> nodes, json_value* parent) +{ + json_value_array* jva = res.obj_pool_jva.construct(); + parent->value.array = jva; + + for (json_value* const_node : nodes) + { + if (const_node->type == detail::node_t::key_value) + throw document_error("key-value pair was not expected."); + + const_node->parent = parent; + jva->value_array.push_back(const_node); + } +} + +#ifndef NDEBUG + +/** + * Verify that the parent pointers stored in the child objects point to + * their real parent object. + */ +void verify_parent_pointers(const json_value* jv, bool object) +{ + if (object) + { + json_value_object* jvo = jv->value.object; + for (const auto& child : jvo->value_object) + { + const json_value& cv = *child.second; + assert(cv.parent == jv); + } + } + else + { + json_value_array* jva = jv->value.array; + for (const auto& child : jva->value_array) + { + const json_value& cv = *child; + assert(cv.parent == jv); + } + } +} + +#endif + +} // anonymous namespace + +namespace detail { namespace init { + +struct node::impl +{ + detail::node_t m_type; + + union + { + double m_value_number; + const char* m_value_string; + }; + + std::vector<detail::init::node> m_value_array; + + impl() : m_type(detail::node_t::unset) {} + impl(double v) : m_type(detail::node_t::number), m_value_number(v) {} + impl(int v) : m_type(detail::node_t::number), m_value_number(v) {} + impl(bool b) : m_type(b ? detail::node_t::boolean_true : detail::node_t::boolean_false) {} + impl(decltype(nullptr)) : m_type(detail::node_t::null) {} + impl(const char* p) : m_type(detail::node_t::string), m_value_string(p) {} + impl(const std::string& s) : m_type(detail::node_t::string), m_value_string(s.data()) {} + + impl(std::initializer_list<detail::init::node> vs) : + m_type(detail::node_t::array_implicit) + { + for (const detail::init::node& v : vs) + m_value_array.push_back(std::move(const_cast<detail::init::node&>(v))); + + // If the list has two elements, and the first element is of type string, + // we treat this as object's key-value pair. + + if (m_value_array.size() != 2) + return; + + const detail::init::node& v0 = *m_value_array.begin(); + if (v0.mp_impl->m_type == detail::node_t::string) + m_type = detail::node_t::key_value; + } + + impl(json::array array) : + m_type(detail::node_t::array), + m_value_array(std::move(array.m_vs)) + {} + + impl(json::object /*obj*/) : + m_type(detail::node_t::object) {} +}; + +node::node(double v) : mp_impl(std::make_unique<impl>(v)) {} +node::node(int v) : mp_impl(std::make_unique<impl>(v)) {} +node::node(bool b) : mp_impl(std::make_unique<impl>(b)) {} +node::node(std::nullptr_t) : mp_impl(std::make_unique<impl>(nullptr)) {} +node::node(const char* p) : mp_impl(std::make_unique<impl>(p)) {} +node::node(const std::string& s) : mp_impl(std::make_unique<impl>(s)) {} +node::node(std::initializer_list<detail::init::node> vs) : mp_impl(std::make_unique<impl>(std::move(vs))) {} +node::node(json::array array) : mp_impl(std::make_unique<impl>(std::move(array))) {} +node::node(json::object obj) : mp_impl(std::make_unique<impl>(std::move(obj))) {} + +node::node(node&& other) : mp_impl(std::move(other.mp_impl)) {} +node::~node() {} + +json::node_t node::type() const +{ + return static_cast<json::node_t>(mp_impl->m_type); +} + +json_value* node::to_json_value(document_resource& res) const +{ + json_value* jv = nullptr; + + switch (mp_impl->m_type) + { + case detail::node_t::key_value: + { + assert(mp_impl->m_value_array.size() == 2); + auto it = mp_impl->m_value_array.begin(); + const detail::init::node& key_node = *it; + assert(key_node.mp_impl->m_type == detail::node_t::string); + std::string_view key = res.str_pool.intern(key_node.mp_impl->m_value_string).first; + ++it; + json_value* value = it->to_json_value(res); + if (value->type == detail::node_t::key_value) + throw key_value_error("nested key-value pairs are not allowed."); + + ++it; + assert(it == mp_impl->m_value_array.end()); + + jv = res.obj_pool.construct(mp_impl->m_type); + jv->value.kvp.key = key.data(); + jv->value.kvp.n_key = key.size(); + jv->value.kvp.value = value; + break; + } + case detail::node_t::array: + { + std::vector<json_value*> nodes; + for (const detail::init::node& v2 : mp_impl->m_value_array) + { + json_value* r = v2.to_json_value(res); + nodes.push_back(r); + } + + jv = aggregate_nodes(res, std::move(nodes), false); +#ifndef NDEBUG + verify_parent_pointers(jv, false); +#endif + break; + } + case detail::node_t::array_implicit: + { + std::vector<json_value*> nodes; + bool object = !mp_impl->m_value_array.empty(); + for (const detail::init::node& v2 : mp_impl->m_value_array) + { + json_value* r = v2.to_json_value(res); + if (r->type != detail::node_t::key_value) + object = false; + nodes.push_back(r); + } + + jv = aggregate_nodes(res, std::move(nodes), object); +#ifndef NDEBUG + verify_parent_pointers(jv, object); +#endif + break; + } + case detail::node_t::object: + { + // Currently only empty object instance is allowed. + assert(mp_impl->m_value_array.size() == 0); + jv = res.obj_pool.construct(mp_impl->m_type); + jv->value.object = res.obj_pool_jvo.construct(); + break; + } + case detail::node_t::string: + { + std::string_view s = res.str_pool.intern(mp_impl->m_value_string).first; + jv = res.obj_pool.construct(mp_impl->m_type); + jv->value.str.p = s.data(); + jv->value.str.n = s.size(); + break; + } + case detail::node_t::number: + jv = res.obj_pool.construct(mp_impl->m_type); + jv->value.numeric = mp_impl->m_value_number; + break; + case detail::node_t::boolean_true: + case detail::node_t::boolean_false: + case detail::node_t::null: + jv = res.obj_pool.construct(mp_impl->m_type); + break; + case detail::node_t::unset: + default: + { + std::ostringstream os; + os << "unknown node type (type=" << int(mp_impl->m_type) << ")"; + throw document_error(os.str()); + } + } + + return jv; +} + +void node::store_to_node(document_resource& res, json_value* parent) const +{ + parent->type = mp_impl->m_type; + + switch (mp_impl->m_type) + { + case detail::node_t::unset: + throw document_error("node type is unset."); + case detail::node_t::string: + { + std::string_view s = res.str_pool.intern(mp_impl->m_value_string).first; + parent->value.str.p = s.data(); + parent->value.str.n = s.size(); + break; + } + case detail::node_t::number: + parent->value.numeric = mp_impl->m_value_number; + break; + case detail::node_t::object: + { + // Currently only empty object instance is allowed. + assert(mp_impl->m_value_array.size() == 0); + parent->value.object = res.obj_pool_jvo.construct(); + break; + } + case detail::node_t::array_implicit: + { + std::vector<json_value*> nodes; + bool object = true; + for (const detail::init::node& v2 : mp_impl->m_value_array) + { + json_value* r = v2.to_json_value(res); + if (r->type != detail::node_t::key_value) + object = false; + nodes.push_back(r); + } + + if (object) + { + parent->type = detail::node_t::object; + aggregate_nodes_to_object(res, std::move(nodes), parent); + } + else + { + parent->type = detail::node_t::array; + aggregate_nodes_to_array(res, std::move(nodes), parent); + } + + break; + } + case detail::node_t::array: + { + std::vector<json_value*> nodes; + for (const detail::init::node& v2 : mp_impl->m_value_array) + { + json_value* r = v2.to_json_value(res); + nodes.push_back(r); + } + + aggregate_nodes_to_array(res, std::move(nodes), parent); + break; + } + case detail::node_t::boolean_true: + case detail::node_t::boolean_false: + case detail::node_t::null: + break; + case detail::node_t::key_value: + // fall-through + default: + { + std::ostringstream os; + os << "unknown node type (" << (int)mp_impl->m_type << ")"; + throw document_error(os.str()); + } + } +} + +}} // namespace detail::init + +struct document_tree::impl +{ + json::json_value* m_root; + std::unique_ptr<document_resource> m_own_res; + document_resource& m_res; + + impl() : m_root(nullptr), m_own_res(std::make_unique<document_resource>()), m_res(*m_own_res) {} + impl(document_resource& res) : m_root(nullptr), m_res(res) {} +}; + +const document_resource& document_tree::get_resource() const +{ + return mp_impl->m_res; +} + +document_tree::document_tree() : mp_impl(std::make_unique<impl>()) {} +document_tree::document_tree(document_tree&& other) : mp_impl(std::move(other.mp_impl)) {} +document_tree::document_tree(document_resource& res) : mp_impl(std::make_unique<impl>(res)) {} + +document_tree::document_tree(std::initializer_list<detail::init::node> vs) : + mp_impl(std::make_unique<impl>()) +{ + std::vector<json_value*> nodes; + bool object = true; + for (const detail::init::node& v : vs) + { + json_value* r = v.to_json_value(mp_impl->m_res); + if (r->type != detail::node_t::key_value) + object = false; + nodes.push_back(r); + } + + mp_impl->m_root = aggregate_nodes(mp_impl->m_res, std::move(nodes), object); +} + +document_tree::document_tree(array vs) : mp_impl(std::make_unique<impl>()) +{ + json_value_array* jva = mp_impl->m_res.obj_pool_jva.construct(); + mp_impl->m_root = mp_impl->m_res.obj_pool.construct(detail::node_t::array); + mp_impl->m_root->value.array = jva; + + for (const detail::init::node& v : vs.m_vs) + { + json_value* r = v.to_json_value(mp_impl->m_res); + jva->value_array.push_back(r); + } +} + +document_tree::document_tree(object /*obj*/) : mp_impl(std::make_unique<impl>()) +{ + mp_impl->m_root = mp_impl->m_res.obj_pool.construct(detail::node_t::object); + mp_impl->m_root->value.object = mp_impl->m_res.obj_pool_jvo.construct(); +} + +document_tree::~document_tree() {} + +document_tree& document_tree::operator= (std::initializer_list<detail::init::node> vs) +{ + document_tree tmp(std::move(vs)); + swap(tmp); + return *this; +} + +document_tree& document_tree::operator= (array vs) +{ + document_tree tmp(std::move(vs)); + swap(tmp); + return *this; +} + +document_tree& document_tree::operator= (object obj) +{ + document_tree tmp(std::move(obj)); + swap(tmp); + return *this; +} + +void document_tree::load(std::string_view stream, const json_config& config) +{ + json::parser_handler hdl(config, mp_impl->m_res); + json_parser<json::parser_handler> parser(stream, hdl); + parser.parse(); + mp_impl->m_root = hdl.get_root(); + + auto& external_refs = hdl.get_external_refs(); + + json_config ext_config = config; + // The stream will get destroyed after each parsing of an external json file. + ext_config.persistent_string_values = true; + + fs::path parent_dir = config.input_path; + parent_dir = parent_dir.parent_path(); + for (auto it = external_refs.begin(), ite = external_refs.end(); it != ite; ++it) + { + fs::path extfile = std::string{it->path}; + fs::path extpath = parent_dir; + extpath /= extfile; + + // Get the stream content from the path. + file_content ext_content(extpath.string().data()); + + ext_config.input_path = extpath.string(); + document_tree doc(mp_impl->m_res); + try + { + doc.load(ext_content.str(), ext_config); + } + catch (const parse_error& e) + { + std::ostringstream os; + os << "Error while parsing " << extpath.string() << std::endl; + os << create_parse_error_output(ext_content.str(), e.offset()) << std::endl; + os << e.what(); + + // Re-throw as general_error to avoid getting caught as parse + // error by the parent caller. + throw general_error(os.str()); + } + + json::json_value* root = doc.mp_impl->m_root; + if (root->type == detail::node_t::object) + { + json::json_value_object* jvo_src = root->value.object; + json::json_value_object* jvo_dest = it->dest; + if (jvo_dest->value_object.size() == 1) + { + // Swap with the referenced object only when the destination + // has one child value i.e. it only has '$ref'. + jvo_dest->swap(*jvo_src); + jvo_dest->has_ref = false; + } + } + } +} + +json::const_node document_tree::get_document_root() const +{ + json::json_value* p = mp_impl->m_root; + if (!p) + throw document_error("document tree is empty"); + + return json::const_node(this, p); +} + +json::node document_tree::get_document_root() +{ + json::json_value* p = mp_impl->m_root; + if (!p) + throw document_error("document tree is empty"); + + return json::node(this, p); +} + +std::string document_tree::dump() const +{ + if (!mp_impl->m_root) + return std::string(); + + return json::dump_json_tree(mp_impl->m_root); +} + +std::string document_tree::dump_xml() const +{ + if (!mp_impl->m_root) + return std::string(); + + return json::dump_xml_tree(mp_impl->m_root); +} + +std::string document_tree::dump_yaml() const +{ + json::yaml_dumper dumper; + return dumper.dump(mp_impl->m_root); +} + +void document_tree::swap(document_tree& other) +{ + std::swap(mp_impl, other.mp_impl); +} + +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/json_document_tree_test.cpp b/src/liborcus/json_document_tree_test.cpp new file mode 100644 index 0000000..3ab6876 --- /dev/null +++ b/src/liborcus/json_document_tree_test.cpp @@ -0,0 +1,862 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "test_global.hpp" + +#include <orcus/stream.hpp> +#include <orcus/json_document_tree.hpp> +#include <orcus/json_parser_base.hpp> +#include <orcus/config.hpp> +#include <orcus/xml_namespace.hpp> +#include <orcus/dom_tree.hpp> + +#include "filesystem_env.hpp" + +#include <cassert> +#include <cstdlib> +#include <iostream> +#include <cmath> +#include <cstring> + +using namespace orcus; + +fs::path json_test_dirs[] = { + SRCDIR"/test/json/basic1", + SRCDIR"/test/json/basic2", + SRCDIR"/test/json/basic3", + SRCDIR"/test/json/basic4", + SRCDIR"/test/json/empty-array-1", + SRCDIR"/test/json/empty-array-2", + SRCDIR"/test/json/empty-array-3", + SRCDIR"/test/json/nested1", + SRCDIR"/test/json/nested2", + SRCDIR"/test/json/swagger", + SRCDIR"/test/json/to-yaml-1", +}; + +fs::path json_test_refs_dirs[] = { + SRCDIR"/test/json/refs1", +}; + +bool string_expected(const json::const_node& node, const char* expected) +{ + if (node.type() != json::node_t::string) + return false; + + if (node.string_value() == expected) + return true; + + std::cerr << "expected='" << expected << "', actual='" << node.string_value() << "'" << std::endl; + return false; +} + +bool number_expected( + const json::const_node& node, double expected, + double decimal = 0.0, double exponent = 0.0) +{ + if (node.type() != json::node_t::number) + return false; + + double actual = node.numeric_value(); + if (!decimal || !exponent) + return actual == expected; + + // Remove the exponent component. + actual /= std::pow(10.0, exponent); + expected /= std::pow(10.0, exponent); + + // Only compare down to the specified decimal place. + actual *= std::pow(10.0, decimal); + expected *= std::pow(10.0, decimal); + + actual = std::round(actual); + expected = std::round(expected); + + if (actual == expected) + return true; + + std::cerr << "expected=" << expected << ", actual=" << actual << std::endl; + return false; +} + +std::string dump_check_content(const json::document_tree& doc) +{ + std::string xml_strm = doc.dump_xml(); + assert(!xml_strm.empty()); + + xmlns_repository repo; + xmlns_context cxt = repo.create_context(); + dom::document_tree dom(cxt); + dom.load(xml_strm); + + std::ostringstream os; + dom.dump_compact(os); + return os.str(); +} + +bool compare_check_contents(const file_content& expected, const std::string& actual) +{ + std::string_view _expected(expected.data(), expected.size()); + std::string_view _actual(actual.data(), actual.size()); + _expected = trim(_expected); + _actual = trim(_actual); + + if (_expected != _actual) + { + std::size_t pos = locate_first_different_char(_expected, _actual); + std::cout << create_parse_error_output(_expected, pos) << std::endl; + std::cout << create_parse_error_output(_actual, pos) << std::endl; + } + + return _expected == _actual; +} + +void verify_input(json_config& test_config, const fs::path& basedir) +{ + fs::path json_file = basedir / "input.json"; + test_config.input_path = json_file.string(); + + std::cout << "* verify input: " << json_file << std::endl; + + file_content content(json_file.string()); + json::document_tree doc; + doc.load(content.str(), test_config); + + fs::path check_file = basedir / "check.txt"; + file_content check_master(check_file.string()); + std::string check_doc = dump_check_content(doc); + + bool result = compare_check_contents(check_master, check_doc); + assert(result); + + if (fs::path outpath = basedir / "output.yaml"; fs::is_regular_file(outpath)) + { + // Test the yaml output. + std::cout << " * yaml output: " << outpath << std::endl; + + file_content expected(outpath.string()); + std::string actual = doc.dump_yaml(); + + test::verify_content(__FILE__, __LINE__, expected.str(), actual); + } +} + +void test_json_parse() +{ + json_config test_config; + + for (std::size_t i = 0; i < std::size(json_test_dirs); ++i) + { + fs::path basedir = json_test_dirs[i]; + verify_input(test_config, basedir); + } +} + +void test_json_resolve_refs() +{ + json_config test_config; + test_config.resolve_references = true; + + for (size_t i = 0; i < std::size(json_test_refs_dirs); ++i) + { + fs::path basedir = json_test_refs_dirs[i]; + verify_input(test_config, basedir); + } +} + +void test_json_parse_empty() +{ + json_config test_config; + + const char* tests[] = { + "{}", + "[]", + "{\"key1\": {}, \"key2\": {}}" + }; + + for (size_t i = 0; i < std::size(tests); ++i) + { + const char* test = tests[i]; + std::cout << "JSON stream: '" << test << "' (" << std::strlen(test) << ")" << std::endl; + json::document_tree doc; + try + { + doc.load(test, test_config); + } + catch (const parse_error& e) + { + std::cout << create_parse_error_output(test, e.offset()) << std::endl; + std::cout << e.what() << std::endl; + assert(false); + } + } +} + +void test_json_parse_invalid() +{ + json_config test_config; + + const char* invalids[] = { + "[foo]", + "[qwerty]", + "[1,2] null", + "{\"key\" 1: 12}", + "[1,,2]", + "\"key\": {\"inner\": 12}" + }; + + for (std::size_t i = 0; i < std::size(invalids); ++i) + { + const char* invalid_json = invalids[i]; + json::document_tree doc; + try + { + doc.load(invalid_json, test_config); + std::cerr << "Invalid JSON expression is parsed as valid: '" << invalid_json << "'" << std::endl; + assert(false); + } + catch (const parse_error& e) + { + // works as expected. + std::cout << "invalid expression tested: " << invalid_json << std::endl; + std::cout << "error message received: " << e.what() << std::endl; + } + } +} + +std::unique_ptr<json::document_tree> get_doc_tree(const char* filepath) +{ + json_config test_config; + + std::cout << filepath << std::endl; + file_content content(filepath); + std::cout << "--- original" << std::endl; + std::cout << content.str() << std::endl; + + auto doc = std::make_unique<json::document_tree>(); + doc->load(content.str(), test_config); + + return doc; +} + +void dump_and_load( + const json::document_tree& doc, const std::function<void(json::const_node)>& test_func) +{ + json::document_tree doc2; + std::string dumped = doc.dump(); + std::cout << "--- dumped" << std::endl; + std::cout << dumped << std::endl; + doc2.load(dumped, json_config()); + json::const_node node = doc2.get_document_root(); + test_func(node); +} + +void test_json_traverse_basic1() +{ + auto test_func = [](json::const_node node) + { + assert(node.type() == json::node_t::array); + assert(node.child_count() == 3); + assert(node.child(0).type() == json::node_t::boolean_true); + assert(node.child(1).type() == json::node_t::boolean_false); + assert(node.child(2).type() == json::node_t::null); + + // Move to child node and move back. + json::const_node node2 = node.child(0).parent(); + assert(node.identity() == node2.identity()); + }; + + const char* filepath = SRCDIR"/test/json/basic1/input.json"; + std::unique_ptr<json::document_tree> doc = get_doc_tree(filepath); + json::const_node node = doc->get_document_root(); + test_func(node); + dump_and_load(*doc, test_func); +} + +void test_json_traverse_basic2() +{ + auto test_func = [](json::const_node node) + { + assert(node.type() == json::node_t::array); + assert(node.child_count() == 14); + + assert(string_expected(node.child(0), "I am string")); + assert(string_expected(node.child(1), "me too")); + assert(string_expected(node.child(2), "")); + assert(string_expected(node.child(3), "\\")); + assert(string_expected(node.child(4), "/")); + assert(string_expected(node.child(5), "\\b")); + assert(string_expected(node.child(6), "\\f")); + assert(string_expected(node.child(7), "\\n")); + assert(string_expected(node.child(8), "\\r")); + assert(string_expected(node.child(9), "\\t")); + assert(string_expected(node.child(10), "\"quoted\"")); + assert(string_expected(node.child(11), "http://www.google.com")); + assert(string_expected(node.child(12), "one \\n two \\n three")); + assert(string_expected(node.child(13), "front segment 'single quote' and \"double quote\" end segment")); + }; + + const char* filepath = SRCDIR"/test/json/basic2/input.json"; + std::unique_ptr<json::document_tree> doc = get_doc_tree(filepath); + json::const_node node = doc->get_document_root(); + test_func(node); + dump_and_load(*doc, test_func); +} + +void test_json_traverse_basic3() +{ + auto test_func = [](json::const_node node) + { + assert(node.type() == json::node_t::array); + assert(node.child_count() == 9); + + assert(number_expected(node.child(0), 0.0)); + assert(number_expected(node.child(1), 1.0)); + assert(number_expected(node.child(2), 2.0)); + assert(number_expected(node.child(3), 15.0)); + assert(number_expected(node.child(4), 12.34)); + assert(number_expected(node.child(5), -0.12)); + assert(number_expected(node.child(6), 1.2e+22, 1.0, 22.0)); + assert(number_expected(node.child(7), 1.11e-7, 2.0, -7.0)); + assert(number_expected(node.child(8), 11E2)); + }; + + const char* filepath = SRCDIR"/test/json/basic3/input.json"; + std::unique_ptr<json::document_tree> doc = get_doc_tree(filepath); + json::const_node node = doc->get_document_root(); + test_func(node); + dump_and_load(*doc, test_func); +} + +void test_json_traverse_basic4() +{ + auto test_func = [](json::const_node node) + { + assert(node.type() == json::node_t::object); + auto keys = node.keys(); + assert(keys.size() == 3); + for (auto it = keys.begin(), ite = keys.end(); it != ite; ++it) + { + std::string_view key = *it; + json::const_node child = node.child(key); + if (key == "int") + assert(number_expected(child, 12.0)); + else if (key == "float") + assert(number_expected(child, 0.125)); + else if (key == "string") + assert(string_expected(child, "blah...")); + else + assert(!"unexpected key"); + } + }; + + const char* filepath = SRCDIR"/test/json/basic4/input.json"; + std::unique_ptr<json::document_tree> doc = get_doc_tree(filepath); + json::const_node node = doc->get_document_root(); + test_func(node); + dump_and_load(*doc, test_func); +} + +void test_json_traverse_nested1() +{ + auto test_func = [](json::const_node node) + { + uintptr_t root_id = node.identity(); + + assert(node.type() == json::node_t::object); + assert(node.child_count() == 1); + + node = node.child(0); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 3); + + assert(number_expected(node.child(0), 1.0)); + assert(number_expected(node.child(1), 2.0)); + assert(number_expected(node.child(2), 3.0)); + + node = node.parent(); + assert(node.identity() == root_id); + }; + + const char* filepath = SRCDIR"/test/json/nested1/input.json"; + std::unique_ptr<json::document_tree> doc = get_doc_tree(filepath); + json::const_node node = doc->get_document_root(); + test_func(node); + dump_and_load(*doc, test_func); +} + +void test_json_traverse_nested2() +{ + auto test_func = [](json::const_node node) + { + assert(node.type() == json::node_t::array); + assert(node.child_count() == 3); + + node = node.child(0); + assert(node.type() == json::node_t::object); + assert(number_expected(node.child("value"), 1.0)); + node = node.parent(); + + node = node.child(1); + assert(node.type() == json::node_t::object); + assert(number_expected(node.child("value"), 2.0)); + node = node.parent(); + + node = node.child(2); + assert(node.type() == json::node_t::object); + assert(number_expected(node.child("value"), 3.0)); + node = node.parent(); + }; + + const char* filepath = SRCDIR"/test/json/nested2/input.json"; + std::unique_ptr<json::document_tree> doc = get_doc_tree(filepath); + json::const_node node = doc->get_document_root(); + test_func(node); + dump_and_load(*doc, test_func); +} + +void test_json_init_list_flat1() +{ + json::document_tree doc = { 1.0, 2.0, 3.0, 4.0 }; + json::const_node node = doc.get_document_root(); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 4); + + node = node.child(0); + assert(node.type() == json::node_t::number); + assert(node.numeric_value() == 1.0); + node = node.parent(); + + node = node.child(1); + assert(node.type() == json::node_t::number); + assert(node.numeric_value() == 2.0); + node = node.parent(); + + node = node.child(2); + assert(node.type() == json::node_t::number); + assert(node.numeric_value() == 3.0); + node = node.parent(); + + node = node.child(3); + assert(node.type() == json::node_t::number); + assert(node.numeric_value() == 4.0); + node = node.parent(); + + // Use iterators. + auto it = node.begin(); + assert(it->type() == json::node_t::number); + assert(it->numeric_value() == 1.0); + ++it; + assert(it->type() == json::node_t::number); + assert(it->numeric_value() == 2.0); + auto test = it++; // post increment + assert(test->numeric_value() == 2.0); + assert(it->type() == json::node_t::number); + assert(it->numeric_value() == 3.0); + test = ++it; // pre increment + assert(test->numeric_value() == 4.0); + ++it; + assert(it == node.end()); + --it; + assert(it->numeric_value() == 4.0); + test = it--; + assert(test->numeric_value() == 4.0); + assert(it->numeric_value() == 3.0); + + doc = { nullptr }; + node = doc.get_document_root(); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 1); + + node = node.child(0); + assert(node.type() == json::node_t::null); + + doc = { true, false }; + node = doc.get_document_root(); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 2); + + node = node.child(0); + assert(node.type() == json::node_t::boolean_true); + node = node.parent(); + + node = node.child(1); + assert(node.type() == json::node_t::boolean_false); + node = node.parent(); + + doc = { "A", "B", "C" }; + node = doc.get_document_root(); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 3); + + node = node.child(0); + assert(node.type() == json::node_t::string); + assert(node.string_value() == "A"); + node = node.parent(); + + node = node.child(1); + assert(node.type() == json::node_t::string); + assert(node.string_value() == "B"); + node = node.parent(); + + node = node.child(2); + assert(node.type() == json::node_t::string); + assert(node.string_value() == "C"); +} + +void test_json_init_list_nested1() +{ + json::document_tree doc = { + { true, false, nullptr }, + { 1.1, 2.2, "text" } + }; + + json::const_node node = doc.get_document_root(); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 2); + + node = node.child(0); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 3); + assert(node.child(0).type() == json::node_t::boolean_true); + assert(node.child(1).type() == json::node_t::boolean_false); + assert(node.child(2).type() == json::node_t::null); + node = node.parent(); + + node = node.child(1); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 3); + assert(node.child(0).type() == json::node_t::number); + assert(node.child(0).numeric_value() == 1.1); + assert(node.child(1).type() == json::node_t::number); + assert(node.child(1).numeric_value() == 2.2); + assert(node.child(2).type() == json::node_t::string); + assert(node.child(2).string_value() == "text"); +} + +void test_json_init_list_object1() +{ + json::document_tree doc = { + { "key1", 1.2 }, + { "key2", "some text" }, + }; + + json::const_node node = doc.get_document_root(); + assert(node.type() == json::node_t::object); + assert(node.child_count() == 2); + assert(node.key(0) == "key1"); + assert(node.key(1) == "key2"); + + node = node.child("key1"); + assert(node.type() == json::node_t::number); + assert(node.numeric_value() == 1.2); + node = node.parent(); + + node = node.child("key2"); + assert(node.type() == json::node_t::string); + assert(node.string_value() == "some text"); +} + +void test_json_init_list_object2() +{ + // nested objects. + json::document_tree doc = { + { "parent1", + { + { "child1", true }, + { "child2", false }, + { "child3", 123.4 }, + } + }, + { "parent2", "not-nested" }, + }; + + json::const_node node = doc.get_document_root(); + assert(node.type() == json::node_t::object); + assert(node.child_count() == 2); + assert(node.key(0) == "parent1"); + assert(node.key(1) == "parent2"); + + node = node.child("parent1"); + assert(node.type() == json::node_t::object); + assert(node.child_count() == 3); + assert(node.key(0) == "child1"); + assert(node.key(1) == "child2"); + assert(node.key(2) == "child3"); + + assert(node.child("child1").type() == json::node_t::boolean_true); + assert(node.child("child2").type() == json::node_t::boolean_false); + assert(node.child("child3").type() == json::node_t::number); + assert(node.child("child3").numeric_value() == 123.4); + + node = node.parent(); + + node = node.child("parent2"); + assert(node.type() == json::node_t::string); + assert(node.string_value() == "not-nested"); +} + +void test_json_init_list_explicit_array() +{ + try + { + // This structure is too ambiguous and cannot be implicitly + // determined. + json::document_tree doc = { + { "array", { "one", 987.0 } } + }; + assert(!"key_value_error was not thrown"); + } + catch (const json::key_value_error&) + { + // expected. + } + + // Explicitly define an array instead. + json::document_tree doc = { + { "array", json::array({ "one", 987.0 }) } + }; + + json::node node = doc.get_document_root(); + assert(node.type() == json::node_t::object); + assert(node.child_count() == 1); + assert(node.key(0) == "array"); + + node = node.child(0); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 2); + assert(node.child(0).string_value() == "one"); + assert(node.child(1).numeric_value() == 987.0); + + doc = json::array({1, 2, 3}); + node = doc.get_document_root(); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 3); + assert(node.child(0).numeric_value() == 1.0); + assert(node.child(1).numeric_value() == 2.0); + assert(node.child(2).numeric_value() == 3.0); + + node.push_back(4); + node.push_back(5); + assert(node.child_count() == 5); + assert(node.child(3).numeric_value() == 4.0); + assert(node.child(4).numeric_value() == 5.0); + + // empty JSON with array root. + json::document_tree doc2 = json::array(); + node = doc2.get_document_root(); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 0); + + // Assigning a non-const node to a const one should work. + json::const_node cnode = node; + assert(node.type() == json::node_t::array); + assert(node.child_count() == 0); +} + +void test_json_init_list_explicit_object() +{ + json::document_tree doc = json::object(); + json::node node = doc.get_document_root(); + assert(node.type() == json::node_t::object); + assert(node.child_count() == 0); + + // Initialize with an array of 3 empty objects. + doc = { + json::object(), + json::object(), + json::object() + }; + + node = doc.get_document_root(); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 3); + + for (size_t i = 0; i < 3; ++i) + { + node = node.child(i); + assert(node.type() == json::node_t::object); + assert(node.child_count() == 0); + node = node.parent(); + } +} + +void test_json_init_root_object_add_child() +{ + json::document_tree doc = json::object(); + json::node node = doc.get_document_root(); + assert(node.type() == json::node_t::object); + assert(node.child_count() == 0); + + node["child1"] = 1.0; + + assert(node.child_count() == 1); + + node = node.child("child1"); + assert(node.type() == json::node_t::number); + assert(node.numeric_value() == 1.0); + + node = node.parent(); + node["child2"] = "foo"; + + assert(node.child_count() == 2); + + node = node.child("child2"); + assert(node.type() == json::node_t::string); + assert(node.string_value() == "foo"); + + node = node.parent(); + + // Access to child via [] operator. + node = node["child1"]; + assert(node.type() == json::node_t::number); + assert(node.numeric_value() == 1.0); + + node = node.parent(); + node["child3"] = { true, false }; + + node = node.child("child3"); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 2); + + node = node.child(0); + assert(node.type() == json::node_t::boolean_true); + + // Move up to the parent array. + node = node.parent(); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 2); + + // Move down to the other child node. + node = node.child(1); + assert(node.type() == json::node_t::boolean_false); + + // Move up to the root node. + node = node.parent().parent(); + assert(node.type() == json::node_t::object); + assert(node.child_count() == 3); + + node["child1"] = true; // overwrite an existing node. + node = node.child("child1"); + assert(node.type() == json::node_t::boolean_true); + + // direct assignment. + node = false; + assert(node.type() == json::node_t::boolean_false); + + node = node.parent().child("child1"); // make sure the link is still intact. + assert(node.type() == json::node_t::boolean_false); + + node = node.parent(); + node["null-child"] = nullptr; + + node = node.child("null-child"); + assert(node.type() == json::node_t::null); + + node = node.parent(); + node["object-child"] = json::object(); + + node = node.child("object-child"); + assert(node.type() == json::node_t::object); + assert(node.child_count() == 0); + + node["array"] = json::array({true, false, nullptr}); + + node = node.child("array"); + assert(node.type() == json::node_t::array); + assert(node.child_count() == 3); + + node = node.parent(); + node["nested-object"] = + { + { "key1", "foo" }, + { "key2", 12.34 } + }; + + node = node.child("nested-object"); + assert(node.type() == json::node_t::object); + assert(node.child_count() == 2); + assert(node.child("key1").string_value() == "foo"); + assert(node.child("key2").numeric_value() == 12.34); +} + +void test_json_init_empty_array() +{ + json::document_tree doc = json::array(); + json::node node = doc.get_document_root(); + assert(node.type() == json::node_t::array); + + doc = { + { "key1", json::array({true, false}) }, + { "key2", json::array() } // empty array + }; + + node = doc.get_document_root(); + assert(node.type() == json::node_t::object); + node = node["key1"]; + assert(node.type() == json::node_t::array); + node = node.parent()["key2"]; + assert(node.type() == json::node_t::array); +} + +void test_json_dynamic_object_keys() +{ + json::document_tree doc = json::object(); + json::node root = doc.get_document_root(); + + /* {"test": [1.2, 1.3]} */ + auto node = root["test"]; + node = json::array(); + node.push_back(1.2); + node.push_back(1.3); + + // Dump the doc as a string and reload it. + doc.load(doc.dump(), json_config()); + root = doc.get_document_root(); + assert(root.type() == json::node_t::object); + node = root["test"]; + assert(node.type() == json::node_t::array); + assert(node.child_count() == 2u); + assert(node.child(0).numeric_value() == 1.2); + assert(node.child(1).numeric_value() == 1.3); +} + +int main() +{ + try + { + test_json_parse(); + test_json_resolve_refs(); + test_json_parse_empty(); + test_json_parse_invalid(); + test_json_traverse_basic1(); + test_json_traverse_basic2(); + test_json_traverse_basic3(); + test_json_traverse_basic4(); + test_json_traverse_nested1(); + test_json_traverse_nested2(); + + test_json_init_list_flat1(); + test_json_init_list_nested1(); + test_json_init_list_object1(); + test_json_init_list_object2(); + test_json_init_list_explicit_array(); + test_json_init_list_explicit_object(); + test_json_init_root_object_add_child(); + test_json_init_empty_array(); + test_json_dynamic_object_keys(); + } + catch (const orcus::general_error& e) + { + std::cerr << e.what() << std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/json_map_tree.cpp b/src/liborcus/json_map_tree.cpp new file mode 100644 index 0000000..294e782 --- /dev/null +++ b/src/liborcus/json_map_tree.cpp @@ -0,0 +1,786 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "json_map_tree.hpp" +#include "orcus/measurement.hpp" + +#include <iostream> +#include <sstream> + +namespace orcus { + +constexpr json_map_tree::child_position_type json_map_tree::node_child_default_position; + +namespace { + +void throw_path_error(const char* file, int line, std::string_view path) +{ + std::ostringstream os; + os << file << "#" << line << ": failed to link this path '" << path << "'"; + throw json_map_tree::path_error(os.str()); +} + +enum class json_path_token_t { unknown, array_pos, object_key, end }; + +struct json_path_token_value_t +{ + json_path_token_t type = json_path_token_t::unknown; + + union + { + json_map_tree::child_position_type array_pos = json_map_tree::node_child_default_position; + + struct + { + const char* p; + size_t n; + + } str; + + } value; + + json_path_token_value_t(json_path_token_t _type) : type(_type) {} + + json_path_token_value_t(json_map_tree::child_position_type array_pos): type(json_path_token_t::array_pos) + { + value.array_pos = array_pos; + } + + json_path_token_value_t(const char* p, size_t n) : type(json_path_token_t::object_key) + { + value.str.p = p; + value.str.n = n; + } +}; + +std::string_view get_last_object_key(const std::vector<json_path_token_value_t>& stack) +{ + if (stack.size() < 2) + return std::string_view{}; + + auto it = stack.rbegin(); + ++it; + const json_path_token_value_t& t2 = *it; + if (t2.type != json_path_token_t::object_key) + return std::string_view{}; + + return std::string_view{t2.value.str.p, t2.value.str.n}; +} + +class json_path_parser +{ + const char* mp_cur; + const char* mp_end; + +public: + + json_path_parser(std::string_view path) : + mp_cur(path.data()), + mp_end(mp_cur + path.size()) + { + assert(!path.empty()); + assert(path[0] == '$'); + ++mp_cur; // skip the first '$'. + } + + json_path_token_value_t next() + { + if (mp_cur == mp_end) + return json_path_token_t::end; + + if (*mp_cur == '[') + return next_pos(); + + return json_path_token_t::unknown; + } + + json_path_token_value_t next_object_key() + { + assert(*mp_cur == '\''); + ++mp_cur; + const char* p_head = mp_cur; + + for (; mp_cur != mp_end && *mp_cur != '\''; ++mp_cur) + { + // Skip until we reach the closing quote. + } + + if (*mp_cur != '\'') + return json_path_token_t::unknown; + + size_t n = std::distance(p_head, mp_cur); + + ++mp_cur; // Skip the quote. + if (*mp_cur != ']') + return json_path_token_t::unknown; + + ++mp_cur; // Skip the ']'. + + return json_path_token_value_t(p_head, n); + } + + json_path_token_value_t next_pos() + { + assert(*mp_cur == '['); + ++mp_cur; // Skip the '['. + + if (mp_cur == mp_end) + return json_path_token_t::unknown; + + if (*mp_cur == '\'') + return next_object_key(); + + const char* p_head = mp_cur; + + for (; mp_cur != mp_end; ++mp_cur) + { + if (*mp_cur != ']') + continue; + + if (p_head == mp_cur) + { + // empty brackets. + ++mp_cur; + return json_map_tree::node_child_default_position; + } + + const char* p_parse_ended = nullptr; + std::size_t n = mp_cur - p_head; + long pos = to_long({p_head, n}, &p_parse_ended); + + if (p_parse_ended != mp_cur) + // Parsing failed. + break; + + if (pos < 0) + // array position cannot be negative. + break; + + ++mp_cur; // skip the ']'. + return pos; + } + + return json_path_token_t::unknown; + } +}; + +} // anonymous namespace + +json_map_tree::path_error::path_error(const std::string& msg) : + general_error(msg) {} + +json_map_tree::cell_reference_type::cell_reference_type(const cell_position_t& _pos) : + pos(_pos) {} + +json_map_tree::range_reference_type::range_reference_type(const cell_position_t& _pos) : + pos(_pos), row_position(0), row_header(false) {} + +json_map_tree::node::node() {} +json_map_tree::node::node(node&& other) : + type(other.type) +{ + value.children = nullptr; + + switch (type) + { + case map_node_type::array: + value.children = other.value.children; + other.value.children = nullptr; + break; + case map_node_type::cell_ref: + value.cell_ref = other.value.cell_ref; + other.value.cell_ref = nullptr; + break; + case map_node_type::range_field_ref: + value.range_field_ref = other.value.range_field_ref; + other.value.range_field_ref = nullptr; + default: + ; + } + + other.type = map_node_type::unknown; + + row_group = other.row_group; + other.row_group = nullptr; + + anchored_fields = std::move(other.anchored_fields); +} + +json_map_tree::node& json_map_tree::node::get_or_create_child_node(child_position_type pos) +{ + node_children_type& children = *value.children; + + auto it = children.lower_bound(pos); // get the first position where pos <= k is true. + + if (it == children.end() || children.key_comp()(pos, it->first)) + { + // Insert a new array child node of unspecified type at the specified position. + it = children.insert( + it, node_children_type::value_type(pos, node())); + } + + assert(it->first == pos); + return it->second; +} + +json_map_tree::walker::scope::scope(node* _p) : p(_p), array_position(0) {} + +json_map_tree::walker::walker(const json_map_tree& parent) : m_parent(parent) {} + +json_map_tree::node* json_map_tree::walker::push_node(input_node_type nt) +{ + if (!m_unlinked_stack.empty()) + { + // We're still in the unlinked region. + m_unlinked_stack.push_back(nt); + return nullptr; + } + + if (m_stack.empty()) + { + if (!m_parent.m_root) + { + // Tree is empty. + m_unlinked_stack.push_back(nt); + return nullptr; + } + + node* p = m_parent.m_root.get(); + + if (!is_equivalent(nt, p->type)) + { + // Different node type. + m_unlinked_stack.push_back(nt); + return nullptr; + } + + m_stack.push_back(p); + return m_stack.back().p; + } + + scope& cur_scope = m_stack.back(); + + switch (cur_scope.p->type) + { + case json_map_tree::map_node_type::array: + { + node_children_type& node_children = *cur_scope.p->value.children; + + auto it = node_children.find(cur_scope.array_position++); + if (it == node_children.end()) + it = node_children.find(json_map_tree::node_child_default_position); + + if (it == node_children.end()) + { + // This array node has no children. + m_unlinked_stack.push_back(nt); + return nullptr; + } + + node* p = &it->second; + + if (!is_equivalent(nt, p->type)) + { + // Different node type. + m_unlinked_stack.push_back(nt); + return nullptr; + } + + m_stack.push_back(p); + return m_stack.back().p; + } + case json_map_tree::map_node_type::object: + { + node_children_type& node_children = *cur_scope.p->value.children; + auto it = node_children.find(cur_scope.array_position); + if (it == node_children.end()) + { + // The currently specified key does not exist in this object. + m_unlinked_stack.push_back(nt); + return nullptr; + } + + node* p = &it->second; + + if (!is_equivalent(nt, p->type)) + { + // Different node type. + m_unlinked_stack.push_back(nt); + return nullptr; + } + + m_stack.push_back(p); + return m_stack.back().p; + } + default: + ; + } + + m_unlinked_stack.push_back(nt); + return nullptr; +} + +json_map_tree::node* json_map_tree::walker::pop_node(input_node_type nt) +{ + if (!m_unlinked_stack.empty()) + { + // We're in the unlinked region. Pop a node from the unlinked stack. + if (m_unlinked_stack.back() != nt) + throw general_error("Closing node is of different type than the opening node in the unlinked node stack."); + + m_unlinked_stack.pop_back(); + + if (!m_unlinked_stack.empty()) + // We are still in the unlinked region. + return nullptr; + + return m_stack.empty() ? nullptr : m_stack.back().p; + } + + if (m_stack.empty()) + throw general_error("A node was popped while the stack was empty."); + + if (!is_equivalent(nt, m_stack.back().p->type)) + throw general_error("Closing node is of different type than the opening node in the linked node stack."); + + m_stack.pop_back(); + return m_stack.empty() ? nullptr : m_stack.back().p; +} + +void json_map_tree::walker::set_object_key(const char* p, size_t n) +{ + if (!m_unlinked_stack.empty()) + return; + + if (m_stack.empty()) + return; + + scope& cur_scope = m_stack.back(); + if (cur_scope.p->type != map_node_type::object) + return; + + std::string_view pooled = m_parent.m_str_pool.intern({p, n}).first; + cur_scope.array_position = reinterpret_cast<child_position_type>(pooled.data()); +} + +json_map_tree::json_map_tree() {} +json_map_tree::~json_map_tree() {} + +json_map_tree::walker json_map_tree::get_tree_walker() const +{ + return walker(*this); +} + +void json_map_tree::set_cell_link(std::string_view path, const cell_position_t& pos) +{ + path_stack_type stack = get_or_create_destination_node(path); + if (stack.node_stack.empty()) + return; + + node* p = stack.node_stack.back(); + if (p->type != map_node_type::unknown) + { + std::ostringstream os; + os << "this path is not linkable: '" << path << '\''; + throw path_error(os.str()); + } + + p->type = map_node_type::cell_ref; + p->value.cell_ref = m_cell_ref_pool.construct(pos); + + // Ensure that this tree owns the instance of the string. + p->value.cell_ref->pos.sheet = m_str_pool.intern(p->value.cell_ref->pos.sheet).first; +} + +const json_map_tree::node* json_map_tree::get_link(std::string_view path) const +{ + return get_destination_node(path); +} + +void json_map_tree::start_range(const cell_position_t& pos, bool row_header) +{ + m_current_range.pos = pos; + m_current_range.fields.clear(); + m_current_range.row_groups.clear(); + m_current_range.row_header = row_header; +} + +void json_map_tree::append_field_link(std::string_view path, std::string_view label) +{ + m_current_range.fields.emplace_back(path, label); +} + +void json_map_tree::set_range_row_group(std::string_view path) +{ + m_current_range.row_groups.push_back(path); +} + +void json_map_tree::commit_range() +{ + range_reference_type* ref = &get_range_reference(m_current_range.pos); + ref->row_header = m_current_range.row_header; + spreadsheet::col_t column_pos = 0; + + for (std::string_view path : m_current_range.row_groups) + { + path_stack_type stack = get_or_create_destination_node(path); + if (stack.node_stack.empty()) + throw_path_error(__FILE__, __LINE__, path); + + stack.node_stack.back()->row_group = ref; + } + + long unlabeled_field_count = 0; + + for (const auto& field : m_current_range.fields) + { + std::string_view path = field.first; + std::string_view label = field.second; + + path_stack_type stack = get_or_create_destination_node(path); + if (stack.node_stack.empty() || stack.node_stack.back()->type != map_node_type::unknown) + throw_path_error(__FILE__, __LINE__, path); + + node* p = stack.node_stack.back(); + p->type = map_node_type::range_field_ref; + p->value.range_field_ref = m_range_field_ref_pool.construct(); + p->value.range_field_ref->column_pos = column_pos++; + p->value.range_field_ref->ref = ref; + + if (!label.empty()) + { + // A custom label is specified. This one takes precedence. + p->value.range_field_ref->label = m_str_pool.intern(label).first; + } + else if (stack.dest_key.empty()) + { + // This field is probably associated with an array. + std::ostringstream os; + os << "field " << unlabeled_field_count++; + p->value.range_field_ref->label = m_str_pool.intern(os.str()).first; + } + else + // This field is associated with an object key. Use its key as the label. + p->value.range_field_ref->label = m_str_pool.intern(stack.dest_key).first; + + ref->fields.push_back(p->value.range_field_ref); + + // Find the first row group node ancountered going up from the field + // node, and anchor itself to it. + for (auto it = stack.node_stack.rbegin(); it != stack.node_stack.rend(); ++it) + { + node* anchor_node = *it; + if (anchor_node->row_group) + { + anchor_node->anchored_fields.push_back(p); + break; + } + } + } +} + +json_map_tree::range_ref_store_type& json_map_tree::get_range_references() +{ + return m_range_refs; +} + +json_map_tree::range_reference_type& json_map_tree::get_range_reference(const cell_position_t& pos) +{ + auto it = m_range_refs.lower_bound(pos); + if (it == m_range_refs.end() || m_range_refs.key_comp()(m_current_range.pos, it->first)) + { + // Ensure that we own the sheet name instance before storing it. + m_current_range.pos.sheet = m_str_pool.intern(m_current_range.pos.sheet).first; + + it = m_range_refs.insert( + it, range_ref_store_type::value_type( + m_current_range.pos, range_reference_type(m_current_range.pos))); + } + + return it->second; +} + +const json_map_tree::node* json_map_tree::get_destination_node(std::string_view path) const +{ + if (!m_root) + // The tree is empty. + return nullptr; + + if (path.empty() || path[0] != '$') + // A valid path must begin with a '$'. + return nullptr; + + json_path_parser parser(path); + const node* cur_node = m_root.get(); + + for (json_path_token_value_t t = parser.next(); t.type != json_path_token_t::unknown; t = parser.next()) + { + switch (t.type) + { + case json_path_token_t::array_pos: + { + if (cur_node->type != map_node_type::array) + return nullptr; + + auto it = cur_node->value.children->find(t.value.array_pos); + if (it == cur_node->value.children->end()) + return nullptr; + + cur_node = &it->second; + break; + } + case json_path_token_t::object_key: + { + if (cur_node->type != map_node_type::object) + return nullptr; + + child_position_type pos = to_key_position(t.value.str.p, t.value.str.n); + + auto it = cur_node->value.children->find(pos); + if (it == cur_node->value.children->end()) + return nullptr; + + cur_node = &it->second; + break; + } + case json_path_token_t::end: + return cur_node; + case json_path_token_t::unknown: + default: + // Something has gone wrong. Bail out. + break; + } + } + + // If this code path reaches here, something has gone wrong. + return nullptr; +} + +json_map_tree::path_stack_type json_map_tree::get_or_create_destination_node(std::string_view path) +{ + path_stack_type stack; + + if (path.empty() || path[0] != '$') + // A valid path must begin with a '$'. + return stack; + + json_path_parser parser(path); + json_path_token_value_t t = parser.next(); + + std::vector<json_path_token_value_t> token_stack; + token_stack.push_back(t); + + switch (t.type) + { + case json_path_token_t::array_pos: + { + // Insert or re-use an array node and its child at specified position. + + if (m_root) + { + if (m_root->type == map_node_type::unknown) + { + m_root->type = map_node_type::array; + m_root->value.children = m_node_children_pool.construct(); + } + + if (m_root->type != map_node_type::array) + throw path_error("root node was expected to be of type array, but is not."); + } + else + { + m_root = std::make_unique<node>(); + m_root->type = map_node_type::array; + m_root->value.children = m_node_children_pool.construct(); + } + + stack.node_stack.push_back(m_root.get()); + node* p = &stack.node_stack.back()->get_or_create_child_node(t.value.array_pos); + stack.node_stack.push_back(p); + break; + } + case json_path_token_t::object_key: + { + if (m_root) + { + if (m_root->type == map_node_type::unknown) + { + m_root->type = map_node_type::object; + m_root->value.children = m_node_children_pool.construct(); + } + + if (m_root->type != map_node_type::object) + throw path_error("root node was expected to be of type array, but is not."); + } + else + { + m_root = std::make_unique<node>(); + m_root->type = map_node_type::object; + m_root->value.children = m_node_children_pool.construct(); + } + + stack.node_stack.push_back(m_root.get()); + child_position_type pos = to_key_position(t.value.str.p, t.value.str.n); + node* p = &stack.node_stack.back()->get_or_create_child_node(pos); + stack.node_stack.push_back(p); + break; + } + case json_path_token_t::end: + { + if (!m_root) + { + m_root = std::make_unique<node>(); + m_root->type = map_node_type::unknown; + } + + stack.node_stack.push_back(m_root.get()); + return stack; + } + default: + // Something has gone wrong. Bail out. + stack.node_stack.clear(); + return stack; + } + + for (t = parser.next(); t.type != json_path_token_t::unknown; t = parser.next()) + { + token_stack.push_back(t); + node* cur_node = stack.node_stack.back(); + + switch (t.type) + { + case json_path_token_t::array_pos: + { + switch (cur_node->type) + { + case map_node_type::array: + // Do nothing. + break; + case map_node_type::unknown: + // Turn this node into an array node. + cur_node->type = map_node_type::array; + cur_node->value.children = m_node_children_pool.construct(); + break; + default: + throw_path_error(__FILE__, __LINE__, path); + } + node* p = &stack.node_stack.back()->get_or_create_child_node(t.value.array_pos); + stack.node_stack.push_back(p); + break; + } + case json_path_token_t::object_key: + { + switch (cur_node->type) + { + case map_node_type::object: + // Do nothing. + break; + case map_node_type::unknown: + // Turn this node into an object node. + cur_node->type = map_node_type::object; + cur_node->value.children = m_node_children_pool.construct(); + break; + default: + throw_path_error(__FILE__, __LINE__, path); + } + + // For an object children, we use the memory address of a + // pooled key string as its position. + child_position_type pos = to_key_position(t.value.str.p, t.value.str.n); + node* p = &stack.node_stack.back()->get_or_create_child_node(pos); + stack.node_stack.push_back(p); + break; + } + case json_path_token_t::end: + { + assert(token_stack.size() >= 2); + stack.dest_key = get_last_object_key(token_stack); + + return stack; + } + case json_path_token_t::unknown: + default: + // Something has gone wrong. Bail out. + break; + } + } + + // If this code path reaches here, something has gone wrong. + stack.node_stack.clear(); + return stack; +} + +json_map_tree::child_position_type json_map_tree::to_key_position(const char* p, size_t n) const +{ + std::string_view pooled_key = m_str_pool.intern({p, n}).first; + child_position_type pos = reinterpret_cast<child_position_type>(pooled_key.data()); + return pos; +} + +bool json_map_tree::is_equivalent(input_node_type input_node, map_node_type map_node) +{ + uint8_t left = (0x0F & uint8_t(input_node)); + uint8_t right = (0x0F & uint8_t(map_node)); + return left == right; +} + +std::ostream& operator<< (std::ostream& os, json_map_tree::input_node_type nt) +{ + os << "(input-node-type: "; + + switch (nt) + { + case json_map_tree::input_node_type::array: + os << "array"; + break; + case json_map_tree::input_node_type::object: + os << "object"; + break; + case json_map_tree::input_node_type::value: + os << "value"; + break; + case json_map_tree::input_node_type::unknown: + os << "unknown"; + break; + } + + os << ')'; + + return os; +} + +std::ostream& operator<< (std::ostream& os, json_map_tree::map_node_type nt) +{ + os << "(map-node-type: "; + + switch (nt) + { + case json_map_tree::map_node_type::array: + os << "array"; + break; + case json_map_tree::map_node_type::cell_ref: + os << "cell-ref"; + break; + case json_map_tree::map_node_type::object: + os << "object"; + break; + case json_map_tree::map_node_type::range_field_ref: + os << "range-field-ref"; + break; + case json_map_tree::map_node_type::unknown: + os << "unknown"; + break; + } + + os << ')'; + + return os; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/json_map_tree.hpp b/src/liborcus/json_map_tree.hpp new file mode 100644 index 0000000..9470af0 --- /dev/null +++ b/src/liborcus/json_map_tree.hpp @@ -0,0 +1,197 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "spreadsheet_impl_types.hpp" +#include "orcus/string_pool.hpp" +#include "orcus/exception.hpp" + +#include <boost/pool/object_pool.hpp> +#include <memory> +#include <map> +#include <vector> +#include <iosfwd> + +namespace orcus { + +using spreadsheet::detail::cell_position_t; + +class json_map_tree +{ +public: + using child_position_type = std::uintptr_t; + + static constexpr child_position_type node_child_default_position = -1; + + /** + * Error indicating improper path. + */ + class path_error : public general_error + { + public: + path_error(const std::string& msg); + }; + + struct node; + struct range_reference_type; + using node_children_type = std::map<child_position_type, node>; + using range_ref_store_type = std::map<cell_position_t, range_reference_type>; + + /** Types of nodes in the json input tree. */ + enum class input_node_type { unknown = 0x00, array = 0x01, object = 0x02, value = 0x04 }; + + /** + * Types of nodes in the map tree. The lower 4-bits specify the input + * node type which are kept in sync with the input_node_type values. The + * next 4-bits specify the link type. + */ + enum class map_node_type { unknown = 0x00, array = 0x01, object = 0x02, cell_ref = 0x14, range_field_ref = 0x24 }; + + struct cell_reference_type + { + cell_position_t pos; + + cell_reference_type(const cell_position_t& _pos); + }; + + struct range_field_reference_type; + + struct range_reference_type + { + cell_position_t pos; + std::vector<const range_field_reference_type*> fields; + spreadsheet::row_t row_position; + bool row_header; + + range_reference_type(const cell_position_t& _pos); + }; + + /** Represents a field within a range reference. */ + struct range_field_reference_type + { + range_reference_type* ref; + spreadsheet::col_t column_pos; + std::string_view label; + }; + + struct node + { + map_node_type type = map_node_type::unknown; + + union + { + node_children_type* children = nullptr; + cell_reference_type* cell_ref; + range_field_reference_type* range_field_ref; + + } value; + + /** + * The node is a row-group node (node that defines a row boundary) + * if this value is set to a non-null value. If this is not null, it + * points to the range_reference instance it belongs to. + */ + range_reference_type* row_group = nullptr; + + std::vector<node*> anchored_fields; + + node(const node&) = delete; + node& operator=(const node&) = delete; + + node(); + node(node&& other); + + node& get_or_create_child_node(child_position_type pos); + }; + + class walker + { + friend class json_map_tree; + + struct scope + { + node* p; + child_position_type array_position; + + scope(node* _p); + }; + + using stack_type = std::vector<scope>; + using unlinked_stack_type = std::vector<input_node_type>; + + const json_map_tree& m_parent; + stack_type m_stack; + unlinked_stack_type m_unlinked_stack; + + walker(const json_map_tree& parent); + public: + + node* push_node(input_node_type nt); + node* pop_node(input_node_type nt); + + void set_object_key(const char* p, size_t n); + }; + + json_map_tree(); + ~json_map_tree(); + + walker get_tree_walker() const; + + void set_cell_link(std::string_view path, const cell_position_t& pos); + + const node* get_link(std::string_view path) const; + + void start_range(const cell_position_t& pos, bool row_header); + void append_field_link(std::string_view path, std::string_view label); + void set_range_row_group(std::string_view path); + void commit_range(); + + range_ref_store_type& get_range_references(); + +private: + range_reference_type& get_range_reference(const cell_position_t& pos); + + const node* get_destination_node(std::string_view path) const; + + struct path_stack_type + { + std::vector<node*> node_stack; + std::string_view dest_key; //< object key associated with the destination value (if applicable) + }; + + path_stack_type get_or_create_destination_node(std::string_view path); + + child_position_type to_key_position(const char* p, size_t n) const; + + static bool is_equivalent(input_node_type input_node, map_node_type map_node); + +private: + boost::object_pool<node_children_type> m_node_children_pool; + boost::object_pool<cell_reference_type> m_cell_ref_pool; + boost::object_pool<range_field_reference_type> m_range_field_ref_pool; + + mutable string_pool m_str_pool; + + std::unique_ptr<node> m_root; + + range_ref_store_type m_range_refs; + + struct + { + cell_position_t pos; + std::vector<std::pair<std::string_view, std::string_view>> fields; // path, label + std::vector<std::string_view> row_groups; + bool row_header; + + } m_current_range; +}; + +std::ostream& operator<< (std::ostream& os, json_map_tree::input_node_type nt); +std::ostream& operator<< (std::ostream& os, json_map_tree::map_node_type nt); + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/json_map_tree_test.cpp b/src/liborcus/json_map_tree_test.cpp new file mode 100644 index 0000000..6100bd9 --- /dev/null +++ b/src/liborcus/json_map_tree_test.cpp @@ -0,0 +1,130 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "json_map_tree.hpp" + +#include <cassert> +#include <iostream> + +using namespace orcus; +using namespace std; + +void test_link_array_values() +{ + json_map_tree tree; + + cell_position_t pos("sheet", 0, 0); + + tree.set_cell_link("$[0]", pos); + pos.row = 1; + tree.set_cell_link("$[][0]", pos); + + const json_map_tree::node* p = tree.get_link("$[0]"); + assert(p); + assert(p->type == json_map_tree::map_node_type::cell_ref); + assert(p->value.cell_ref->pos == cell_position_t("sheet", 0, 0)); + + p = tree.get_link("$[][0]"); + assert(p); + assert(p->type == json_map_tree::map_node_type::cell_ref); + assert(p->value.cell_ref->pos == cell_position_t("sheet", 1, 0)); +} + +void test_link_object_values() +{ + struct entry + { + const char* path; + cell_position_t pos; + }; + + std::vector<entry> entries = + { + { "$[]['id']", cell_position_t("sheet", 2, 3) }, + { "$[]['name']", cell_position_t("sheet", 2, 4) }, + { "$[]['address']", cell_position_t("sheet", 2, 5) }, + }; + + json_map_tree tree; + + for (const entry& e : entries) + tree.set_cell_link(e.path, e.pos); + + for (const entry& e : entries) + { + const json_map_tree::node* p = tree.get_link(e.path); + assert(p); + assert(p->type == json_map_tree::map_node_type::cell_ref); + assert(e.pos == p->value.cell_ref->pos); + } +} + +void test_link_object_root() +{ + json_map_tree tree; + + const char* path = "$['root'][2]"; + cell_position_t pos("sheet", 3, 4); + tree.set_cell_link(path, pos); + + const json_map_tree::node* p = tree.get_link(path); + assert(p); + assert(p->type == json_map_tree::map_node_type::cell_ref); + assert(p->value.cell_ref->pos == pos); +} + +void test_link_range_fields() +{ + json_map_tree tree; + + cell_position_t pos("sheet", 1, 2); + + tree.start_range(pos, false); + tree.append_field_link("$[][0]", std::string_view{}); + tree.append_field_link("$[][1]", std::string_view{}); + tree.append_field_link("$[][2]", std::string_view{}); + tree.set_range_row_group("$[]"); + tree.commit_range(); + + const json_map_tree::node* p = tree.get_link("$[][0]"); + assert(p); + assert(p->type == json_map_tree::map_node_type::range_field_ref); + assert(p->value.range_field_ref->column_pos == 0); + + p = tree.get_link("$[][1]"); + assert(p); + assert(p->type == json_map_tree::map_node_type::range_field_ref); + assert(p->value.range_field_ref->column_pos == 1); + + p = tree.get_link("$[][2]"); + assert(p); + assert(p->type == json_map_tree::map_node_type::range_field_ref); + assert(p->value.range_field_ref->column_pos == 2); + + // Check the range reference data itself. + const json_map_tree::range_reference_type* ref = p->value.range_field_ref->ref; + assert(ref->fields.size() == 3); + assert(ref->pos == pos); + + // Make sure the row group is set. + p = tree.get_link("$[]"); + assert(p); + assert(p->type == json_map_tree::map_node_type::array); + assert(p->row_group == ref); +} + +int main() +{ + test_link_array_values(); + test_link_object_values(); + test_link_object_root(); + test_link_range_fields(); + + return EXIT_SUCCESS; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/json_structure_mapper.cpp b/src/liborcus/json_structure_mapper.cpp new file mode 100644 index 0000000..09a9e97 --- /dev/null +++ b/src/liborcus/json_structure_mapper.cpp @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "json_structure_mapper.hpp" + +#include <algorithm> +#include <sstream> +#include <cassert> + +namespace orcus { namespace json { namespace detail { + +structure_mapper::structure_mapper(structure_tree::range_handler_type rh, const json::structure_tree::walker& walker) : + m_walker(walker), + m_range_handler(std::move(rh)), + m_repeat_count(0) {} + +void structure_mapper::run() +{ + reset(); + traverse(0); +} + +void structure_mapper::reset() +{ + m_walker.root(); + m_current_range.paths.clear(); + m_current_range.row_groups.clear(); + m_repeat_count = 0; +} + +void structure_mapper::push_range() +{ + m_range_handler(std::move(m_current_range)); + + m_current_range.paths.clear(); + m_current_range.row_groups.clear(); +} + +void structure_mapper::traverse(size_t /*pos*/) +{ + json::structure_tree::node_properties node = m_walker.get_node(); + + if (node.repeat) + { + ++m_repeat_count; + m_current_range.row_groups.push_back(m_walker.build_row_group_path()); + } + + if (m_repeat_count && node.type == json::structure_tree::node_type::value) + { + for (std::string path : m_walker.build_field_paths()) + m_current_range.paths.push_back(std::move(path)); + } + + for (size_t i = 0, n = m_walker.child_count(); i < n; ++i) + { + m_walker.descend(i); + traverse(i); + m_walker.ascend(); + } + + if (node.repeat) + { + --m_repeat_count; + + if (!m_repeat_count) + push_range(); + } +} + +}}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/json_structure_mapper.hpp b/src/liborcus/json_structure_mapper.hpp new file mode 100644 index 0000000..6dfdd08 --- /dev/null +++ b/src/liborcus/json_structure_mapper.hpp @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/json_structure_tree.hpp" + +#include <vector> +#include <functional> + +namespace orcus { namespace json { namespace detail { + +class structure_mapper +{ +public: + structure_mapper(json::structure_tree::range_handler_type rh, const json::structure_tree::walker& walker); + + void run(); + +private: + void reset(); + void push_range(); + void traverse(size_t pos); + +private: + json::structure_tree::walker m_walker; + json::structure_tree::range_handler_type m_range_handler; + size_t m_repeat_count; + json::table_range_t m_current_range; + +}; + +}}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/json_structure_tree.cpp b/src/liborcus/json_structure_tree.cpp new file mode 100644 index 0000000..862b4de --- /dev/null +++ b/src/liborcus/json_structure_tree.cpp @@ -0,0 +1,720 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/json_structure_tree.hpp> +#include <orcus/json_parser.hpp> +#include <orcus/string_pool.hpp> + +#include "json_structure_mapper.hpp" + +#include <vector> +#include <memory> +#include <algorithm> +#include <map> +#include <functional> + +#include <boost/pool/object_pool.hpp> + +namespace orcus { namespace json { + +namespace { + +struct structure_node; + +using node_children_type = std::vector<structure_node*>; +using node_type = structure_tree::node_type; +using array_positions_type = std::map<int32_t, bool>; + +/** + * Only pick those array positions that are marked "valid" - the associated + * boolean value is true. + */ +std::vector<int32_t> to_valid_array_positions(const array_positions_type& array_positions) +{ + std::vector<int32_t> aps; + + for (const auto& e : array_positions) + { + if (e.second) + aps.push_back(e.first); + } + + return aps; +} + +/** + * Represents a node inside a JSON structure tree. + */ +struct structure_node +{ + bool repeat = false; + + node_type type = node_type::unknown; + + node_children_type children; + + /** + * The number of child nodes in the source data tree, not to be confused + * with the number of child nodes in the structure tree. + */ + int32_t child_count = 0; + + std::string_view name; //< value of a key for a object key node. + + /** + * For a value node that is an immediate child of an array node, these + * positions are the positions of the parent array that values always + * occur in the source data tree. + */ + array_positions_type array_positions; + + structure_node(node_type _type) : type(_type) {} + + bool operator== (const structure_node& other) const + { + if (type != other.type) + return false; + + if (type != node_type::object_key) + return true; + + return name == other.name; + } + + bool operator< (const structure_node& other) const + { + if (type != other.type) + return type < other.type; + + if (name != other.name) + return name < other.name; + + return true; + } +}; + +struct parse_scope +{ + structure_node& node; + + int32_t child_count = 0; + + parse_scope(structure_node& _node) : node(_node) {} +}; + +using parse_scopes_type = std::vector<parse_scope>; + +/** + * Represents a scope during structure tree traversal. + */ +struct scope +{ + const structure_node& node; + node_children_type::const_iterator current_pos; + + scope(const structure_node& _node) : + node(_node), + current_pos(node.children.begin()) {} +}; + +using scope_stack_type = std::vector<scope>; + +void print_scope(std::ostream& os, const scope& s) +{ + switch (s.node.type) + { + case node_type::array: + os << "array"; + break; + case node_type::object: + os << "object"; + break; + case node_type::object_key: + os << "['" << s.node.name << "']"; + break; + default: + os << "???"; + } + + if (s.node.repeat) + os << "(*)"; + + if (s.node.type == node_type::array && s.node.child_count) + os << '[' << s.node.child_count << ']'; +} + +void print_scopes(std::ostream& os, const scope_stack_type& scopes) +{ + auto it = scopes.cbegin(); + auto ite = scopes.cend(); + + os << '$'; + print_scope(os, *it); + + for (++it; it != ite; ++it) + { + if (it->node.type != node_type::object_key) + os << '.'; + print_scope(os, *it); + } +} + +structure_tree::node_properties to_node_properties(const structure_node& sn) +{ + structure_tree::node_properties np; + np.type = sn.type; + np.repeat = sn.repeat; + return np; +} + +} // anonymous namespace + +struct structure_tree::impl +{ + boost::object_pool<structure_node> m_node_store; + structure_node* m_root; + parse_scopes_type m_stack; + string_pool m_pool; + + impl() : m_root(nullptr) {} + ~impl() {} + + void begin_parse() {} + + void end_parse() {} + + void begin_array() + { + push_stack(node_type::array); + } + + void end_array() + { + pop_stack(); + } + + void begin_object() + { + push_stack(node_type::object); + } + + void object_key(std::string_view key, bool transient) + { + structure_node node(node_type::object_key); + node.name = key; + + if (transient) + node.name = m_pool.intern(node.name).first; + + push_stack(node); + } + + void end_object() + { + pop_stack(); + } + + void boolean_true() + { + push_value(); + } + + void boolean_false() + { + push_value(); + } + + void null() + { + push_value(); + } + + void string(std::string_view /*val*/, bool /*transient*/) + { + push_value(); + } + + void number(double /*val*/) + { + push_value(); + } + + void normalize_tree() + { + if (!m_root) + return; + + std::function<void(structure_node&)> descend = [&descend](structure_node& node) + { + if (node.children.empty()) + return; + + // Sort all children. + std::sort(node.children.begin(), node.children.end(), + [](const structure_node* left, const structure_node* right) -> bool + { + return *left < *right; + } + ); + + for (structure_node* child : node.children) + descend(*child); + }; + + descend(*m_root); + } + + void dump_compact(std::ostream& os) const + { + if (!m_root) + return; + + scope_stack_type scopes; + scopes.emplace_back(*m_root); + + while (!scopes.empty()) + { + scope& cur_scope = scopes.back(); + + bool new_scope = false; + + for (; cur_scope.current_pos != cur_scope.node.children.end(); ++cur_scope.current_pos) + { + const structure_node& cur_node = **cur_scope.current_pos; + + if (cur_node.type == node_type::value) + { + assert(cur_node.children.empty()); + + // Print all its parent scopes. + print_scopes(os, scopes); + + // Print the value node at the end. + os << ".value"; + + // Print array positions if applicable. + std::vector<int32_t> aps = to_valid_array_positions(cur_node.array_positions); + + if (!aps.empty()) + { + os << '['; + auto it = aps.cbegin(); + os << *it; + for (++it; it != aps.cend(); ++it) + os << ',' << *it; + os << ']'; + } + + os << std::endl; + continue; + } + + if (cur_node.children.empty()) + continue; + + // This node has child nodes. Push a new scope and trigger a new inner loop. + + ++cur_scope.current_pos; // Don't forget to move to the next sibling for when we return to this scope. + scopes.emplace_back(cur_node); + new_scope = true; + break; + } + + if (new_scope) + continue; + + scopes.pop_back(); + } + } + +private: + + parse_scope& get_current_scope() + { + assert(!m_stack.empty()); + return m_stack.back(); + } + + bool is_node_repeatable(const structure_node& node) const + { + const structure_node& cur = m_stack.back().node; + + if (cur.type != node_type::array) + return false; + + return node.type == node_type::array || node.type == node_type::object; + } + + void push_stack(const structure_node& node) + { + if (!m_root) + { + // This is the very first node. + assert(node.type != node_type::object_key); + m_root = m_node_store.construct(node.type); + m_stack.emplace_back(*m_root); + return; + } + + parse_scope& cur_scope = get_current_scope(); + structure_node& cur_node = cur_scope.node; + + // Record the position of this new child in case the parent is an + // array and the new node is a value node. + + int32_t array_pos = -1; + + if (cur_node.type == node_type::array) + { + array_pos = cur_scope.child_count; + + if (node.type != node_type::value) + { + // See if this array has a child value node. + auto it = std::find_if( + cur_node.children.begin(), cur_node.children.end(), + [](const structure_node* p) -> bool { return p->type == node_type::value; } + ); + + if (it != cur_node.children.end()) + { + // It has a child value node. See if this value node has + // this array position recorded. If yes, turn it off + // since this position is not always a value. + array_positions_type& aps = (*it)->array_positions; + auto it_array_pos = aps.find(array_pos); + if (it_array_pos != aps.end()) + it_array_pos->second = false; + } + + array_pos = -1; + } + } + + ++cur_scope.child_count; + + { + // See if the current node has a child node of the specified type. + auto it = std::find_if(cur_node.children.begin(), cur_node.children.end(), + [&node](const structure_node* p) -> bool + { + return *p == node; + } + ); + + if (it == cur_node.children.end()) + { + // current node doesn't have a child of specified type. Add one. + cur_node.children.push_back(m_node_store.construct(node)); + m_stack.emplace_back(*cur_node.children.back()); + } + else + { + // current node does have a child of specified type. + bool repeat = is_node_repeatable(node); + structure_node& child = **it; + child.repeat = repeat; + m_stack.emplace_back(child); + } + } + + if (array_pos >= 0) + { + array_positions_type& aps = m_stack.back().node.array_positions; + int32_t min_pos = aps.empty() ? 0 : aps.begin()->first; + if (array_pos >= min_pos) + { + auto it = aps.lower_bound(array_pos); + + if (it == aps.end() || aps.key_comp()(array_pos, it->first)) + { + // Insert a new array child node of unspecified type at the specified position. + aps.insert( + it, array_positions_type::value_type(array_pos, true)); + } + } + } + } + + void push_value() + { + push_stack(node_type::value); + pop_stack(); + } + + void pop_stack() + { + parse_scope& cur_scope = get_current_scope(); + structure_node& cur_node = cur_scope.node; + if (cur_scope.child_count > cur_node.child_count) + cur_node.child_count = cur_scope.child_count; + + m_stack.pop_back(); + + if (!m_stack.empty() && get_current_scope().node.type == node_type::object_key) + // Object key is a special non-leaf node that can only have one child. + m_stack.pop_back(); + } +}; + +struct structure_tree::walker::impl +{ + using stack_type = std::vector<const structure_node*>; + + const structure_tree::impl* parent_impl; + + stack_type stack; + + impl() : parent_impl(nullptr) {} + + impl(const structure_tree::impl* _parent_impl) : parent_impl(_parent_impl) {} + + impl(const structure_tree::walker::impl& other) : + parent_impl(other.parent_impl) {} + + void check_tree() + { + if (!parent_impl) + throw json_structure_error( + "This walker is not associated with any json_structure_tree instance."); + + if (!parent_impl->m_root) + throw json_structure_error("Empty tree."); + } + + void check_stack() + { + check_tree(); + + if (stack.empty()) + throw json_structure_error( + "Walker stack is empty. Most likely caused by not calling root() to start the traversal."); + } +}; + +structure_tree::walker::walker() : mp_impl(std::make_unique<impl>()) {} +structure_tree::walker::walker(const walker& other) : mp_impl(std::make_unique<impl>(*other.mp_impl)) {} +structure_tree::walker::walker(const structure_tree::impl* parent_impl) : mp_impl(std::make_unique<impl>(parent_impl)) {} +structure_tree::walker::~walker() {} + +void structure_tree::walker::root() +{ + mp_impl->check_tree(); + + mp_impl->stack.clear(); + mp_impl->stack.push_back(mp_impl->parent_impl->m_root); +} + +void structure_tree::walker::descend(size_t child_pos) +{ + mp_impl->check_stack(); + assert(!mp_impl->stack.empty()); + + const structure_node* p = mp_impl->stack.back(); + assert(p); + + if (child_pos >= p->children.size()) + { + std::ostringstream os; + os << "Specified child position of " << child_pos << " exceeds the child count of " << p->children.size() << '.'; + throw json_structure_error(os.str()); + } + + p = p->children[child_pos]; + assert(p); + mp_impl->stack.push_back(p); +} + +void structure_tree::walker::ascend() +{ + mp_impl->check_stack(); + assert(!mp_impl->stack.empty()); + + if (mp_impl->stack.size() == 1u) + throw json_structure_error("You cannot ascend from the root node."); + + mp_impl->stack.pop_back(); +} + +size_t structure_tree::walker::child_count() const +{ + mp_impl->check_stack(); + assert(!mp_impl->stack.empty()); + + const structure_node* p = mp_impl->stack.back(); + return p->children.size(); +} + +structure_tree::node_properties structure_tree::walker::get_node() const +{ + mp_impl->check_stack(); + assert(!mp_impl->stack.empty()); + + const structure_node* p = mp_impl->stack.back(); + assert(p); + return to_node_properties(*p); +} + +std::vector<std::string> structure_tree::walker::build_field_paths() const +{ + mp_impl->check_stack(); + assert(!mp_impl->stack.empty()); + + if (mp_impl->stack.empty() || mp_impl->stack.back()->type != node_type::value) + throw json_structure_error("You can only build field paths to value node."); + + std::ostringstream os; + os << '$'; + + auto it = mp_impl->stack.cbegin(), ite = mp_impl->stack.cend(); + + const structure_node* p = nullptr; + const structure_node* p_prev = *it; + + for (++it; it != ite; ++it, p_prev = p) + { + p = *it; + + switch (p_prev->type) + { + case structure_tree::node_type::array: + if (p->type != structure_tree::node_type::value) + os << "[]"; + break; + case structure_tree::node_type::object_key: + os << "['" << p_prev->name << "']"; + break; + default: + ; + } + } + + if (p_prev->type == structure_tree::node_type::value && !p->array_positions.empty()) + { + // non-empty array positions implies that the parent is an array. + std::vector<int32_t> aps = to_valid_array_positions(p->array_positions); + if (!aps.empty()) + { + std::vector<std::string> ret; + std::string base = os.str(); + for (int32_t ap : aps) + { + std::ostringstream path; + path << base << '[' << ap << ']'; + ret.push_back(path.str()); + } + + return ret; + } + } + + return std::vector<std::string>(1u, os.str()); +} + +std::string structure_tree::walker::build_row_group_path() const +{ + mp_impl->check_stack(); + + if (mp_impl->stack.size() < 2u) + throw json_structure_error("Current node is root - it doesn't have a parent."); + + if (!mp_impl->stack.back()->repeat) + throw json_structure_error( + "Current node is not a repeating node. Only the parent node of a repeating node can be a row group."); + + { + auto it = mp_impl->stack.crbegin(); + ++it; + if ((*it)->type != structure_tree::node_type::array) + throw json_structure_error( + "Parent node of the current node is not of array type, but it should be."); + } + + std::ostringstream os; + os << '$'; + + auto it = mp_impl->stack.cbegin(), ite = mp_impl->stack.cend(); + ite -= 2; // jump to the parent node, and we don't include the last node in the path output. + + for (; it != ite; ++it) + { + const structure_node* p = *it; + + switch (p->type) + { + case structure_tree::node_type::array: + os << "[]"; + break; + case structure_tree::node_type::object_key: + os << "['" << p->name << "']"; + break; + default: + ; + } + } + + return os.str(); +} + +structure_tree::structure_tree() : mp_impl(std::make_unique<impl>()) {} +structure_tree::~structure_tree() {} + +void structure_tree::parse(std::string_view stream) +{ + json_parser<impl> parser(stream, *mp_impl); + parser.parse(); +} + +void structure_tree::normalize_tree() +{ + mp_impl->normalize_tree(); +} + +void structure_tree::dump_compact(std::ostream& os) const +{ + mp_impl->dump_compact(os); +} + +structure_tree::walker structure_tree::get_walker() const +{ + return walker(mp_impl.get()); +} + +void structure_tree::process_ranges(range_handler_type rh) const +{ + detail::structure_mapper mapper(rh, get_walker()); + mapper.run(); +} + +std::ostream& operator<< (std::ostream& os, structure_tree::node_type nt) +{ + + switch (nt) + { + case structure_tree::node_type::array: + os << "structure_tree::node_type::array"; + break; + case structure_tree::node_type::object: + os << "structure_tree::node_type::object"; + break; + case structure_tree::node_type::object_key: + os << "structure_tree::node_type::object_key"; + break; + case structure_tree::node_type::unknown: + os << "structure_tree::node_type::unknown"; + break; + case structure_tree::node_type::value: + os << "structure_tree::node_type::value"; + break; + } + + return os; +} + +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/json_structure_tree_test.cpp b/src/liborcus/json_structure_tree_test.cpp new file mode 100644 index 0000000..60a0598 --- /dev/null +++ b/src/liborcus/json_structure_tree_test.cpp @@ -0,0 +1,201 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/json_structure_tree.hpp> +#include <orcus/stream.hpp> +#include <orcus/parser_global.hpp> +#include "filesystem_env.hpp" + +#include <vector> +#include <sstream> +#include <cassert> +#include <unordered_set> + +using namespace orcus; + +std::vector<const char*> base_dirs = { + SRCDIR"/test/json-structure/arrays-in-object/", + SRCDIR"/test/json-structure/nested-arrays/", + SRCDIR"/test/json-structure/nested-arrays-mixed/", + SRCDIR"/test/json-structure/nested-arrays-mixed-2/", + SRCDIR"/test/json-structure/repeat-objects/", + SRCDIR"/test/json-structure/repeat-objects-2/", + SRCDIR"/test/json-structure/multiple-ranges/", +}; + +/** + * All json contents under this directory have no value nodes. Since the + * structure output of a JSON content only dumps value nodes, the output + * string should be empty when the source content does not have any value + * nodes. + */ +void test_no_value_nodes() +{ + fs::path base_dir(SRCDIR"/test/json-structure/no-value-nodes"); + + for (const fs::path& p : fs::directory_iterator(base_dir)) + { + if (!fs::is_regular_file(p)) + continue; + + if (p.extension().string() != ".json") + continue; + + file_content strm(p.string().data()); + json::structure_tree tree; + tree.parse(strm.str()); + tree.normalize_tree(); + std::ostringstream os; + tree.dump_compact(os); + + assert(os.str().empty()); + } +} + +void test_basic() +{ + for (const char* base_dir : base_dirs) + { + std::string filepath(base_dir); + filepath.append("input.json"); + + file_content strm(filepath.data()); + assert(!strm.empty()); + json::structure_tree tree; + tree.parse(strm.str()); + tree.normalize_tree(); + std::ostringstream os; + tree.dump_compact(os); + std::string data_content = os.str(); + + // Check the dump content against known datum. + filepath = base_dir; + filepath.append("check.txt"); + file_content strm_check(filepath.data()); + assert(!strm_check.empty()); + + // They should be identical, plus or minus leading/trailing whitespaces. + std::string_view s1(data_content.data(), data_content.size()); + std::string_view s2 = strm_check.str(); + assert(trim(s1) == trim(s2)); + } +} + +void test_automatic_range_detection() +{ + using detected_group_type = std::unordered_set<std::string>; + using detected_groups_type = std::vector<detected_group_type>; + + struct check + { + fs::path filepath; + detected_groups_type expected_groups; + }; + + std::vector<check> checks = + { + { + SRCDIR"/test/json-structure/arrays-in-object/input.json", + { + { + "row-group:$['rows']", + "path:$['rows'][]['name']", + "path:$['rows'][]['age']", + "path:$['rows'][]['error']", + } + } + }, + { + SRCDIR"/test/json-structure/repeat-objects/input.json", + { + { + "path:$[]['name']", + "path:$[]['age']", + "row-group:$", + } + } + }, + { + SRCDIR"/test/json-structure/repeat-objects-2/input.json", + { + { + "path:$[]['name']", + "path:$[]['age']", + "path:$[]['props']['alpha']", + "path:$[]['props']['beta']", + "path:$[]['props']['gamma']", + "path:$[]['props']['theta']", + "row-group:$", + } + } + }, + { + SRCDIR"/test/json-structure/multiple-ranges/input.json", + { + { + "path:$['data'][]['category']", + "path:$['data'][]['region']", + "path:$['data'][]['records'][]['id']", + "path:$['data'][]['records'][]['ref']", + "row-group:$['data']", + "row-group:$['data'][]['records']", + }, + { + "path:$['misc'][][0]", + "path:$['misc'][][1]", + "path:$['misc'][][2]", + "row-group:$['misc']", + } + } + }, + }; + + for (const check& c : checks) + { + file_content strm(c.filepath.string().data()); + assert(!strm.empty()); + json::structure_tree tree; + tree.parse(strm.str()); + + detected_groups_type observed_groups; + + json::structure_tree::range_handler_type rh = [&observed_groups](json::table_range_t&& range) + { + detected_group_type observed; + for (const std::string& s : range.row_groups) + { + std::ostringstream os; + os << "row-group:" << s; + observed.insert(os.str()); + } + + for (const std::string& s : range.paths) + { + std::ostringstream os; + os << "path:" << s; + observed.insert(os.str()); + } + + observed_groups.push_back(std::move(observed)); + }; + + tree.process_ranges(rh); + + assert(observed_groups == c.expected_groups); + } +} + +int main() +{ + test_no_value_nodes(); + test_basic(); + test_automatic_range_detection(); + + return EXIT_SUCCESS; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/json_util.cpp b/src/liborcus/json_util.cpp new file mode 100644 index 0000000..b031cbe --- /dev/null +++ b/src/liborcus/json_util.cpp @@ -0,0 +1,27 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/json_global.hpp" + +#include <sstream> + +namespace orcus { namespace json { + +namespace { + +const char quote = '"'; + +} + +void dump_string(std::ostringstream& os, const std::string& s) +{ + os << quote << escape_string(s) << quote; +} + +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/json_util.hpp b/src/liborcus/json_util.hpp new file mode 100644 index 0000000..00917a2 --- /dev/null +++ b/src/liborcus/json_util.hpp @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_JSON_UTIL_HPP +#define INCLUDED_ORCUS_JSON_UTIL_HPP + +#include <sstream> + +namespace orcus { namespace json { + +void dump_string(std::ostringstream& os, const std::string& s); + +}} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/measurement.cpp b/src/liborcus/measurement.cpp new file mode 100644 index 0000000..f034595 --- /dev/null +++ b/src/liborcus/measurement.cpp @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/measurement.hpp> +#include <orcus/exception.hpp> +#include <orcus/parser_global.hpp> + +#include <mdds/sorted_string_map.hpp> +#include <mdds/global.hpp> + +#include <sstream> + +namespace orcus { + +double to_double(std::string_view s, const char** p_parse_ended) +{ + const char* p = s.data(); + double value; + const char* p_last = parse_numeric(p, p + s.size(), value); + if (p_parse_ended) + *p_parse_ended = p_last; + + return value; +} + +long to_long(std::string_view s, const char** p_parse_ended) +{ + long value; + const char* p_last = parse_integer(s.data(), s.data() + s.size(), value); + if (p_parse_ended) + *p_parse_ended = p_last; + + return value; +} + +bool to_bool(std::string_view s) +{ + size_t n = s.size(); + if (n == 1) + // Any single char other than '0' is true. + return s[0] != '0'; + + return s == "true" || s == "TRUE"; +} + +namespace { + +namespace length { + +using map_type = mdds::sorted_string_map<length_unit_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = +{ + { "cm", length_unit_t::centimeter }, + { "in", length_unit_t::inch }, + { "mm", length_unit_t::millimeter }, + { "pt", length_unit_t::point }, + { "px", length_unit_t::pixel } +}; + +const map_type& get() +{ + static map_type mt(entries, std::size(entries), length_unit_t::unknown); + return mt; +} + +} // namespace length + +} // anonymous namespace + +length_t to_length(std::string_view str) +{ + length_t ret; + if (str.empty()) + return ret; + + const char* p = str.data(); + const char* p_start = p; + const char* p_end = p_start + str.size(); + p = parse_numeric(p, p_end, ret.value); + + std::string_view tail(p, p_end-p); + ret.unit = length::get().find(tail); + + return ret; +} + +namespace { + +double convert_inch(double value, length_unit_t unit_to) +{ + switch (unit_to) + { + case length_unit_t::twip: + // inches to twips : 1 twip = 1/1440 inches + return value * 1440.0; + default: + ; + } + + throw general_error("convert_inch: unsupported unit of measurement."); +} + +double convert_point(double value, length_unit_t unit_to) +{ + switch (unit_to) + { + case length_unit_t::twip: + // 20 twips = 1 point + return value * 20.0; + default: + ; + } + + throw general_error("convert_point: unsupported unit of measurement."); +} + +double convert_centimeter(double value, length_unit_t unit_to) +{ + switch (unit_to) + { + case length_unit_t::twip: + // centimeters to twips : 2.54 cm = 1 inch = 1440 twips + return value / 2.54 * 1440.0; + default: + ; + } + + throw general_error("convert_centimeter: unsupported unit of measurement."); +} + +double convert_millimeter(double value, length_unit_t unit_to) +{ + switch (unit_to) + { + case length_unit_t::twip: + // millimeters to twips : 25.4 mm = 1 inch = 1440 twips + return value / 25.4 * 1440.0; + default: + ; + } + + throw general_error("convert_millimeter: unsupported unit of measurement."); +} + +double convert_twip(double value, length_unit_t unit_to) +{ + switch (unit_to) + { + case length_unit_t::inch: + // twips to inches : 1 twip = 1/1440 inches + return value / 1440.0; + case length_unit_t::point: + // 1 twip = 1/1440 inches = 72/1440 points = 1/20 points + return value / 20.0; + default: + ; + } + throw general_error("convert_twip: unsupported unit of measurement."); +} + +/** + * Since Excel's column width is based on the maximum digit width of font + * used as the "Normal" style font, it's impossible to convert it accurately + * without the font information. + */ +double convert_xlsx_column_digit(double value, length_unit_t unit_to) +{ + // Convert to centimeters first. Here, we'll just assume that a single + // digit always equals 1.9 millimeters. TODO: find a better way to convert + // this. + value *= 0.19; + return convert_centimeter(value, unit_to); +} + +} + +double convert(double value, length_unit_t unit_from, length_unit_t unit_to) +{ + if (value == 0.0) + return value; + + switch (unit_from) + { + case length_unit_t::point: + return convert_point(value, unit_to); + case length_unit_t::inch: + return convert_inch(value, unit_to); + case length_unit_t::centimeter: + return convert_centimeter(value, unit_to); + case length_unit_t::millimeter: + return convert_millimeter(value, unit_to); + case length_unit_t::twip: + return convert_twip(value, unit_to); + case length_unit_t::xlsx_column_digit: + return convert_xlsx_column_digit(value, unit_to); + default: + ; + } + + std::ostringstream os; + os << "convert: unsupported unit of measurement (from " + << static_cast<int>(unit_from) << " to " + << static_cast<int>(unit_to) << ") (value=" << value << ")"; + throw general_error(os.str()); +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/number_utils.cpp b/src/liborcus/number_utils.cpp new file mode 100644 index 0000000..8e669ae --- /dev/null +++ b/src/liborcus/number_utils.cpp @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "number_utils.hpp" + +namespace orcus { + +namespace { + +std::optional<std::uint8_t> char_to_uint8(char c) +{ + std::uint8_t v; + if ('0' <= c && c <= '9') + { + v = c - '0'; + return v; + } + + if ('A' <= c && c <= 'F') + { + v = c - 'A' + 10; + return v; + } + + if ('a' <= c && c <= 'f') + { + v = c - 'a' + 10; + return v; + } + + return {}; +} + +template<typename IntT> +std::optional<IntT> hex_to_uint(std::string_view s) +{ + static_assert(std::is_integral_v<IntT>); + + constexpr std::size_t expected_len = sizeof(IntT) * 2u; + if (s.size() > expected_len) + return {}; + + IntT value = 0; + for (char c : s) + { + value = value << 4; + auto v = char_to_uint8(c); + if (!v) + return {}; + value += *v; + } + + return value; +} + +} // anonymous namespace + +std::optional<std::uint8_t> hex_to_uint8(std::string_view s) +{ + return hex_to_uint<std::uint8_t>(s); +} + +std::optional<std::uint16_t> hex_to_uint16(std::string_view s) +{ + return hex_to_uint<std::uint16_t>(s); +} + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/number_utils.hpp b/src/liborcus/number_utils.hpp new file mode 100644 index 0000000..acb4c3a --- /dev/null +++ b/src/liborcus/number_utils.hpp @@ -0,0 +1,22 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <string_view> +#include <optional> +#include <cstdint> + +namespace orcus { + +std::optional<std::uint8_t> hex_to_uint8(std::string_view s); + +std::optional<std::uint16_t> hex_to_uint16(std::string_view s); + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_document_styles_context.cpp b/src/liborcus/odf_document_styles_context.cpp new file mode 100644 index 0000000..957e55f --- /dev/null +++ b/src/liborcus/odf_document_styles_context.cpp @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "odf_document_styles_context.hpp" +#include "odf_token_constants.hpp" +#include "odf_namespace_types.hpp" + +#include <orcus/spreadsheet/import_interface_styles.hpp> + +#include <iostream> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +document_styles_context::document_styles_context(session_context& session_cxt, const tokens& tk, odf_styles_map_type& styles_map, ss::iface::import_styles* xstyles) : + xml_context_base(session_cxt, tk), + m_styles_map(styles_map), + mp_styles(xstyles), + m_cxt_styles(session_cxt, tk, xstyles) +{ + register_child(&m_cxt_styles); +} + +xml_context_base* document_styles_context::create_child_context(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_odf_office && name == XML_styles) + { + m_cxt_styles.reset(); + return &m_cxt_styles; + } + + return nullptr; +} + +void document_styles_context::end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) +{ + if (ns == NS_odf_office && name == XML_styles) + { + assert(child == &m_cxt_styles); + auto new_styles = m_cxt_styles.pop_styles(); + merge(m_styles_map, new_styles); + assert(new_styles.empty()); + } +} + +void document_styles_context::start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) +{ + auto parent = push_stack(ns, name); + (void)parent; + + (void)attrs; + + warn_unhandled(); +} + +bool document_styles_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + return pop_stack(ns, name); +} + +void document_styles_context::characters(std::string_view /*str*/, bool /*transient*/) +{ +} + + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_document_styles_context.hpp b/src/liborcus/odf_document_styles_context.hpp new file mode 100644 index 0000000..4deecb5 --- /dev/null +++ b/src/liborcus/odf_document_styles_context.hpp @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "xml_context_base.hpp" +#include "odf_styles.hpp" +#include "odf_styles_context.hpp" + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_styles; + +}} + +/** + * Context that handles the <office:document-styles> element scope. + * + * <office:document-styles> is the root element of styles.xml stream inside an + * ODF document. + */ +class document_styles_context : public xml_context_base +{ +public: + document_styles_context( + session_context& session_cxt, const tokens& tk, + odf_styles_map_type& styles_map, spreadsheet::iface::import_styles* xstyles); + + xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name) override; + void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) override; + void start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) override; + bool end_element(xmlns_id_t ns, xml_token_t name) override; + void characters(std::string_view str, bool transient) override; + +private: + odf_styles_map_type& m_styles_map; + spreadsheet::iface::import_styles* mp_styles = nullptr; + + styles_context m_cxt_styles; +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_helper.cpp b/src/liborcus/odf_helper.cpp new file mode 100644 index 0000000..7198b74 --- /dev/null +++ b/src/liborcus/odf_helper.cpp @@ -0,0 +1,260 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "odf_helper.hpp" +#include "string_helper.hpp" +#include <orcus/spreadsheet/types.hpp> +#include <orcus/measurement.hpp> +#include <mdds/sorted_string_map.hpp> +#include <mdds/global.hpp> +#include <orcus/spreadsheet/styles.hpp> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace { + +namespace border_style { + +using map_type = mdds::sorted_string_map<spreadsheet::border_style_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = +{ + { "dash-dot", spreadsheet::border_style_t::dash_dot }, + { "dash-dot-dot", spreadsheet::border_style_t::dash_dot_dot }, + { "dashed", spreadsheet::border_style_t::dashed }, + { "dotted", spreadsheet::border_style_t::dotted }, + { "double-thin", spreadsheet::border_style_t::double_thin }, + { "fine-dashed", spreadsheet::border_style_t::fine_dashed }, + { "none", spreadsheet::border_style_t::none }, + { "solid", spreadsheet::border_style_t::solid }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::border_style_t::unknown); + return mt; +} + +} // namespace border_style + +namespace underline_width { + +using map_type = mdds::sorted_string_map<spreadsheet::underline_width_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = +{ + { "auto", ss::underline_width_t::automatic }, + { "bold", ss::underline_width_t::bold }, + { "dash", ss::underline_width_t::dash }, + { "medium", ss::underline_width_t::medium }, + { "thick", ss::underline_width_t::thick }, + { "thin", ss::underline_width_t::thin }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::underline_width_t::none); + return mt; +} + +} // namespace underline_width + +namespace underline_style { + +using map_type = mdds::sorted_string_map<ss::underline_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = +{ + { "dash", ss::underline_t::dash }, + { "dot-dash", ss::underline_t::dot_dash }, + { "dot-dot-dash", ss::underline_t::dot_dot_dash }, + { "dotted", ss::underline_t::dotted }, + { "long-dash", ss::underline_t::long_dash }, + { "none", ss::underline_t::none }, + { "solid", ss::underline_t::single_line }, + { "wave", ss::underline_t::wave } +}; + +const map_type& get() +{ + static map_type mt(entries, std::size(entries), ss::underline_t::none); + return mt; +} + +} // namespace underline_style + +namespace hor_align { + +using map_type = mdds::sorted_string_map<spreadsheet::hor_alignment_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = +{ + { "center", spreadsheet::hor_alignment_t::center }, + { "end", spreadsheet::hor_alignment_t::right }, + { "justified", spreadsheet::hor_alignment_t::justified }, + { "start", spreadsheet::hor_alignment_t::left } +}; + +const map_type& get() +{ + static map_type mt(entries, std::size(entries), ss::hor_alignment_t::unknown); + return mt; +} + +} // namespace hor_align + +namespace ver_align { + +using map_type = mdds::sorted_string_map<spreadsheet::ver_alignment_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = +{ + { "bottom", spreadsheet::ver_alignment_t::bottom }, + { "justified", spreadsheet::ver_alignment_t::justified }, + { "middle", spreadsheet::ver_alignment_t::middle }, + { "top", spreadsheet::ver_alignment_t::top } +}; + +const map_type& get() +{ + static map_type mt(entries, std::size(entries), ss::ver_alignment_t::unknown); + return mt; +} + +} // namespace ver_align + +bool is_valid_hex_digit(const char& character, orcus::spreadsheet::color_elem_t& val) +{ + if ('0' <= character && character <= '9') + { + val += character - '0'; + return true; + } + + if ('A' <= character && character <= 'F') + { + val += character - 'A' + 10; + return true; + } + + if ('a' <= character && character <= 'f') + { + val += character - 'a' + 10; + return true; + } + + return false; +} + +// converts two characters starting at index to a color value +bool convert_color_digits(std::string_view value, orcus::spreadsheet::color_elem_t& color_val, size_t index) +{ + const char& high_val = value[index]; + color_val = 0; + if (!is_valid_hex_digit(high_val, color_val)) + return false; + color_val *= 16; + const char& low_val = value[++index]; + return is_valid_hex_digit(low_val, color_val); +} + +} // anonymous namespace + +bool odf::convert_fo_color( + std::string_view value, + spreadsheet::color_elem_t& red, + spreadsheet::color_elem_t& green, + spreadsheet::color_elem_t& blue) +{ + auto color = convert_fo_color(value); + if (!color) + return false; + + red = color->red; + green = color->green; + blue = color->blue; + return true; +} + +std::optional<spreadsheet::color_rgb_t> odf::convert_fo_color(std::string_view value) +{ + std::optional<spreadsheet::color_rgb_t> ret; + + // first character needs to be '#' + if (value.size() != 7) + return ret; + + if (value[0] != '#') + return ret; + + spreadsheet::color_rgb_t color; + if (!convert_color_digits(value, color.red, 1)) + return ret; + + if (!convert_color_digits(value, color.green, 3)) + return ret; + + if (!convert_color_digits(value, color.blue, 5)) + return ret; + + return color; +} + +orcus::odf::border_details_t odf::extract_border_details(std::string_view value) +{ + border_details_t border_details; + + auto detail = orcus::string_helper::split_string(value,' '); + + for (const auto& sub_detail : detail) + { + if (sub_detail[0] == '#') + convert_fo_color(sub_detail, border_details.red, border_details.green, border_details.blue); + else if (sub_detail[0] >= '0' && sub_detail[0] <='9') + border_details.border_width = orcus::to_length(sub_detail); + else // This has to be a style + border_details.border_style = border_style::get().find(sub_detail); + } + return border_details; +} + +ss::underline_width_t odf::extract_underline_width(std::string_view value) +{ + // TODO: style:text-underline-width also allows: + // * percent value + // * positive integer + // * positive length + // As we encounter real-life examples of these values, we should add code to + // handle them here. For now, we only handle enumerated values. + return underline_width::get().find(value); +} + +orcus::spreadsheet::underline_t odf::extract_underline_style(std::string_view value) +{ + return underline_style::get().find(value); +} + +ss::hor_alignment_t odf::extract_hor_alignment_style(std::string_view value) +{ + return hor_align::get().find(value); +} + +spreadsheet::ver_alignment_t odf::extract_ver_alignment_style(std::string_view value) +{ + return ver_align::get().find(value); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_helper.hpp b/src/liborcus/odf_helper.hpp new file mode 100644 index 0000000..eb95692 --- /dev/null +++ b/src/liborcus/odf_helper.hpp @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_ODF_HELPER_HPP +#define INCLUDED_ORCUS_ODF_HELPER_HPP + +#include <orcus/spreadsheet/types.hpp> +#include <orcus/measurement.hpp> +#include <orcus/spreadsheet/styles.hpp> + +#include <optional> + +namespace orcus { namespace odf { + +struct border_details_t +{ + spreadsheet::border_style_t border_style = spreadsheet::border_style_t::unknown; + + spreadsheet::color_elem_t red = 0; + spreadsheet::color_elem_t green = 0; + spreadsheet::color_elem_t blue = 0; + + length_t border_width; +}; + +bool convert_fo_color( + std::string_view value, + spreadsheet::color_elem_t& red, + spreadsheet::color_elem_t& green, + spreadsheet::color_elem_t& blue); + +std::optional<spreadsheet::color_rgb_t> convert_fo_color(std::string_view value); + +/** + * extracts border style, width and colors from a string value. + */ +border_details_t extract_border_details(std::string_view value); + +spreadsheet::underline_width_t extract_underline_width(std::string_view value); + +spreadsheet::underline_t extract_underline_style(std::string_view value); + +spreadsheet::hor_alignment_t extract_hor_alignment_style(std::string_view value); + +spreadsheet::ver_alignment_t extract_ver_alignment_style(std::string_view value); + +}} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_helper_test.cpp b/src/liborcus/odf_helper_test.cpp new file mode 100644 index 0000000..803644c --- /dev/null +++ b/src/liborcus/odf_helper_test.cpp @@ -0,0 +1,51 @@ +#include "odf_helper.hpp" + +#include <orcus/spreadsheet/types.hpp> + +#include <cassert> + +using namespace orcus::spreadsheet; + +namespace { + +void test_color_conversion(const char* input, bool valid, + color_elem_t red_expected, color_elem_t green_expected, color_elem_t blue_expected) +{ + color_elem_t red, green, blue; + bool valid_result = orcus::odf::convert_fo_color(input, red, green, blue); + + assert(valid == valid_result); + if (valid) + { + assert(red_expected == red); + assert(green_expected == green); + assert(blue_expected == blue); + } +} + +} + +int main() +{ + struct + { + const char* input; + bool valid; + orcus::spreadsheet::color_elem_t red; + orcus::spreadsheet::color_elem_t green; + orcus::spreadsheet::color_elem_t blue; + } data[] = { + { "not valid", false, 0, 0, 0}, + { "#000000", true, 0, 0, 0}, + { "#0000", false, 0, 0, 0}, + { "#abcdef", true, 0xab, 0xcd, 0xef}, + { "#ABCDEF", true, 0xab, 0xcd, 0xef}, + { "#123456", true, 0x12, 0x34, 0x56} + }; + + for (size_t i = 0; i < sizeof(data)/sizeof(data[0]); ++i) + { + test_color_conversion(data[i].input, data[i].valid, data[i].red, data[i].green, data[i].blue); + } + return 0; +} diff --git a/src/liborcus/odf_namespace_types.cpp b/src/liborcus/odf_namespace_types.cpp new file mode 100644 index 0000000..ae768db --- /dev/null +++ b/src/liborcus/odf_namespace_types.cpp @@ -0,0 +1,12 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "odf_namespace_types.hpp" + +#include "odf_namespace_types_cpp.inl" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_namespace_types.hpp b/src/liborcus/odf_namespace_types.hpp new file mode 100644 index 0000000..5dce680 --- /dev/null +++ b/src/liborcus/odf_namespace_types.hpp @@ -0,0 +1,16 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef __ORCUS_ODF_NAMESPACE_TYPES_HPP__ +#define __ORCUS_ODF_NAMESPACE_TYPES_HPP__ + +#include "orcus/types.hpp" + +#include "odf_namespace_types_hpp.inl" + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_namespace_types_cpp.inl b/src/liborcus/odf_namespace_types_cpp.inl new file mode 100644 index 0000000..8b0dc1f --- /dev/null +++ b/src/liborcus/odf_namespace_types_cpp.inl @@ -0,0 +1,63 @@ +namespace orcus { + +const xmlns_id_t NS_odf_anim = "urn:oasis:names:tc:opendocument:xmlns:animation:1.0"; +const xmlns_id_t NS_odf_chart = "urn:oasis:names:tc:opendocument:xmlns:chart:1.0"; +const xmlns_id_t NS_odf_config = "urn:oasis:names:tc:opendocument:xmlns:config:1.0"; +const xmlns_id_t NS_odf_db = "urn:oasis:names:tc:opendocument:xmlns:database:1.0"; +const xmlns_id_t NS_odf_dc = "http://purl.org/dc/elements/1.1/"; +const xmlns_id_t NS_odf_dr3d = "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"; +const xmlns_id_t NS_odf_draw = "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"; +const xmlns_id_t NS_odf_fo = "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"; +const xmlns_id_t NS_odf_form = "urn:oasis:names:tc:opendocument:xmlns:form:1.0"; +const xmlns_id_t NS_odf_grddl = "http://www.w3.org/2003/g/data-view#"; +const xmlns_id_t NS_odf_math = "http://www.w3.org/1998/Math/MathML"; +const xmlns_id_t NS_odf_meta = "urn:oasis:names:tc:opendocument:xmlns:meta:1.0"; +const xmlns_id_t NS_odf_number = "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"; +const xmlns_id_t NS_odf_office = "urn:oasis:names:tc:opendocument:xmlns:office:1.0"; +const xmlns_id_t NS_odf_presentation = "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0"; +const xmlns_id_t NS_odf_script = "urn:oasis:names:tc:opendocument:xmlns:script:1.0"; +const xmlns_id_t NS_odf_smil = "urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0"; +const xmlns_id_t NS_odf_style = "urn:oasis:names:tc:opendocument:xmlns:style:1.0"; +const xmlns_id_t NS_odf_svg = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"; +const xmlns_id_t NS_odf_table = "urn:oasis:names:tc:opendocument:xmlns:table:1.0"; +const xmlns_id_t NS_odf_text = "urn:oasis:names:tc:opendocument:xmlns:text:1.0"; +const xmlns_id_t NS_odf_xforms = "http://www.w3.org/2002/xforms"; +const xmlns_id_t NS_odf_xhtml = "http://www.w3.org/1999/xhtml"; +const xmlns_id_t NS_odf_xlink = "http://www.w3.org/1999/xlink"; + +namespace { + +const xmlns_id_t odf_ns[] = { + NS_odf_anim, + NS_odf_chart, + NS_odf_config, + NS_odf_db, + NS_odf_dc, + NS_odf_dr3d, + NS_odf_draw, + NS_odf_fo, + NS_odf_form, + NS_odf_grddl, + NS_odf_math, + NS_odf_meta, + NS_odf_number, + NS_odf_office, + NS_odf_presentation, + NS_odf_script, + NS_odf_smil, + NS_odf_style, + NS_odf_svg, + NS_odf_table, + NS_odf_text, + NS_odf_xforms, + NS_odf_xhtml, + NS_odf_xlink, + nullptr +}; + +} // anonymous + +const xmlns_id_t* NS_odf_all = odf_ns; + +} + diff --git a/src/liborcus/odf_namespace_types_hpp.inl b/src/liborcus/odf_namespace_types_hpp.inl new file mode 100644 index 0000000..a80c917 --- /dev/null +++ b/src/liborcus/odf_namespace_types_hpp.inl @@ -0,0 +1,31 @@ +namespace orcus { + +extern const xmlns_id_t NS_odf_anim; +extern const xmlns_id_t NS_odf_chart; +extern const xmlns_id_t NS_odf_config; +extern const xmlns_id_t NS_odf_db; +extern const xmlns_id_t NS_odf_dc; +extern const xmlns_id_t NS_odf_dr3d; +extern const xmlns_id_t NS_odf_draw; +extern const xmlns_id_t NS_odf_fo; +extern const xmlns_id_t NS_odf_form; +extern const xmlns_id_t NS_odf_grddl; +extern const xmlns_id_t NS_odf_math; +extern const xmlns_id_t NS_odf_meta; +extern const xmlns_id_t NS_odf_number; +extern const xmlns_id_t NS_odf_office; +extern const xmlns_id_t NS_odf_presentation; +extern const xmlns_id_t NS_odf_script; +extern const xmlns_id_t NS_odf_smil; +extern const xmlns_id_t NS_odf_style; +extern const xmlns_id_t NS_odf_svg; +extern const xmlns_id_t NS_odf_table; +extern const xmlns_id_t NS_odf_text; +extern const xmlns_id_t NS_odf_xforms; +extern const xmlns_id_t NS_odf_xhtml; +extern const xmlns_id_t NS_odf_xlink; + +extern const xmlns_id_t* NS_odf_all; + +} + diff --git a/src/liborcus/odf_number_format_context.cpp b/src/liborcus/odf_number_format_context.cpp new file mode 100644 index 0000000..d224a64 --- /dev/null +++ b/src/liborcus/odf_number_format_context.cpp @@ -0,0 +1,1126 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "odf_number_format_context.hpp" +#include "odf_namespace_types.hpp" +#include "odf_token_constants.hpp" +#include "odf_helper.hpp" +#include "ods_session_data.hpp" +#include "impl_utils.hpp" + +#include <orcus/measurement.hpp> +#include <orcus/spreadsheet/import_interface.hpp> +#include <orcus/spreadsheet/import_interface_styles.hpp> +#include <orcus/spreadsheet/styles.hpp> + +#include <iostream> +#include <algorithm> +#include <string> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace { + +enum class date_style_type +{ + unknown = 0, + short_symbol, + long_symbol +}; + +date_style_type to_date_style(std::string_view s) +{ + constexpr std::pair<std::string_view, date_style_type> entries[] = { + { "short", date_style_type::short_symbol }, + { "long", date_style_type::long_symbol }, + }; + + for (const auto& entry : entries) + { + if (s == entry.first) + return entry.second; + } + + return date_style_type::unknown; +} + +struct parse_result +{ + bool success = true; + std::string error_message; +}; + +date_style_type parse_attrs_for_date_style(const std::vector<xml_token_attr_t>& attrs) +{ + for (const auto& attr : attrs) + { + if (attr.ns == NS_odf_number) + { + switch (attr.name) + { + case XML_style: + return to_date_style(attr.value); + } + } + } + + return date_style_type::unknown; +} + +void parse_element_time_short_long(const std::vector<xml_token_attr_t>& attrs, char c, odf_number_format& style) +{ + style.code += c; + + if (parse_attrs_for_date_style(attrs) == date_style_type::long_symbol) + style.code += c; +} + +void parse_element_number(const std::vector<xml_token_attr_t>& attrs, odf_number_format& style) +{ + bool grouping = false; + long decimal_places = 0; + long min_integer_digits = 0; + + for (const auto& attr : attrs) + { + if (attr.ns == NS_odf_number) + { + switch (attr.name) + { + case XML_decimal_places: + { + decimal_places = to_long(attr.value); + break; + } + case XML_grouping: + grouping = to_bool(attr.value); + break; + case XML_min_integer_digits: + min_integer_digits = to_long(attr.value); + break; + default:; + } + } + } + + if (grouping) + { + if (min_integer_digits < 4) + { + style.code += "#,"; + + for (long i = 0; i < 3 - min_integer_digits; ++i) + style.code += "#"; + + for (long i = 0; i < min_integer_digits; ++i) + style.code += "0"; + } + else + { + std::string temporary_code; + + for (long i = 0; i < min_integer_digits; ++i) + { + if (i % 3 == 0 && i != 0) + temporary_code += ","; + + temporary_code += "0"; + } + + std::reverse(temporary_code.begin(), temporary_code.end()); + style.code += temporary_code; + } + } + else + { + if (min_integer_digits == 0) + style.code += "#"; + + for (long i = 0; i < min_integer_digits; ++i) + style.code += "0"; + } + + if (decimal_places > 0) + { + style.code += "."; + for (long i = 0; i < decimal_places; ++i) + style.code += "0"; + } +} + +void parse_element_text_properties(const std::vector<xml_token_attr_t>& attrs, odf_number_format& style) +{ + std::string_view color; + + for (const auto& attr : attrs) + { + if (attr.ns == NS_odf_fo) + { + switch (attr.name) + { + case XML_color: + { + if (attr.value == "#000000") + color = "BLACK"; + if (attr.value == "#ff0000") + color = "RED"; + if (attr.value == "#00ff00") + color = "GREEN"; + if (attr.value == "#0000ff") + color = "BLUE"; + if (attr.value == "#ffff00") + color = "YELLOW"; + if (attr.value == "#00ffff") + color = "CYAN"; + if (attr.value == "#ff00ff") + color = "MAGENTA"; + if (attr.value == "#ffffff") + color = "WHITE"; + } + } + } + } + + if (!color.empty()) + { + std::ostringstream os; + os << '[' << color << ']'; + style.code += os.str(); + } +} + +parse_result parse_element_map(session_context& cxt, const std::vector<xml_token_attr_t>& attrs, odf_number_format& style) +{ + parse_result res; + + std::string_view comp; // comparison operator e.g. <, >, >=, ... + std::string_view value; // right-hand value + std::string_view style_name; // style name associated with the mapped rule + + for (const auto& attr : attrs) + { + if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_apply_style_name: + { + style_name = attr.value; + break; + } + case XML_condition: + { + // value()[comp][rvalue] e.g. 'value()>=0' + constexpr std::string_view prefix = "value()"; + + // check if the attribute value starts with 'value()' + if (attr.value.compare(0, prefix.size(), prefix) == 0) + { + auto pos_value = attr.value.find_first_not_of("<>=", prefix.size()); + + comp = attr.value.substr(prefix.size(), pos_value - prefix.size()); + value = attr.value.substr(pos_value); + } + break; + } + } + } + } + + if (comp.empty() || value.empty() || style_name.empty()) + { + res.success = false; + return res; + } + + // fetch the code associated with the mapped rule + auto& numfmts = cxt.get_data<ods_session_data>().number_formats; + std::string_view code = numfmts.get_code(style_name); + + if (code.empty()) + { + res.success = false; + std::ostringstream os; + os << "code stored for the number format style named '" << style_name << "' exists, but is empty."; + res.error_message = os.str(); + return res; + } + + // prepend the mapped rule to the current code + std::ostringstream os; + os << '[' << comp << value << ']' << code << ';' << style.code; + style.code = os.str(); + + return res; +} + +} // anonymous namespace + +date_style_context::date_style_context(session_context& session_cxt, const tokens& tk) : + xml_context_base(session_cxt, tk) +{ + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_odf_number, XML_date_style }, // root element + { NS_odf_number, XML_date_style, NS_odf_number, XML_day }, + { NS_odf_number, XML_date_style, NS_odf_number, XML_month }, + { NS_odf_number, XML_date_style, NS_odf_number, XML_text }, + { NS_odf_number, XML_date_style, NS_odf_number, XML_year }, + }; + + init_element_validator(rules, std::size(rules)); +} + +void date_style_context::start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) +{ + push_stack(ns, name); + + if (ns == NS_odf_number) + { + switch (name) + { + case XML_date_style: + start_element_date_style(attrs); + break; + case XML_month: + start_element_month(attrs); + break; + case XML_day: + start_element_day(attrs); + break; + case XML_year: + start_element_year(attrs); + break; + case XML_text: + m_text_stream = std::ostringstream{}; + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool date_style_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_odf_number) + { + switch (name) + { + case XML_text: + m_current_style->code += m_text_stream.str(); + break; + } + } + return pop_stack(ns, name); +} + +void date_style_context::characters(std::string_view str, bool /*transient*/) +{ + m_text_stream << str; +} + +void date_style_context::reset() +{ + m_current_style = std::make_unique<odf_number_format>(); +} + +std::unique_ptr<odf_number_format> date_style_context::pop_style() +{ + return std::move(m_current_style); +} + +void date_style_context::start_element_date_style(const std::vector<xml_token_attr_t>& attrs) +{ + for (const auto& attr : attrs) + { + if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_name: + m_current_style->name = intern(attr); + break; + } + } + } +} + +void date_style_context::start_element_month(const std::vector<xml_token_attr_t>& attrs) +{ + auto style = date_style_type::unknown; + bool textual = false; + + for (const auto& attr : attrs) + { + if (attr.ns == NS_odf_number) + { + switch (attr.name) + { + case XML_style: + style = to_date_style(attr.value); + break; + case XML_textual: + textual = to_bool(attr.value); + break; + } + } + } + + m_current_style->code += 'M'; + + if (style == date_style_type::long_symbol) + m_current_style->code += 'M'; + + if (textual) + m_current_style->code += 'M'; + + if (style == date_style_type::long_symbol && textual) + m_current_style->code += 'M'; +} + +void date_style_context::start_element_day(const std::vector<xml_token_attr_t>& attrs) +{ + m_current_style->code += 'D'; + + if (parse_attrs_for_date_style(attrs) == date_style_type::long_symbol) + m_current_style->code += 'D'; +} + +void date_style_context::start_element_year(const std::vector<xml_token_attr_t>& attrs) +{ + m_current_style->code += "YY"; + + if (parse_attrs_for_date_style(attrs) == date_style_type::long_symbol) + m_current_style->code += "YY"; +} + +time_style_context::time_style_context(session_context& session_cxt, const tokens& tk) : + xml_context_base(session_cxt, tk) +{ + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_odf_number, XML_time_style }, // root element + { NS_odf_number, XML_time_style, NS_odf_number, XML_hours }, + { NS_odf_number, XML_time_style, NS_odf_number, XML_minutes }, + { NS_odf_number, XML_time_style, NS_odf_number, XML_seconds }, + { NS_odf_number, XML_time_style, NS_odf_number, XML_text }, + { NS_odf_number, XML_time_style, NS_odf_number, XML_am_pm }, + }; + + init_element_validator(rules, std::size(rules)); +} + +void time_style_context::start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) +{ + push_stack(ns, name); + + if (ns == NS_odf_number) + { + switch (name) + { + case XML_time_style: + start_element_time_style(attrs); + break; + case XML_hours: + parse_element_time_short_long(attrs, 'H', *m_current_style); + break; + case XML_minutes: + parse_element_time_short_long(attrs, 'M', *m_current_style); + break; + case XML_seconds: + start_element_seconds(attrs); + break; + case XML_text: + m_text_stream = std::ostringstream{}; + break; + case XML_am_pm: + m_current_style->code += "AM/PM"; + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool time_style_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_odf_number) + { + switch (name) + { + case XML_text: + m_current_style->code += m_text_stream.str(); + break; + } + } + + return pop_stack(ns, name); +} + +void time_style_context::characters(std::string_view str, bool /*transient*/) +{ + m_text_stream << str; +} + +void time_style_context::reset() +{ + m_current_style = std::make_unique<odf_number_format>(); +} + +std::unique_ptr<odf_number_format> time_style_context::pop_style() +{ + return std::move(m_current_style); +} + +void time_style_context::start_element_time_style(const std::vector<xml_token_attr_t>& attrs) +{ + for (const auto& attr : attrs) + { + if (attr.ns == NS_odf_style && attr.name == XML_name) + m_current_style->name = intern(attr); + } +} + +void time_style_context::start_element_seconds(const std::vector<xml_token_attr_t>& attrs) +{ + auto style = date_style_type::unknown; + std::optional<std::size_t> decimal_places; + + for (const auto& attr : attrs) + { + if (attr.ns == NS_odf_number) + { + switch (attr.name) + { + case XML_style: + style = to_date_style(attr.value); + break; + case XML_decimal_places: + decimal_places = to_long(attr.value); + break; + } + } + } + + m_current_style->code += 'S'; + + if (style == date_style_type::long_symbol) + m_current_style->code += 'S'; + + if (decimal_places && *decimal_places > 0) + m_current_style->code += std::string{"S", *decimal_places}; +} + +percentage_style_context::percentage_style_context(session_context& session_cxt, const tokens& tk) : + xml_context_base(session_cxt, tk) +{ + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_odf_number, XML_percentage_style }, // root element + { NS_odf_number, XML_percentage_style, NS_odf_number, XML_number }, + { NS_odf_number, XML_percentage_style, NS_odf_number, XML_text }, + }; + + init_element_validator(rules, std::size(rules)); +} + +void percentage_style_context::start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) +{ + push_stack(ns, name); + + if (ns == NS_odf_number) + { + switch (name) + { + case XML_percentage_style: + { + for (const auto& attr : attrs) + { + if (attr.ns == NS_odf_style && attr.name == XML_name) + m_current_style->name = intern(attr); + } + break; + } + case XML_number: + { + parse_element_number(attrs, *m_current_style); + break; + } + case XML_text: + m_text_stream = std::ostringstream{}; + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool percentage_style_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_odf_number) + { + switch (name) + { + case XML_text: + m_current_style->code += m_text_stream.str(); + break; + } + } + return pop_stack(ns, name); +} + +void percentage_style_context::characters(std::string_view str, bool /*transient*/) +{ + m_text_stream << str; +} + +void percentage_style_context::reset() +{ + m_current_style = std::make_unique<odf_number_format>(); +} + +std::unique_ptr<odf_number_format> percentage_style_context::pop_style() +{ + return std::move(m_current_style); +} + +boolean_style_context::boolean_style_context(session_context& session_cxt, const tokens& tk) : + xml_context_base(session_cxt, tk) +{ + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_odf_number, XML_boolean_style }, // root element + { NS_odf_number, XML_boolean_style, NS_odf_number, XML_boolean }, + }; + + init_element_validator(rules, std::size(rules)); +} + +void boolean_style_context::start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) +{ + push_stack(ns, name); + + if (ns == NS_odf_number) + { + switch (name) + { + case XML_boolean_style: + { + for (const auto& attr : attrs) + { + if (attr.ns == NS_odf_style && attr.name == XML_name) + m_current_style->name = intern(attr); + } + break; + } + case XML_boolean: + { + m_current_style->code += "BOOLEAN"; + break; + } + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool boolean_style_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + return pop_stack(ns, name); +} + +void boolean_style_context::reset() +{ + m_current_style = std::make_unique<odf_number_format>(); +} + +std::unique_ptr<odf_number_format> boolean_style_context::pop_style() +{ + return std::move(m_current_style); +} + +text_style_context::text_style_context(session_context& session_cxt, const tokens& tk) : + xml_context_base(session_cxt, tk) +{ + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_odf_number, XML_text_style }, // root element + { NS_odf_number, XML_text_style, NS_odf_number, XML_text }, + { NS_odf_number, XML_text_style, NS_odf_number, XML_text_content }, + }; + + init_element_validator(rules, std::size(rules)); +} + +void text_style_context::start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) +{ + push_stack(ns, name); + + if (ns == NS_odf_number) + { + switch (name) + { + case XML_text_style: + { + for (const auto& attr : attrs) + { + if (attr.ns == NS_odf_style && attr.name == XML_name) + m_current_style->name = intern(attr); + } + break; + } + case XML_text_content: + { + m_current_style->code += '@'; + break; + } + case XML_text: + m_text_stream = std::ostringstream{}; + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool text_style_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_odf_number) + { + switch (name) + { + case XML_text: + m_current_style->code += m_text_stream.str(); + break; + } + } + return pop_stack(ns, name); +} + +void text_style_context::characters(std::string_view str, bool /*transient*/) +{ + m_text_stream << str; +} + +void text_style_context::reset() +{ + m_current_style = std::make_unique<odf_number_format>(); +} + +std::unique_ptr<odf_number_format> text_style_context::pop_style() +{ + return std::move(m_current_style); +} + +number_style_context::number_style_context(session_context& session_cxt, const tokens& tk) : + xml_context_base(session_cxt, tk) +{ + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_odf_number, XML_number_style }, // root element + { NS_odf_number, XML_number_style, NS_odf_number, XML_fraction }, + { NS_odf_number, XML_number_style, NS_odf_number, XML_number }, + { NS_odf_number, XML_number_style, NS_odf_number, XML_scientific_number }, + { NS_odf_number, XML_number_style, NS_odf_number, XML_text }, + { NS_odf_number, XML_number_style, NS_odf_style, XML_map }, + { NS_odf_number, XML_number_style, NS_odf_style, XML_text_properties }, + }; + + init_element_validator(rules, std::size(rules)); +} + +void number_style_context::start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) +{ + push_stack(ns, name); + + if (ns == NS_odf_number) + { + switch (name) + { + case XML_fraction: + start_element_fraction(attrs); + break; + case XML_number_style: + start_element_number_style(attrs); + break; + case XML_number: + parse_element_number(attrs, *m_current_style); + break; + case XML_scientific_number: + start_element_scientific_number(attrs); + break; + case XML_text: + m_text_stream = std::ostringstream{}; + break; + default: + warn_unhandled(); + } + } + else if (ns == NS_odf_style) + { + switch (name) + { + case XML_text_properties: + parse_element_text_properties(attrs, *m_current_style); + break; + case XML_map: + { + auto res = parse_element_map(get_session_context(), attrs, *m_current_style); + if (!res.success && get_config().debug) + warn(res.error_message); + + break; + } + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool number_style_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_odf_number) + { + switch (name) + { + case XML_text: + m_current_style->code += m_text_stream.str(); + break; + default:; + } + } + + return pop_stack(ns, name); +} + +void number_style_context::characters(std::string_view str, bool /*transient*/) +{ + m_text_stream << str; +} + +void number_style_context::reset() +{ + m_current_style = std::make_unique<odf_number_format>(); + m_text_stream = std::ostringstream{}; + m_country_code = std::string_view{}; + m_language = std::string_view{}; +} + +std::unique_ptr<odf_number_format> number_style_context::pop_style() +{ + return std::move(m_current_style); +} + +void number_style_context::start_element_fraction(const std::vector<xml_token_attr_t>& attrs) +{ + std::size_t min_integer_digits = 0; + std::size_t min_numerator_digits = 0; + std::size_t min_denominator_digits = 0; + + std::optional<std::string_view> denominator_value; + + for (const auto& attr : attrs) + { + if (attr.ns == NS_odf_number) + { + switch (attr.name) + { + case XML_min_integer_digits: + min_integer_digits = to_long(attr.value); + break; + case XML_min_numerator_digits: + min_numerator_digits = to_long(attr.value); + break; + case XML_min_denominator_digits: + min_denominator_digits = to_long(attr.value); + break; + case XML_denominator_value: + { + denominator_value = attr.value; + break; + } + } + } + } + + if (min_integer_digits > 0) + { + m_current_style->code += std::string{"#", min_integer_digits}; + m_current_style->code += ' '; + } + + if (min_numerator_digits > 0) + m_current_style->code += std::string{"?", min_numerator_digits}; + + m_current_style->code += '/'; + + if (denominator_value) + m_current_style->code += *denominator_value; + else if (min_denominator_digits > 0) + m_current_style->code += std::string{"?", min_denominator_digits}; +} + +void number_style_context::start_element_number_style(const std::vector<xml_token_attr_t>& attrs) +{ + for (const xml_token_attr_t& attr: attrs) + { + if (attr.ns == NS_odf_number) + { + switch (attr.name) + { + case XML_country: + m_country_code = attr.value; + break; + case XML_language: + m_language = attr.value; + break; + default: + ; + } + } + else if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_name: + m_current_style->name = attr.value; + break; + default: + ; + } + } + } +} + +void number_style_context::start_element_scientific_number(const std::vector<xml_token_attr_t>& attrs) +{ + long decimal_places = 0; + long min_exponent_digits = 0; + long min_integer_digits = 0; + bool grouping = false; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns == NS_odf_number) + { + switch (attr.name) + { + case XML_decimal_places: + decimal_places = to_long(attr.value); + break; + case XML_grouping: + grouping = to_bool(attr.value); + break; + case XML_min_exponent_digits: + min_exponent_digits = to_long(attr.value); + break; + case XML_min_integer_digits: + min_integer_digits = to_long(attr.value); + break; + } + } + } + + if (grouping) + { + if (min_integer_digits < 4) + { + m_current_style->code += "#,"; + + for (long i = 0; i < 3 - min_integer_digits; ++i) + { + m_current_style->code += "#"; + } + + for (long i = 0; i < min_integer_digits; ++i) + { + m_current_style->code += "0"; + } + } + else + { + std::string temporary_code; + for (long i = 0; i < min_integer_digits; ++i) + { + if (i % 3 == 0 && i != 0) + temporary_code += ","; + + temporary_code += "0"; + } + + std::reverse(temporary_code.begin(), temporary_code.end()); + m_current_style->code += temporary_code; + } + } + else + { + if (min_integer_digits == 0) + m_current_style->code += "#"; + + for (long i = 0; i < min_integer_digits; ++i) + m_current_style->code += "0"; + } + + m_current_style->code += "."; + + for (long i = 0; i < decimal_places; ++i) + m_current_style->code += "0"; + + m_current_style->code += "E+"; + + for (long i = 0; i < min_exponent_digits; ++i) + m_current_style->code += "0"; +} + +currency_style_context::currency_style_context(session_context& session_cxt, const tokens& tk) : + xml_context_base(session_cxt, tk) +{ + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_odf_number, XML_currency_style }, // root element + { NS_odf_number, XML_currency_style, NS_odf_number, XML_currency_symbol }, + { NS_odf_number, XML_currency_style, NS_odf_number, XML_number }, + { NS_odf_number, XML_currency_style, NS_odf_number, XML_text }, + { NS_odf_number, XML_currency_style, NS_odf_style, XML_map }, + { NS_odf_number, XML_currency_style, NS_odf_style, XML_text_properties }, + }; + + init_element_validator(rules, std::size(rules)); +} + +void currency_style_context::start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) +{ + push_stack(ns, name); + + if (ns == NS_odf_number) + { + switch (name) + { + case XML_currency_style: + start_element_currency_style(attrs); + break; + case XML_currency_symbol: + m_text_stream = std::ostringstream{}; + break; + case XML_number: + parse_element_number(attrs, *m_current_style); + break; + case XML_text: + m_text_stream = std::ostringstream{}; + break; + default: + warn_unhandled(); + } + } + else if (ns == NS_odf_style) + { + switch (name) + { + case XML_map: + { + auto res = parse_element_map(get_session_context(), attrs, *m_current_style); + if (!res.success && get_config().debug) + warn(res.error_message); + + break; + } + case XML_text_properties: + parse_element_text_properties(attrs, *m_current_style); + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool currency_style_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_odf_number) + { + switch (name) + { + case XML_currency_symbol: + { + std::ostringstream os; + os << m_current_style->code << "[$" << m_text_stream.str() << ']'; + m_current_style->code = os.str(); + break; + } + case XML_text: + m_current_style->code += m_text_stream.str(); + break; + } + } + + return pop_stack(ns, name); +} + +void currency_style_context::characters(std::string_view str, bool /*transient*/) +{ + m_text_stream << str; +} + +void currency_style_context::reset() +{ + m_current_style = std::make_unique<odf_number_format>(); +} + +std::unique_ptr<odf_number_format> currency_style_context::pop_style() +{ + return std::move(m_current_style); +} + +void currency_style_context::start_element_currency_style(const std::vector<xml_token_attr_t>& attrs) +{ + for (const auto& attr : attrs) + { + if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_name: + m_current_style->name = intern(attr); + break; + case XML_volatile: + m_current_style->is_volatile = to_bool(attr.value); + break; + } + } + else if (attr.ns == NS_odf_number) + { + switch (attr.name) + { + case XML_language: + m_language = intern(attr); + break; + case XML_country: + m_country_code = intern(attr); + break; + } + } + } +} + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_number_format_context.hpp b/src/liborcus/odf_number_format_context.hpp new file mode 100644 index 0000000..c91c817 --- /dev/null +++ b/src/liborcus/odf_number_format_context.hpp @@ -0,0 +1,180 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ODF_NUMBER_FORMATTING_CONTEXT_HPP +#define ODF_NUMBER_FORMATTING_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "odf_styles.hpp" + +#include "orcus/string_pool.hpp" + +namespace orcus { + +namespace spreadsheet { namespace iface { + class import_styles; +}} + +class date_style_context : public xml_context_base +{ +public: + date_style_context(session_context& session_cxt, const tokens& tk); + + void start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) override; + bool end_element(xmlns_id_t ns, xml_token_t name) override; + void characters(std::string_view str, bool transient) override; + + void reset(); + + std::unique_ptr<odf_number_format> pop_style(); + +private: + void start_element_date_style(const std::vector<xml_token_attr_t>& attrs); + void start_element_month(const std::vector<xml_token_attr_t>& attrs); + void start_element_day(const std::vector<xml_token_attr_t>& attrs); + void start_element_year(const std::vector<xml_token_attr_t>& attrs); + +private: + std::unique_ptr<odf_number_format> m_current_style; + std::ostringstream m_text_stream; +}; + +class time_style_context : public xml_context_base +{ +public: + time_style_context(session_context& session_cxt, const tokens& tk); + + void start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) override; + bool end_element(xmlns_id_t ns, xml_token_t name) override; + void characters(std::string_view str, bool transient) override; + + void reset(); + + std::unique_ptr<odf_number_format> pop_style(); + +private: + void start_element_time_style(const std::vector<xml_token_attr_t>& attrs); + void start_element_seconds(const std::vector<xml_token_attr_t>& attrs); + +private: + std::unique_ptr<odf_number_format> m_current_style; + std::ostringstream m_text_stream; +}; + +class percentage_style_context : public xml_context_base +{ +public: + percentage_style_context(session_context& session_cxt, const tokens& tk); + + void start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) override; + bool end_element(xmlns_id_t ns, xml_token_t name) override; + void characters(std::string_view str, bool transient) override; + + void reset(); + + std::unique_ptr<odf_number_format> pop_style(); + +private: + std::unique_ptr<odf_number_format> m_current_style; + std::ostringstream m_text_stream; +}; + +class boolean_style_context : public xml_context_base +{ +public: + boolean_style_context(session_context& session_cxt, const tokens& tk); + + void start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) override; + bool end_element(xmlns_id_t ns, xml_token_t name) override; + + void reset(); + + std::unique_ptr<odf_number_format> pop_style(); + +private: + std::unique_ptr<odf_number_format> m_current_style; +}; + +class text_style_context : public xml_context_base +{ +public: + text_style_context(session_context& session_cxt, const tokens& tk); + + void start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) override; + bool end_element(xmlns_id_t ns, xml_token_t name) override; + void characters(std::string_view str, bool transient) override; + + void reset(); + + std::unique_ptr<odf_number_format> pop_style(); + +private: + std::unique_ptr<odf_number_format> m_current_style; + std::ostringstream m_text_stream; +}; + +/** + * Context for <number:number-style> scope. + */ +class number_style_context : public xml_context_base +{ +public: + number_style_context(session_context& session_cxt, const tokens& tk); + + void start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) override; + bool end_element(xmlns_id_t ns, xml_token_t name) override; + void characters(std::string_view str, bool transient) override; + + void reset(); + + std::unique_ptr<odf_number_format> pop_style(); + +private: + void start_element_fraction(const std::vector<xml_token_attr_t>& attrs); + void start_element_number_style(const std::vector<xml_token_attr_t>& attrs); + void start_element_scientific_number(const std::vector<xml_token_attr_t>& attrs); + +private: + std::unique_ptr<odf_number_format> m_current_style; + std::ostringstream m_text_stream; + + std::string_view m_country_code; // TODO: handle this + std::string_view m_language; // TODO: handle this +}; + +/** + * Context for <number:currency-style> element scope. + */ +class currency_style_context : public xml_context_base +{ +public: + currency_style_context(session_context& session_cxt, const tokens& tk); + + void start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) override; + bool end_element(xmlns_id_t ns, xml_token_t name) override; + void characters(std::string_view str, bool transient) override; + + void reset(); + + std::unique_ptr<odf_number_format> pop_style(); + +private: + void start_element_currency_style(const std::vector<xml_token_attr_t>& attrs); + +private: + std::unique_ptr<odf_number_format> m_current_style; + std::ostringstream m_text_stream; + + std::string_view m_country_code; // TODO: handle this + std::string_view m_language; // TODO: handle this +}; + +} // namespace orcus + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_para_context.cpp b/src/liborcus/odf_para_context.cpp new file mode 100644 index 0000000..ad4b193 --- /dev/null +++ b/src/liborcus/odf_para_context.cpp @@ -0,0 +1,165 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "odf_para_context.hpp" +#include "odf_token_constants.hpp" +#include "odf_namespace_types.hpp" +#include "xml_context_global.hpp" + +#include "orcus/spreadsheet/import_interface.hpp" +#include "orcus/exception.hpp" + +#include <iostream> +#include <cassert> + +namespace orcus { + +text_para_context::text_para_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_shared_strings* ssb, odf_styles_map_type& styles) : + xml_context_base(session_cxt, tokens), + mp_sstrings(ssb), m_styles(styles), + m_string_index(0), m_has_content(false) +{ +} + +text_para_context::~text_para_context() = default; + +xml_context_base* text_para_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void text_para_context::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ + // not implemented yet. +} + +void text_para_context::start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + if (ns == NS_odf_text) + { + switch (name) + { + case XML_p: + // paragraph + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + break; + case XML_span: + { + // text span. + xml_element_expected(parent, NS_odf_text, XML_p); + flush_segment(); + std::string_view style_name = + for_each(attrs.begin(), attrs.end(), single_attr_getter(m_pool, NS_odf_text, XML_style_name)).get_value(); + m_span_stack.push_back(style_name); + + } + break; + case XML_s: + // control character. ignored for now. + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool text_para_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_odf_text) + { + switch (name) + { + case XML_p: + { + // paragraph + flush_segment(); + if (mp_sstrings) + m_string_index = mp_sstrings->commit_segments(); + } + break; + case XML_span: + { + // text span. + if (m_span_stack.empty()) + throw xml_structure_error("</text:span> encountered without matching opening element."); + + flush_segment(); + m_span_stack.pop_back(); + } + break; + default: + ; + } + } + return pop_stack(ns, name); +} + +void text_para_context::characters(std::string_view str, bool transient) +{ + if (transient) + m_contents.push_back(m_pool.intern(str).first); + else + m_contents.push_back(str); +} + +void text_para_context::reset() +{ + m_string_index = 0; + m_has_content = false; + m_pool.clear(); + m_contents.clear(); +} + +size_t text_para_context::get_string_index() const +{ + return m_string_index; +} + +bool text_para_context::empty() const +{ + return !m_has_content; +} + +void text_para_context::flush_segment() +{ + if (m_contents.empty()) + // No content to flush. + return; + + m_has_content = true; + + const odf_style* style = nullptr; + if (!m_span_stack.empty()) + { + std::string_view style_name = m_span_stack.back(); + auto it = m_styles.find(style_name); + if (it != m_styles.end()) + style = it->second.get(); + } + + if (mp_sstrings) + { + if (style && style->family == style_family_text) + { + const auto& data = std::get<odf_style::text>(style->data); + mp_sstrings->set_segment_font(data.font); + } + + for (std::string_view ps : m_contents) + mp_sstrings->append_segment(ps); + } + + m_contents.clear(); +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_para_context.hpp b/src/liborcus/odf_para_context.hpp new file mode 100644 index 0000000..42bdb7d --- /dev/null +++ b/src/liborcus/odf_para_context.hpp @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_PARACONTEXT_HPP +#define ORCUS_PARACONTEXT_HPP + +#include "xml_context_base.hpp" +#include "odf_styles.hpp" + +#include "orcus/string_pool.hpp" + +#include <vector> + +namespace orcus { + +namespace spreadsheet { namespace iface { class import_shared_strings; }} + +/** + * This class handles <text:p> contexts. + */ +class text_para_context : public xml_context_base +{ +public: + text_para_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_shared_strings* ssb, odf_styles_map_type& styles); + virtual ~text_para_context(); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child); + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + virtual void characters(std::string_view str, bool transient); + + void reset(); + + size_t get_string_index() const; + bool empty() const; + +private: + void flush_segment(); + +private: + spreadsheet::iface::import_shared_strings* mp_sstrings; + odf_styles_map_type& m_styles; + + string_pool m_pool; + std::vector<std::string_view> m_span_stack; /// stack of text spans. + std::vector<std::string_view> m_contents; + size_t m_string_index; + bool m_has_content; +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_style_context.cpp b/src/liborcus/odf_style_context.cpp new file mode 100644 index 0000000..70953a1 --- /dev/null +++ b/src/liborcus/odf_style_context.cpp @@ -0,0 +1,774 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "odf_style_context.hpp" +#include "impl_utils.hpp" +#include "odf_namespace_types.hpp" +#include "odf_token_constants.hpp" +#include "odf_helper.hpp" +#include "session_context.hpp" +#include "ods_session_data.hpp" + +#include <mdds/sorted_string_map.hpp> + +#include <orcus/spreadsheet/import_interface_styles.hpp> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace { + +namespace style_family { + +using map_type = mdds::sorted_string_map<odf_style_family>; + +constexpr map_type::entry entries[] = +{ + { MDDS_ASCII("graphic"), style_family_graphic }, + { MDDS_ASCII("paragraph"), style_family_paragraph }, + { MDDS_ASCII("table"), style_family_table }, + { MDDS_ASCII("table-cell"), style_family_table_cell }, + { MDDS_ASCII("table-column"), style_family_table_column }, + { MDDS_ASCII("table-row"), style_family_table_row }, + { MDDS_ASCII("text"), style_family_text } +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), style_family_unknown); + return mt; +} + +} // namespace style_family + +odf_style_family to_style_family(std::string_view val) +{ + return style_family::get().find(val.data(), val.size()); +} + +std::string_view to_string(odf_style_family family) +{ + static constexpr std::string_view unknown_str = "unknown"; + + for (const auto& entry : style_family::entries) + { + if (entry.value == family) + return {entry.key, entry.key_length}; + } + + return unknown_str; +} + +namespace st_style { + +typedef mdds::sorted_string_map<ss::strikethrough_style_t> map_type; + +// Keys must be sorted. +constexpr map_type::entry entries[] = +{ + { MDDS_ASCII("dash"), ss::strikethrough_style_t::dash }, + { MDDS_ASCII("dot-dash"), ss::strikethrough_style_t::dot_dash }, + { MDDS_ASCII("dot-dot-dash"), ss::strikethrough_style_t::dot_dot_dash }, + { MDDS_ASCII("dotted"), ss::strikethrough_style_t::dotted }, + { MDDS_ASCII("long-dash"), ss::strikethrough_style_t::long_dash }, + { MDDS_ASCII("none"), ss::strikethrough_style_t::none }, + { MDDS_ASCII("solid"), ss::strikethrough_style_t::solid }, + { MDDS_ASCII("wave"), ss::strikethrough_style_t::wave }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::strikethrough_style_t::none); + return mt; +} + +} // namespace st_style + +} // anonymous namespace + +style_context::style_context(session_context& session_cxt, const tokens& tk, ss::iface::import_styles* iface_styles) : + xml_context_base(session_cxt, tk), + mp_styles(iface_styles) +{ +} + +void style_context::start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + + if (ns == NS_odf_style) + { + switch (name) + { + case XML_style: + { + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + + std::string_view style_name; + std::string_view display_style_name; + std::string_view parent_style_name; + std::optional<std::string_view> data_style_name; + odf_style_family family = style_family_unknown; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_name: + style_name = intern(attr.value); + break; + case XML_display_name: + display_style_name = intern(attr.value); + break; + case XML_family: + family = to_style_family(attr.value); + break; + case XML_parent_style_name: + parent_style_name = intern(attr.value); + break; + case XML_data_style_name: + data_style_name = attr.value; // no need to intern + break; + } + } + } + + m_current_style = std::make_unique<odf_style>( + style_name, display_style_name, family, parent_style_name); + + if (data_style_name && family == style_family_table_cell) + { + const auto& ods_data = get_session_context().get_data<ods_session_data>(); + const auto& numfmt_name2id = ods_data.number_formats.name2id_map; + + if (auto it = numfmt_name2id.find(*data_style_name); it != numfmt_name2id.end()) + { + // record the number format id associated with the name. + auto& data = std::get<odf_style::cell>(m_current_style->data); + data.number_format = it->second; + } + else + { + if (get_config().debug) + { + std::ostringstream os; + os << "no number style found for the data style name of '" << *data_style_name << "'"; + warn(os.str()); + } + } + } + break; + } + case XML_table_column_properties: + { + xml_element_expected(parent, NS_odf_style, XML_style); + assert(m_current_style->family == style_family_table_column); + + for (const xml_token_attr_t& attr: attrs) + { + if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_column_width: + { + std::get<odf_style::column>(m_current_style->data).width = to_length(attr.value); + break; + } + } + } + } + + break; + } + case XML_table_row_properties: + { + xml_element_expected(parent, NS_odf_style, XML_style); + assert(m_current_style->family == style_family_table_row); + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_row_height: + { + auto& data = std::get<odf_style::row>(m_current_style->data); + data.height = to_length(attr.value); + data.height_set = true; + break; + } + } + } + } + + break; + } + case XML_table_properties: + xml_element_expected(parent, NS_odf_style, XML_style); + break; + case XML_paragraph_properties: + start_paragraph_properties(parent, attrs); + break; + case XML_text_properties: + start_text_properties(parent, attrs); + break; + case XML_table_cell_properties: + start_table_cell_properties(parent, attrs); + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool style_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + return pop_stack(ns, name); +} + +void style_context::reset() +{ + m_current_style.reset(); +} + +std::unique_ptr<odf_style> style_context::pop_style() +{ + return std::move(m_current_style); +} + +void style_context::characters(std::string_view /*str*/, bool /*transient*/) +{ +} + +void style_context::start_paragraph_properties(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs) +{ + xml_element_expected(parent, NS_odf_style, XML_style); + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns == NS_odf_fo) + { + switch (attr.name) + { + case XML_text_align: + { + auto v = odf::extract_hor_alignment_style(attr.value); + + switch (m_current_style->family) + { + case style_family_table_cell: + { + auto& data = std::get<odf_style::cell>(m_current_style->data); + data.hor_align = v; + break; + } + case style_family_paragraph: + { + auto& data = std::get<odf_style::paragraph>(m_current_style->data); + data.hor_align = v; + break; + } + default: + { + if (get_config().debug) + { + std::ostringstream os; + os << "unhandled fo:text-align attribute (family=" << to_string(m_current_style->family) << ")"; + warn(os.str()); + } + } + } + break; + } + default: + ; + } + } + } +} + +void style_context::start_text_properties(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs) +{ + static const xml_elem_set_t expected = { + { NS_odf_style, XML_style }, + { NS_odf_text, XML_list_level_style_number }, + { NS_odf_text, XML_list_level_style_bullet }, + }; + xml_element_expected(parent, expected); + + if (parent != xml_token_pair_t(NS_odf_style, XML_style)) + // TODO : handle this properly in the future. + return; + + // NB: no need to intern the font names since they are consumed at the end + // of this function. + std::optional<std::string_view> font_name; + std::optional<std::string_view> font_name_asian; + std::optional<std::string_view> font_name_complex; + std::optional<length_t> font_size; + std::optional<length_t> font_size_asian; + std::optional<length_t> font_size_complex; + std::optional<bool> bold; + std::optional<bool> bold_asian; + std::optional<bool> bold_complex; + std::optional<bool> italic; + std::optional<bool> italic_asian; + std::optional<bool> italic_complex; + std::optional<ss::color_rgb_t> color; + + std::optional<ss::color_rgb_t> underline_color; + std::optional<ss::underline_t> underline_style; + std::optional<ss::underline_type_t> underline_type; + std::optional<ss::underline_width_t> underline_width; + std::optional<ss::underline_mode_t> underline_mode; + + std::optional<ss::strikethrough_style_t> strikethrough_style; + std::optional<ss::strikethrough_type_t> strikethrough_type; + std::optional<ss::strikethrough_width_t> strikethrough_width; + std::optional<ss::strikethrough_text_t> strikethrough_text; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_font_name: + font_name = attr.value; + break; + case XML_font_name_asian: + font_name_asian = attr.value; + break; + case XML_font_name_complex: + font_name_complex = attr.value; + break; + case XML_font_size_asian: + font_size_asian = to_length(attr.value); + break; + case XML_font_size_complex: + font_size_complex = to_length(attr.value); + break; + case XML_font_style_asian: + italic_asian = attr.value == "italic"; + break; + case XML_font_style_complex: + italic_complex = attr.value == "italic"; + break; + case XML_font_weight_asian: + bold_asian = attr.value == "bold"; + break; + case XML_font_weight_complex: + bold_complex = attr.value == "bold"; + break; + case XML_text_underline_color: + if (attr.value != "font-color") + underline_color = odf::convert_fo_color(attr.value); + break; + case XML_text_underline_mode: + if (attr.value == "skip-white-space") + underline_mode = ss::underline_mode_t::skip_white_space; + else + underline_mode = ss::underline_mode_t::continuous; + break; + case XML_text_underline_width: + { + underline_width = odf::extract_underline_width(attr.value); + break; + } + case XML_text_underline_style: + { + underline_style = odf::extract_underline_style(attr.value); + break; + } + case XML_text_underline_type: + { + if (attr.value == "none") + underline_type = ss::underline_type_t::none; + else if (attr.value == "single") + underline_type = ss::underline_type_t::single_type; + else if (attr.value == "double") + underline_type = ss::underline_type_t::double_type; + break; + } + case XML_text_line_through_style: + { + strikethrough_style = st_style::get().find(attr.value.data(), attr.value.size()); + break; + } + case XML_text_line_through_type: + { + if (attr.value == "single") + strikethrough_type = ss::strikethrough_type_t::single_type; + else if (attr.value == "double") + strikethrough_type = ss::strikethrough_type_t::double_type; + else + strikethrough_type = ss::strikethrough_type_t::unknown; + break; + } + case XML_text_line_through_width: + { + if (attr.value == "bold") + strikethrough_width = ss::strikethrough_width_t::bold; + else + strikethrough_width = ss::strikethrough_width_t::unknown; + break; + } + case XML_text_line_through_text: + { + if (attr.value == "/") + strikethrough_text = ss::strikethrough_text_t::slash; + else if (attr.value == "X") + strikethrough_text = ss::strikethrough_text_t::cross; + else + strikethrough_text = ss::strikethrough_text_t::unknown; + break; + } + } + } + else if (attr.ns == NS_odf_fo) + { + switch (attr.name) + { + case XML_font_size: + font_size = to_length(attr.value); + break; + case XML_font_style: + italic = attr.value == "italic"; + break; + case XML_font_weight: + bold = attr.value == "bold"; + break; + case XML_color: + color = odf::convert_fo_color(attr.value); + break; + } + } + } + + // Commit the font data. + auto* font_style = mp_styles->start_font_style(); + ENSURE_INTERFACE(font_style, import_font_style); + + if (font_name) + font_style->set_name(*font_name); + + if (font_name_asian) + font_style->set_name_asian(*font_name_asian); + + if (font_name_complex) + font_style->set_name_complex(*font_name_complex); + + if (font_size && font_size->unit == length_unit_t::point) + font_style->set_size(font_size->value); + + if (font_size_asian && font_size_asian->unit == length_unit_t::point) + font_style->set_size_asian(font_size_asian->value); + + if (font_size_complex && font_size_complex->unit == length_unit_t::point) + font_style->set_size_complex(font_size_complex->value); + + if (bold) + font_style->set_bold(*bold); + + if (bold_asian) + font_style->set_bold_asian(*bold_asian); + + if (bold_complex) + font_style->set_bold_complex(*bold_complex); + + if (italic) + font_style->set_italic(*italic); + + if (italic_asian) + font_style->set_italic_asian(*italic_asian); + + if (italic_complex) + font_style->set_italic_complex(*italic_complex); + + if (color) + font_style->set_color(255, color->red, color->green, color->blue); + + if (underline_color) + // Separate underline color is specified. + font_style->set_underline_color(255, underline_color->red, underline_color->green, underline_color->blue); + + if (underline_width) + font_style->set_underline_width(*underline_width); + + if (underline_style) + font_style->set_underline(*underline_style); + + if (underline_type) + font_style->set_underline_type(*underline_type); + + if (underline_mode) + font_style->set_underline_mode(*underline_mode); + + if (strikethrough_style) + font_style->set_strikethrough_style(*strikethrough_style); + + if (strikethrough_type) + font_style->set_strikethrough_type(*strikethrough_type); + + if (strikethrough_width) + font_style->set_strikethrough_width(*strikethrough_width); + + if (strikethrough_text) + font_style->set_strikethrough_text(*strikethrough_text); + + size_t font_id = font_style->commit(); + + switch (m_current_style->family) + { + case style_family_table_cell: + { + auto& data = std::get<odf_style::cell>(m_current_style->data); + data.font = font_id; + break; + } + case style_family_text: + { + auto& data = std::get<odf_style::text>(m_current_style->data); + data.font = font_id; + break; + } + default: + ; + } +} + +void style_context::start_table_cell_properties(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs) +{ + xml_element_expected(parent, NS_odf_style, XML_style); + + if (m_current_style->family != style_family_table_cell) + throw xml_structure_error("expected table_cell family style in cell_properties element"); + + if (!mp_styles) + return; + + auto& data = std::get<odf_style::cell>(m_current_style->data); + + std::optional<spreadsheet::color_rgb_t> bg_color; + + std::optional<bool> locked; + std::optional<bool> hidden; + std::optional<bool> formula_hidden; + std::optional<bool> print_content; + + bool cell_protection_set = false; + + using border_map_type = std::map<ss::border_direction_t, odf::border_details_t>; + border_map_type border_styles; + + ss::ver_alignment_t ver_alignment = ss::ver_alignment_t::unknown; + std::optional<bool> wrap_text; + std::optional<bool> shrink_to_fit; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns == NS_odf_fo) + { + switch (attr.name) + { + case XML_background_color: + bg_color = odf::convert_fo_color(attr.value); + break; + case XML_border: + { + odf::border_details_t border_details = odf::extract_border_details(attr.value); + + const ss::border_direction_t dirs[] = + { + ss::border_direction_t::top, + ss::border_direction_t::bottom, + ss::border_direction_t::left, + ss::border_direction_t::right + }; + + for (const auto dir : dirs) + border_styles.insert_or_assign(dir, border_details); + + break; + } + case XML_border_top: + { + odf::border_details_t border_details = odf::extract_border_details(attr.value); + border_styles.insert_or_assign(ss::border_direction_t::top, border_details); + break; + } + case XML_border_bottom: + { + odf::border_details_t border_details = odf::extract_border_details(attr.value); + border_styles.insert_or_assign(ss::border_direction_t::bottom, border_details); + break; + } + case XML_border_left: + { + odf::border_details_t border_details = odf::extract_border_details(attr.value); + border_styles.insert_or_assign(ss::border_direction_t::left, border_details); + break; + } + case XML_border_right: + { + odf::border_details_t border_details = odf::extract_border_details(attr.value); + border_styles.insert_or_assign(ss::border_direction_t::right, border_details); + break; + } + case XML_diagonal_bl_tr: + { + odf::border_details_t border_details = odf::extract_border_details(attr.value); + border_styles.insert_or_assign(ss::border_direction_t::diagonal_bl_tr, border_details); + break; + } + case XML_diagonal_tl_br: + { + odf::border_details_t border_details = odf::extract_border_details(attr.value); + border_styles.insert_or_assign(ss::border_direction_t::diagonal_tl_br, border_details); + break; + } + case XML_wrap_option: + { + wrap_text = (attr.value == "wrap"); + break; + } + default: + ; + } + } + else if (attr.ns == NS_odf_style) + { + switch (attr.name) + { + case XML_print_content: + { + cell_protection_set = true; + print_content = to_bool(attr.value); + break; + } + case XML_cell_protect: + { + if (attr.value == "protected") + { + cell_protection_set = true; + locked = true; + } + else if (attr.value == "hidden-and-protected") + { + cell_protection_set = true; + locked = true; + hidden = true; + } + else if (attr.value == "formula-hidden") + { + cell_protection_set = true; + formula_hidden = true; + } + else if (attr.value == "protected formula-hidden" || attr.value == "formula-hidden protected") + { + cell_protection_set = true; + formula_hidden = true; + locked = true; + } + else if (attr.value == "none") + { + cell_protection_set = true; + locked = false; + hidden = false; + formula_hidden = false; + } + break; + } + case XML_vertical_align: + ver_alignment = odf::extract_ver_alignment_style(attr.value); + break; + case XML_shrink_to_fit: + shrink_to_fit = to_bool(attr.value); + break; + default: + ; + } + } + } + + std::size_t fill_id = 0; + std::size_t border_id = 0; + std::size_t cell_protection_id = 0; + + if (bg_color) + { + auto* fill_style = mp_styles->start_fill_style(); + ENSURE_INTERFACE(fill_style, import_fill_style); + + fill_style->set_pattern_type(ss::fill_pattern_t::solid); + fill_style->set_fg_color(255, bg_color->red, bg_color->green, bg_color->blue); + fill_id = fill_style->commit(); + } + + if (!border_styles.empty()) + { + auto* border_style = mp_styles->start_border_style(); + ENSURE_INTERFACE(border_style, import_border_style); + + for (const auto& [dir, details] : border_styles) + { + border_style->set_color(dir, 255, details.red, details.green, details.blue); + border_style->set_style(dir, details.border_style); + border_style->set_width(dir, details.border_width.value, details.border_width.unit); + } + + border_id = border_style->commit(); + } + + if (cell_protection_set) + { + auto* cell_protection = mp_styles->start_cell_protection(); + ENSURE_INTERFACE(cell_protection, import_cell_protection); + + if (hidden) + cell_protection->set_hidden(*hidden); + + if (locked) + cell_protection->set_locked(*locked); + + if (print_content) + cell_protection->set_print_content(*print_content); + + if (formula_hidden) + cell_protection->set_formula_hidden(*formula_hidden); + + cell_protection_id = cell_protection->commit(); + } + + switch (m_current_style->family) + { + case style_family_table_cell: + { + data.fill = fill_id; + data.border = border_id; + data.protection = cell_protection_id; + data.ver_align = ver_alignment; + data.wrap_text = wrap_text; + data.shrink_to_fit = shrink_to_fit; + break; + } + default: + ; + } +} + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_style_context.hpp b/src/liborcus/odf_style_context.hpp new file mode 100644 index 0000000..4a33948 --- /dev/null +++ b/src/liborcus/odf_style_context.hpp @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "xml_context_base.hpp" +#include "odf_styles.hpp" + +#include <memory> + +namespace orcus { + +namespace spreadsheet { namespace iface { + class import_styles; +}} + +/** + * Context for <style:style> element scope. + * + * This context populates one odf_style instance that represents a single set + * of style properties. + */ +class style_context : public xml_context_base +{ +public: + style_context(session_context& session_cxt, const tokens& tk, spreadsheet::iface::import_styles* iface_styles); + + void start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) override; + void characters(std::string_view str, bool transient) override; + bool end_element(xmlns_id_t ns, xml_token_t name) override; + + void reset(); + std::unique_ptr<odf_style> pop_style(); + +private: + void start_paragraph_properties(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs); + void start_text_properties(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs); + void start_table_cell_properties(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs); + +private: + spreadsheet::iface::import_styles* mp_styles = nullptr; + std::unique_ptr<odf_style> m_current_style; +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_styles.cpp b/src/liborcus/odf_styles.cpp new file mode 100644 index 0000000..814d468 --- /dev/null +++ b/src/liborcus/odf_styles.cpp @@ -0,0 +1,110 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "odf_styles.hpp" + +#include <stdexcept> + +namespace orcus { + +odf_style::odf_style() : family(style_family_unknown) {} +odf_style::odf_style(std::string_view _name, std::string_view _display_name, odf_style_family _family, std::string_view parent) : + name(_name), + display_name(_display_name), + family(_family), + parent_name(parent) +{ + switch (family) + { + case style_family_table_column: + data = column{}; + break; + case style_family_table_row: + data = row{}; + break; + case style_family_table_cell: + data = cell{}; + break; + case style_family_table: + data = table{}; + break; + case style_family_graphic: + data = graphic{}; + break; + case style_family_paragraph: + data = paragraph{}; + break; + case style_family_text: + data = text{}; + break; + case style_family_unknown: + throw std::invalid_argument("unkown style family is not allowed"); + } +} + +odf_style::~odf_style() {} + +odf_number_format::odf_number_format(std::string_view _name, bool _is_volatile): + name(_name), + is_volatile(_is_volatile) +{ +} + +void merge(odf_styles_map_type& dst, odf_styles_map_type& src) +{ + for (auto& [name, style] : src) + dst.insert_or_assign(name, std::move(style)); + + src.clear(); +} + +void dump_state(const odf_styles_map_type& styles_map, std::ostream& os) +{ + os << "styles picked up:\n"; + + auto it = styles_map.begin(), it_end = styles_map.end(); + for (; it != it_end; ++it) + { + os << " style: " << it->first << " [ "; + + switch (it->second->family) + { + case style_family_table_column: + { + const auto& data = std::get<odf_style::column>(it->second->data); + os << "column width: " << data.width.to_string(); + break; + } + case style_family_table_row: + { + const auto& data = std::get<odf_style::row>(it->second->data); + os << "row height: " << data.height.to_string(); + break; + } + case style_family_table_cell: + { + const auto& cell = std::get<odf_style::cell>(it->second->data); + os << "xf ID: " << cell.xf; + break; + } + case style_family_text: + { + const auto& data = std::get<odf_style::text>(it->second->data); + os << "font ID: " << data.font; + break; + } + default: + ; + } + + os << " ]\n"; + } +} + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_styles.hpp b/src/liborcus/odf_styles.hpp new file mode 100644 index 0000000..c4e5eaf --- /dev/null +++ b/src/liborcus/odf_styles.hpp @@ -0,0 +1,127 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_ODF_STYLES_HPP +#define INCLUDED_ORCUS_ODF_STYLES_HPP + +#include <orcus/measurement.hpp> +#include <orcus/spreadsheet/types.hpp> + +#include <map> +#include <memory> +#include <variant> +#include <ostream> +#include <optional> + +namespace orcus { + +enum odf_style_family +{ + style_family_unknown = 0, + style_family_table_column, + style_family_table_row, + style_family_table_cell, + style_family_table, + style_family_graphic, + style_family_paragraph, + style_family_text +}; + +/** + * Each instance of this class represents a single <style:style> entry. + */ +struct odf_style +{ + struct column + { + length_t width; + }; + + struct row + { + length_t height; + bool height_set = false; + }; + + struct cell + { + std::size_t font = 0; + std::size_t fill = 0; + std::size_t border = 0; + std::size_t protection = 0; + std::size_t xf = 0; + std::size_t number_format = 0; + spreadsheet::hor_alignment_t hor_align = spreadsheet::hor_alignment_t::unknown; + spreadsheet::ver_alignment_t ver_align = spreadsheet::ver_alignment_t::unknown; + std::optional<bool> wrap_text; + std::optional<bool> shrink_to_fit; + }; + + struct table + { + }; + + struct graphic + { + }; + + struct paragraph + { + spreadsheet::hor_alignment_t hor_align = spreadsheet::hor_alignment_t::unknown; + }; + + struct text + { + size_t font; + }; + + using data_type = std::variant<column, row, cell, table, graphic, paragraph, text>; + + std::string_view name; + std::string_view display_name; + odf_style_family family; + std::string_view parent_name; + + data_type data; + + odf_style(const odf_style&) = delete; + odf_style& operator=(const odf_style&) = delete; + + odf_style(); + odf_style(std::string_view _name, std::string_view _display_name, odf_style_family _family, std::string_view parent); + + ~odf_style(); +}; + +struct odf_number_format +{ + std::string_view name; + std::string code; + bool is_volatile = false; + + odf_number_format() = default; + odf_number_format(std::string_view _name, bool _is_volatile); +}; + +using odf_styles_map_type = std::map<std::string_view, std::unique_ptr<odf_style>>; + +/** + * Merge two styles collections into one. + * + * @param dst destination where all the styles will be stored when the call + * returns. + * @param src source collection to move all the styles from. After the call + * returns this one will be empty. + */ +void merge(odf_styles_map_type& dst, odf_styles_map_type& src); + +void dump_state(const odf_styles_map_type& styles_map, std::ostream& os); + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_styles_context.cpp b/src/liborcus/odf_styles_context.cpp new file mode 100644 index 0000000..cf2589d --- /dev/null +++ b/src/liborcus/odf_styles_context.cpp @@ -0,0 +1,403 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "odf_styles_context.hpp" +#include "odf_namespace_types.hpp" +#include "odf_token_constants.hpp" +#include "ods_session_data.hpp" +#include "impl_utils.hpp" + +#include <orcus/spreadsheet/import_interface_styles.hpp> +#include <iostream> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +styles_context::styles_context( + session_context& session_cxt, const tokens& tk, + spreadsheet::iface::import_styles* iface_styles) : + xml_context_base(session_cxt, tk), + mp_styles(iface_styles), + m_automatic_styles(false), + m_cxt_style(session_cxt, tk, mp_styles), + m_cxt_number_style(session_cxt, tk), + m_cxt_currency_style(session_cxt, tk), + m_cxt_boolean_style(session_cxt, tk), + m_cxt_text_style(session_cxt, tk), + m_cxt_percentage_style(session_cxt, tk), + m_cxt_date_style(session_cxt, tk), + m_cxt_time_style(session_cxt, tk) +{ + register_child(&m_cxt_style); + register_child(&m_cxt_number_style); + register_child(&m_cxt_currency_style); + register_child(&m_cxt_boolean_style); + register_child(&m_cxt_text_style); + register_child(&m_cxt_percentage_style); + register_child(&m_cxt_date_style); + register_child(&m_cxt_time_style); + + commit_default_styles(); +} + +xml_context_base* styles_context::create_child_context(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_odf_number) + { + switch (name) + { + case XML_number_style: + { + m_cxt_number_style.reset(); + return &m_cxt_number_style; + } + case XML_currency_style: + { + m_cxt_currency_style.reset(); + return &m_cxt_currency_style; + } + case XML_boolean_style: + { + m_cxt_boolean_style.reset(); + return &m_cxt_boolean_style; + } + case XML_text_style: + { + m_cxt_text_style.reset(); + return &m_cxt_text_style; + } + case XML_percentage_style: + { + m_cxt_percentage_style.reset(); + return &m_cxt_percentage_style; + } + case XML_date_style: + { + m_cxt_date_style.reset(); + return &m_cxt_date_style; + } + case XML_time_style: + { + m_cxt_time_style.reset(); + return &m_cxt_time_style; + } + } + } + + if (ns == NS_odf_style && name == XML_style) + { + m_cxt_style.reset(); + return &m_cxt_style; + } + + return nullptr; +} + +void styles_context::end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) +{ + if (ns == NS_odf_number) + { + switch (name) + { + case XML_number_style: + { + assert(child == &m_cxt_number_style); + push_number_style(m_cxt_number_style.pop_style()); + break; + } + case XML_currency_style: + { + assert(child == &m_cxt_currency_style); + push_number_style(m_cxt_currency_style.pop_style()); + break; + } + case XML_boolean_style: + { + assert(child == &m_cxt_boolean_style); + push_number_style(m_cxt_boolean_style.pop_style()); + break; + } + case XML_text_style: + { + assert(child == &m_cxt_text_style); + push_number_style(m_cxt_text_style.pop_style()); + break; + } + case XML_percentage_style: + { + assert(child == &m_cxt_percentage_style); + push_number_style(m_cxt_percentage_style.pop_style()); + break; + } + case XML_date_style: + { + assert(child == &m_cxt_date_style); + push_number_style(m_cxt_date_style.pop_style()); + break; + } + case XML_time_style: + { + assert(child == &m_cxt_time_style); + push_number_style(m_cxt_time_style.pop_style()); + break; + } + default:; + } + } + else if (ns == NS_odf_style && name == XML_style) + { + assert(child == &m_cxt_style); + std::unique_ptr<odf_style> current_style = m_cxt_style.pop_style(); + + std::optional<std::size_t> parent_xfid = query_parent_style_xfid(current_style->parent_name); + + if (mp_styles && current_style->family == style_family_table_cell) + { + auto& cell = std::get<odf_style::cell>(current_style->data); + + if (m_automatic_styles) + { + // Import it into the direct cell style store + auto* xf = mp_styles->start_xf(ss::xf_category_t::cell); + ENSURE_INTERFACE(xf, import_xf); + xf->set_font(cell.font); + xf->set_fill(cell.fill); + xf->set_border(cell.border); + xf->set_protection(cell.protection); + xf->set_number_format(cell.number_format); + + if (cell.hor_align != ss::hor_alignment_t::unknown) + xf->set_horizontal_alignment(cell.hor_align); + if (cell.ver_align != ss::ver_alignment_t::unknown) + xf->set_vertical_alignment(cell.ver_align); + if (cell.wrap_text) + xf->set_wrap_text(*cell.wrap_text); + if (cell.shrink_to_fit) + xf->set_shrink_to_fit(*cell.shrink_to_fit); + + if (parent_xfid) + xf->set_style_xf(*parent_xfid); + + cell.xf = xf->commit(); + } + else + { + // Import it into the cell style xf store, and reference + // its index in the cell style name store. + auto* xf = mp_styles->start_xf(ss::xf_category_t::cell_style); + ENSURE_INTERFACE(xf, import_xf); + xf->set_font(cell.font); + xf->set_fill(cell.fill); + xf->set_border(cell.border); + xf->set_protection(cell.protection); + xf->set_number_format(cell.number_format); + + if (cell.hor_align != ss::hor_alignment_t::unknown) + xf->set_horizontal_alignment(cell.hor_align); + if (cell.ver_align != ss::ver_alignment_t::unknown) + xf->set_vertical_alignment(cell.ver_align); + if (cell.wrap_text) + xf->set_wrap_text(*cell.wrap_text); + if (cell.shrink_to_fit) + xf->set_shrink_to_fit(*cell.shrink_to_fit); + + if (parent_xfid) + xf->set_style_xf(*parent_xfid); + + size_t style_xf_id = xf->commit(); + cell.xf = style_xf_id; + + auto* cell_style = mp_styles->start_cell_style(); + ENSURE_INTERFACE(cell_style, import_cell_style); + + if (!current_style->display_name.empty()) + cell_style->set_display_name(current_style->display_name); + + cell_style->set_name(current_style->name); + cell_style->set_xf(style_xf_id); + cell_style->set_parent_name(current_style->parent_name); + cell_style->commit(); + } + } + + std::string_view style_name = get_session_context().intern(current_style->name); + m_styles.emplace(style_name, std::move(current_style)); + } +} + +void styles_context::start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& /*attrs*/) +{ + xml_token_pair_t parent = push_stack(ns, name); + if (ns == NS_odf_office) + { + switch (name) + { + case XML_automatic_styles: + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + m_automatic_styles = true; + break; + case XML_styles: + m_automatic_styles = false; + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool styles_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + return pop_stack(ns, name); +} + +void styles_context::characters(std::string_view /*str*/, bool /*transient*/) +{ +} + +void styles_context::reset() +{ + m_styles.clear(); +} + +odf_styles_map_type styles_context::pop_styles() +{ + return std::move(m_styles); +} + +void styles_context::commit_default_styles() +{ + if (!mp_styles) + return; + + auto* font_style = mp_styles->start_font_style(); + ENSURE_INTERFACE(font_style, import_font_style); + + auto* fill_style = mp_styles->start_fill_style(); + ENSURE_INTERFACE(fill_style, import_fill_style); + + auto* border_style = mp_styles->start_border_style(); + ENSURE_INTERFACE(border_style, import_border_style); + + auto* cell_protection = mp_styles->start_cell_protection(); + ENSURE_INTERFACE(cell_protection, import_cell_protection); + + auto* number_format = mp_styles->start_number_format(); + ENSURE_INTERFACE(number_format, import_number_format); + + // Set default styles. Default styles must be associated with an index of 0. + // Set empty styles for all style types before importing real styles. + font_style->commit(); + fill_style->commit(); + border_style->commit(); + cell_protection->commit(); + number_format->commit(); + + auto* xf = mp_styles->start_xf(ss::xf_category_t::cell); + ENSURE_INTERFACE(xf, import_xf); + xf->commit(); + + xf = mp_styles->start_xf(ss::xf_category_t::cell_style); + ENSURE_INTERFACE(xf, import_xf); + xf->commit(); + + auto* cell_style = mp_styles->start_cell_style(); + ENSURE_INTERFACE(cell_style, import_cell_style); + cell_style->commit(); +} + +void styles_context::push_number_style(std::unique_ptr<odf_number_format> num_style) +{ + if (!mp_styles) + return; + + if (num_style->name.empty()) + { + warn("ignoring a number style with empty name."); + return; + } + + if (num_style->code.empty()) + { + std::ostringstream os; + os << "number style named '" << num_style->name << "' has empty code."; + warn(os.str()); + return; + } + + auto* number_format = mp_styles->start_number_format(); + ENSURE_INTERFACE(number_format, import_number_format); + + number_format->set_code(num_style->code); + std::size_t id = number_format->commit(); + + if (get_config().debug) + { + std::cerr << "number-style: name='" << num_style->name + << "'; code='" << num_style->code + << "'; id=" << id << std::endl; + } + + auto& sess_cxt = get_session_context(); + auto& numfmts_store = sess_cxt.get_data<ods_session_data>().number_formats; + + if (auto res = numfmts_store.name2id_map.insert_or_assign(sess_cxt.intern(num_style->name), id); !res.second) + { + std::ostringstream os; + os << "number style named '" << num_style->name << "' has been overwritten."; + warn(os.str()); + } + + if (auto res = numfmts_store.id2code_map.insert_or_assign(id, std::move(num_style->code)); !res.second) + { + std::ostringstream os; + os << "number style associated with the id of " << id << " has been overwritten."; + warn(os.str()); + } +} + +std::optional<std::size_t> styles_context::query_parent_style_xfid(std::string_view parent_name) const +{ + std::optional<std::size_t> parent_xfid; + + if (parent_name.empty()) + return parent_xfid; + + const ods_session_data& ods_data = get_session_context().get_data<ods_session_data>(); + + auto it = ods_data.styles_map.find(parent_name); + if (it == ods_data.styles_map.end()) + { + // Not found in the session store. Check the current styles map too. + auto it2 = m_styles.find(parent_name); + if (it2 != m_styles.end()) + { + const odf_style& s = *it2->second; + if (s.family == style_family_table_cell) + { + const odf_style::cell& c = std::get<odf_style::cell>(s.data); + parent_xfid = c.xf; + } + } + return parent_xfid; + } + + const odf_style& s = *it->second; + if (s.family != style_family_table_cell) + return parent_xfid; + + const odf_style::cell& c = std::get<odf_style::cell>(s.data); + parent_xfid = c.xf; + + return parent_xfid; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_styles_context.hpp b/src/liborcus/odf_styles_context.hpp new file mode 100644 index 0000000..01b2ac4 --- /dev/null +++ b/src/liborcus/odf_styles_context.hpp @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_ODF_STYLES_CONTEXT_HPP +#define ORCUS_ODF_STYLES_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "odf_styles.hpp" +#include "odf_style_context.hpp" +#include "odf_number_format_context.hpp" + +#include <unordered_map> + +namespace orcus { + +namespace spreadsheet { namespace iface { + class import_styles; +}} + +/** + * Context that handles <office:automatic-styles> or <office:styles> scope. + */ +class styles_context : public xml_context_base +{ +public: + styles_context( + session_context& session_cxt, const tokens& tk, spreadsheet::iface::import_styles* iface_styles); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name) override; + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) override; + virtual void start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) override; + virtual bool end_element(xmlns_id_t ns, xml_token_t name) override; + virtual void characters(std::string_view str, bool transient) override; + + void reset(); + odf_styles_map_type pop_styles(); + +private: + void commit_default_styles(); + + void push_number_style(std::unique_ptr<odf_number_format> num_style); + + std::optional<std::size_t> query_parent_style_xfid(std::string_view parent_name) const; + +private: + spreadsheet::iface::import_styles* mp_styles; + odf_styles_map_type m_styles; + + // an automatic style corresponds to a cell format and not a real style + bool m_automatic_styles; + + style_context m_cxt_style; + number_style_context m_cxt_number_style; + currency_style_context m_cxt_currency_style; + boolean_style_context m_cxt_boolean_style; + text_style_context m_cxt_text_style; + percentage_style_context m_cxt_percentage_style; + date_style_context m_cxt_date_style; + time_style_context m_cxt_time_style; +}; + +} // namespace orcus + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_token_constants.hpp b/src/liborcus/odf_token_constants.hpp new file mode 100644 index 0000000..71cf64b --- /dev/null +++ b/src/liborcus/odf_token_constants.hpp @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef __ORCUS_ODF_TOKEN_CONSTANTS_HPP__ +#define __ORCUS_ODF_TOKEN_CONSTANTS_HPP__ + +#include "orcus/types.hpp" + +namespace orcus { + +#include "odf_token_constants.inl" + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_token_constants.inl b/src/liborcus/odf_token_constants.inl new file mode 100644 index 0000000..868e465 --- /dev/null +++ b/src/liborcus/odf_token_constants.inl @@ -0,0 +1,2280 @@ +// This file has been auto-generated. Do not hand-edit this. + +const xml_token_t XML_0 = 1; +const xml_token_t XML_0deg = 2; +const xml_token_t XML_0grad = 3; +const xml_token_t XML_0rad = 4; +const xml_token_t XML_1 = 5; +const xml_token_t XML_1_3 = 6; +const xml_token_t XML_100 = 7; +const xml_token_t XML_2 = 8; +const xml_token_t XML_200 = 9; +const xml_token_t XML_3 = 10; +const xml_token_t XML_300 = 11; +const xml_token_t XML_3d = 12; +const xml_token_t XML_400 = 13; +const xml_token_t XML_500 = 14; +const xml_token_t XML_600 = 15; +const xml_token_t XML_700 = 16; +const xml_token_t XML_800 = 17; +const xml_token_t XML_900 = 18; +const xml_token_t XML_A = 19; +const xml_token_t XML_I = 20; +const xml_token_t XML_ROC = 21; +const xml_token_t XML__blank = 22; +const xml_token_t XML__parent = 23; +const xml_token_t XML__self = 24; +const xml_token_t XML__top = 25; +const xml_token_t XML_a = 26; +const xml_token_t XML_about = 27; +const xml_token_t XML_above = 28; +const xml_token_t XML_accelerate = 29; +const xml_token_t XML_accent = 30; +const xml_token_t XML_accent_height = 31; +const xml_token_t XML_acceptance_state = 32; +const xml_token_t XML_accepted = 33; +const xml_token_t XML_accumulate = 34; +const xml_token_t XML_action = 35; +const xml_token_t XML_active = 36; +const xml_token_t XML_actuate = 37; +const xml_token_t XML_add_empty_lines = 38; +const xml_token_t XML_additional_column_statement = 39; +const xml_token_t XML_additive = 40; +const xml_token_t XML_address = 41; +const xml_token_t XML_adjustment = 42; +const xml_token_t XML_after_previous = 43; +const xml_token_t XML_algorithm = 44; +const xml_token_t XML_align = 45; +const xml_token_t XML_all = 46; +const xml_token_t XML_allow_deletes = 47; +const xml_token_t XML_allow_empty_cell = 48; +const xml_token_t XML_allow_inserts = 49; +const xml_token_t XML_allow_updates = 50; +const xml_token_t XML_alpha_numeric = 51; +const xml_token_t XML_alphabetic = 52; +const xml_token_t XML_alphabetical_index = 53; +const xml_token_t XML_alphabetical_index_auto_mark_file = 54; +const xml_token_t XML_alphabetical_index_entry_template = 55; +const xml_token_t XML_alphabetical_index_mark = 56; +const xml_token_t XML_alphabetical_index_mark_end = 57; +const xml_token_t XML_alphabetical_index_mark_start = 58; +const xml_token_t XML_alphabetical_index_source = 59; +const xml_token_t XML_alphabetical_separators = 60; +const xml_token_t XML_alternate = 61; +const xml_token_t XML_always = 62; +const xml_token_t XML_am_pm = 63; +const xml_token_t XML_ambient_color = 64; +const xml_token_t XML_anchor_page_number = 65; +const xml_token_t XML_anchor_type = 66; +const xml_token_t XML_angle = 67; +const xml_token_t XML_angle_offset = 68; +const xml_token_t XML_angled_connector_line = 69; +const xml_token_t XML_angled_line = 70; +const xml_token_t XML_anim = 71; +const xml_token_t XML_animate = 72; +const xml_token_t XML_animateColor = 73; +const xml_token_t XML_animateMotion = 74; +const xml_token_t XML_animateTransform = 75; +const xml_token_t XML_animation = 76; +const xml_token_t XML_animation_delay = 77; +const xml_token_t XML_animation_direction = 78; +const xml_token_t XML_animation_group = 79; +const xml_token_t XML_animation_repeat = 80; +const xml_token_t XML_animation_start_inside = 81; +const xml_token_t XML_animation_steps = 82; +const xml_token_t XML_animation_stop_inside = 83; +const xml_token_t XML_animations = 84; +const xml_token_t XML_annotation = 85; +const xml_token_t XML_annotation_end = 86; +const xml_token_t XML_annotations = 87; +const xml_token_t XML_annote = 88; +const xml_token_t XML_appear = 89; +const xml_token_t XML_append_table_alias_name = 90; +const xml_token_t XML_applet = 91; +const xml_token_t XML_application_connection_settings = 92; +const xml_token_t XML_application_data = 93; +const xml_token_t XML_apply_command = 94; +const xml_token_t XML_apply_design_mode = 95; +const xml_token_t XML_apply_filter = 96; +const xml_token_t XML_apply_style_name = 97; +const xml_token_t XML_arc = 98; +const xml_token_t XML_archive = 99; +const xml_token_t XML_area = 100; +const xml_token_t XML_area_circle = 101; +const xml_token_t XML_area_polygon = 102; +const xml_token_t XML_area_rectangle = 103; +const xml_token_t XML_array = 104; +const xml_token_t XML_arrow_down = 105; +const xml_token_t XML_arrow_left = 106; +const xml_token_t XML_arrow_right = 107; +const xml_token_t XML_arrow_up = 108; +const xml_token_t XML_article = 109; +const xml_token_t XML_as_char = 110; +const xml_token_t XML_as_template = 111; +const xml_token_t XML_ascending = 112; +const xml_token_t XML_ascent = 113; +const xml_token_t XML_asian = 114; +const xml_token_t XML_asterisk = 115; +const xml_token_t XML_at_axis = 116; +const xml_token_t XML_at_labels = 117; +const xml_token_t XML_at_labels_and_axis = 118; +const xml_token_t XML_attached_axis = 119; +const xml_token_t XML_attractive = 120; +const xml_token_t XML_attributeName = 121; +const xml_token_t XML_audio = 122; +const xml_token_t XML_audio_level = 123; +const xml_token_t XML_author = 124; +const xml_token_t XML_author_initials = 125; +const xml_token_t XML_author_name = 126; +const xml_token_t XML_auto = 127; +const xml_token_t XML_auto_complete = 128; +const xml_token_t XML_auto_create_new_frame = 129; +const xml_token_t XML_auto_grow_height = 130; +const xml_token_t XML_auto_grow_width = 131; +const xml_token_t XML_auto_increment = 132; +const xml_token_t XML_auto_position = 133; +const xml_token_t XML_auto_reload = 134; +const xml_token_t XML_auto_size = 135; +const xml_token_t XML_auto_text_indent = 136; +const xml_token_t XML_auto_update = 137; +const xml_token_t XML_autoReverse = 138; +const xml_token_t XML_automatic = 139; +const xml_token_t XML_automatic_content = 140; +const xml_token_t XML_automatic_find_labels = 141; +const xml_token_t XML_automatic_focus = 142; +const xml_token_t XML_automatic_order = 143; +const xml_token_t XML_automatic_styles = 144; +const xml_token_t XML_automatic_update = 145; +const xml_token_t XML_average = 146; +const xml_token_t XML_averaged_abscissa = 147; +const xml_token_t XML_avoid_overlap = 148; +const xml_token_t XML_axial = 149; +const xml_token_t XML_axis = 150; +const xml_token_t XML_axis_label_position = 151; +const xml_token_t XML_axis_position = 152; +const xml_token_t XML_b_spline = 153; +const xml_token_t XML_back_scale = 154; +const xml_token_t XML_backface_culling = 155; +const xml_token_t XML_background = 156; +const xml_token_t XML_background_color = 157; +const xml_token_t XML_background_image = 158; +const xml_token_t XML_background_objects_visible = 159; +const xml_token_t XML_background_size = 160; +const xml_token_t XML_background_transparency = 161; +const xml_token_t XML_background_visible = 162; +const xml_token_t XML_balanced = 163; +const xml_token_t XML_base_cell_address = 164; +const xml_token_t XML_base_dn = 165; +const xml_token_t XML_base64Binary = 166; +const xml_token_t XML_baseline = 167; +const xml_token_t XML_bbox = 168; +const xml_token_t XML_begin = 169; +const xml_token_t XML_below = 170; +const xml_token_t XML_bevel = 171; +const xml_token_t XML_bibliography = 172; +const xml_token_t XML_bibliography_configuration = 173; +const xml_token_t XML_bibliography_data_field = 174; +const xml_token_t XML_bibliography_entry_template = 175; +const xml_token_t XML_bibliography_mark = 176; +const xml_token_t XML_bibliography_source = 177; +const xml_token_t XML_bibliography_type = 178; +const xml_token_t XML_biggest = 179; +const xml_token_t XML_bigint = 180; +const xml_token_t XML_binary = 181; +const xml_token_t XML_binary_data = 182; +const xml_token_t XML_bind = 183; +const xml_token_t XML_bind_styles_to_content = 184; +const xml_token_t XML_bit = 185; +const xml_token_t XML_bitmap = 186; +const xml_token_t XML_blend = 187; +const xml_token_t XML_blob = 188; +const xml_token_t XML_blue = 189; +const xml_token_t XML_body = 190; +const xml_token_t XML_bold = 191; +const xml_token_t XML_book = 192; +const xml_token_t XML_booklet = 193; +const xml_token_t XML_bookmark = 194; +const xml_token_t XML_bookmark_end = 195; +const xml_token_t XML_bookmark_start = 196; +const xml_token_t XML_booktitle = 197; +const xml_token_t XML_boolean = 198; +const xml_token_t XML_boolean_comparison_mode = 199; +const xml_token_t XML_boolean_style = 200; +const xml_token_t XML_boolean_value = 201; +const xml_token_t XML_border = 202; +const xml_token_t XML_border_bottom = 203; +const xml_token_t XML_border_color = 204; +const xml_token_t XML_border_left = 205; +const xml_token_t XML_border_line_width = 206; +const xml_token_t XML_border_line_width_bottom = 207; +const xml_token_t XML_border_line_width_left = 208; +const xml_token_t XML_border_line_width_right = 209; +const xml_token_t XML_border_line_width_top = 210; +const xml_token_t XML_border_model = 211; +const xml_token_t XML_border_right = 212; +const xml_token_t XML_border_top = 213; +const xml_token_t XML_both = 214; +const xml_token_t XML_bottom = 215; +const xml_token_t XML_bottom_end = 216; +const xml_token_t XML_bottom_left = 217; +const xml_token_t XML_bottom_right = 218; +const xml_token_t XML_bottom_start = 219; +const xml_token_t XML_bound_column = 220; +const xml_token_t XML_bow_tie = 221; +const xml_token_t XML_break_after = 222; +const xml_token_t XML_break_before = 223; +const xml_token_t XML_buddhist = 224; +const xml_token_t XML_bullet_char = 225; +const xml_token_t XML_bullet_relative_size = 226; +const xml_token_t XML_butt = 227; +const xml_token_t XML_button = 228; +const xml_token_t XML_button_type = 229; +const xml_token_t XML_buttons = 230; +const xml_token_t XML_by = 231; +const xml_token_t XML_c = 232; +const xml_token_t XML_calcMode = 233; +const xml_token_t XML_calculation_settings = 234; +const xml_token_t XML_calendar = 235; +const xml_token_t XML_cap_height = 236; +const xml_token_t XML_capitalize = 237; +const xml_token_t XML_capitalize_entries = 238; +const xml_token_t XML_caption = 239; +const xml_token_t XML_caption_angle = 240; +const xml_token_t XML_caption_angle_type = 241; +const xml_token_t XML_caption_escape = 242; +const xml_token_t XML_caption_escape_direction = 243; +const xml_token_t XML_caption_fit_line_length = 244; +const xml_token_t XML_caption_gap = 245; +const xml_token_t XML_caption_id = 246; +const xml_token_t XML_caption_line_length = 247; +const xml_token_t XML_caption_point_x = 248; +const xml_token_t XML_caption_point_y = 249; +const xml_token_t XML_caption_sequence_format = 250; +const xml_token_t XML_caption_sequence_name = 251; +const xml_token_t XML_caption_type = 252; +const xml_token_t XML_cascade = 253; +const xml_token_t XML_case_sensitive = 254; +const xml_token_t XML_catalog_name = 255; +const xml_token_t XML_categories = 256; +const xml_token_t XML_category_and_value = 257; +const xml_token_t XML_cell_address = 258; +const xml_token_t XML_cell_content_change = 259; +const xml_token_t XML_cell_content_deletion = 260; +const xml_token_t XML_cell_count = 261; +const xml_token_t XML_cell_protect = 262; +const xml_token_t XML_cell_range = 263; +const xml_token_t XML_cell_range_address = 264; +const xml_token_t XML_cell_range_source = 265; +const xml_token_t XML_center = 266; +const xml_token_t XML_central = 267; +const xml_token_t XML_chain_next_name = 268; +const xml_token_t XML_change = 269; +const xml_token_t XML_change_deletion = 270; +const xml_token_t XML_change_end = 271; +const xml_token_t XML_change_id = 272; +const xml_token_t XML_change_info = 273; +const xml_token_t XML_change_start = 274; +const xml_token_t XML_change_track_table_cell = 275; +const xml_token_t XML_changed_region = 276; +const xml_token_t XML_chapter = 277; +const xml_token_t XML_char = 278; +const xml_token_t XML_character_count = 279; +const xml_token_t XML_character_set = 280; +const xml_token_t XML_chart = 281; +const xml_token_t XML_chart_properties = 282; +const xml_token_t XML_charts = 283; +const xml_token_t XML_checkbox = 284; +const xml_token_t XML_checked = 285; +const xml_token_t XML_checkerboard = 286; +const xml_token_t XML_circle = 287; +const xml_token_t XML_citation_body_style_name = 288; +const xml_token_t XML_citation_style_name = 289; +const xml_token_t XML_class = 290; +const xml_token_t XML_class_id = 291; +const xml_token_t XML_class_names = 292; +const xml_token_t XML_clip = 293; +const xml_token_t XML_clob = 294; +const xml_token_t XML_clockwise = 295; +const xml_token_t XML_close = 296; +const xml_token_t XML_close_back = 297; +const xml_token_t XML_close_front = 298; +const xml_token_t XML_close_horizontal = 299; +const xml_token_t XML_close_vertical = 300; +const xml_token_t XML_cm = 301; +const xml_token_t XML_code = 302; +const xml_token_t XML_collapse = 303; +const xml_token_t XML_collapsing = 304; +const xml_token_t XML_color = 305; +const xml_token_t XML_color_interpolation = 306; +const xml_token_t XML_color_interpolation_direction = 307; +const xml_token_t XML_color_inversion = 308; +const xml_token_t XML_color_mode = 309; +const xml_token_t XML_column = 310; +const xml_token_t XML_column_count = 311; +const xml_token_t XML_column_definition = 312; +const xml_token_t XML_column_definitions = 313; +const xml_token_t XML_column_gap = 314; +const xml_token_t XML_column_mapping = 315; +const xml_token_t XML_column_name = 316; +const xml_token_t XML_column_percentage = 317; +const xml_token_t XML_column_sep = 318; +const xml_token_t XML_column_width = 319; +const xml_token_t XML_columns = 320; +const xml_token_t XML_combine_entries = 321; +const xml_token_t XML_combine_entries_with_dash = 322; +const xml_token_t XML_combine_entries_with_pp = 323; +const xml_token_t XML_combobox = 324; +const xml_token_t XML_comma_separated = 325; +const xml_token_t XML_command = 326; +const xml_token_t XML_command_type = 327; +const xml_token_t XML_comment = 328; +const xml_token_t XML_complex = 329; +const xml_token_t XML_component = 330; +const xml_token_t XML_component_collection = 331; +const xml_token_t XML_concave = 332; +const xml_token_t XML_concentric_gradient_fill_allowed = 333; +const xml_token_t XML_cond_style_name = 334; +const xml_token_t XML_condensed = 335; +const xml_token_t XML_condition = 336; +const xml_token_t XML_condition_source = 337; +const xml_token_t XML_condition_source_range_address = 338; +const xml_token_t XML_conditional_text = 339; +const xml_token_t XML_cone = 340; +const xml_token_t XML_conference = 341; +const xml_token_t XML_config = 342; +const xml_token_t XML_config_item = 343; +const xml_token_t XML_config_item_map_entry = 344; +const xml_token_t XML_config_item_map_indexed = 345; +const xml_token_t XML_config_item_map_named = 346; +const xml_token_t XML_config_item_set = 347; +const xml_token_t XML_connect_bars = 348; +const xml_token_t XML_connection_data = 349; +const xml_token_t XML_connection_name = 350; +const xml_token_t XML_connection_resource = 351; +const xml_token_t XML_connector = 352; +const xml_token_t XML_consecutive_numbering = 353; +const xml_token_t XML_consolidation = 354; +const xml_token_t XML_constant = 355; +const xml_token_t XML_contains_error = 356; +const xml_token_t XML_contains_header = 357; +const xml_token_t XML_content = 358; +const xml_token_t XML_content_validation = 359; +const xml_token_t XML_content_validation_name = 360; +const xml_token_t XML_content_validations = 361; +const xml_token_t XML_contextual_spacing = 362; +const xml_token_t XML_continue = 363; +const xml_token_t XML_continue_list = 364; +const xml_token_t XML_continue_numbering = 365; +const xml_token_t XML_continuous = 366; +const xml_token_t XML_contour_path = 367; +const xml_token_t XML_contour_polygon = 368; +const xml_token_t XML_contrast = 369; +const xml_token_t XML_control = 370; +const xml_token_t XML_control_implementation = 371; +const xml_token_t XML_conversion_mode = 372; +const xml_token_t XML_convert_empty_to_null = 373; +const xml_token_t XML_coordinate_region = 374; +const xml_token_t XML_copy_all = 375; +const xml_token_t XML_copy_back = 376; +const xml_token_t XML_copy_formulas = 377; +const xml_token_t XML_copy_of = 378; +const xml_token_t XML_copy_outline_levels = 379; +const xml_token_t XML_copy_results_only = 380; +const xml_token_t XML_copy_styles = 381; +const xml_token_t XML_corner_radius = 382; +const xml_token_t XML_corners = 383; +const xml_token_t XML_correct = 384; +const xml_token_t XML_count = 385; +const xml_token_t XML_count_empty_lines = 386; +const xml_token_t XML_count_in_text_boxes = 387; +const xml_token_t XML_counter_clockwise = 388; +const xml_token_t XML_counterclockwise = 389; +const xml_token_t XML_countnums = 390; +const xml_token_t XML_country = 391; +const xml_token_t XML_country_asian = 392; +const xml_token_t XML_country_complex = 393; +const xml_token_t XML_covered_table_cell = 394; +const xml_token_t XML_creation_date = 395; +const xml_token_t XML_creation_time = 396; +const xml_token_t XML_creator = 397; +const xml_token_t XML_creator_initials = 398; +const xml_token_t XML_cube = 399; +const xml_token_t XML_cubic_spline = 400; +const xml_token_t XML_cuboid = 401; +const xml_token_t XML_currency = 402; +const xml_token_t XML_currency_style = 403; +const xml_token_t XML_currency_symbol = 404; +const xml_token_t XML_current = 405; +const xml_token_t XML_current_date = 406; +const xml_token_t XML_current_selected = 407; +const xml_token_t XML_current_state = 408; +const xml_token_t XML_current_value = 409; +const xml_token_t XML_curve = 410; +const xml_token_t XML_custom = 411; +const xml_token_t XML_custom_shape = 412; +const xml_token_t XML_custom1 = 413; +const xml_token_t XML_custom2 = 414; +const xml_token_t XML_custom3 = 415; +const xml_token_t XML_custom4 = 416; +const xml_token_t XML_custom5 = 417; +const xml_token_t XML_cut = 418; +const xml_token_t XML_cut_offs = 419; +const xml_token_t XML_cx = 420; +const xml_token_t XML_cy = 421; +const xml_token_t XML_cylinder = 422; +const xml_token_t XML_d = 423; +const xml_token_t XML_dash = 424; +const xml_token_t XML_dashed = 425; +const xml_token_t XML_data = 426; +const xml_token_t XML_data_cell_range_address = 427; +const xml_token_t XML_data_field = 428; +const xml_token_t XML_data_label = 429; +const xml_token_t XML_data_label_number = 430; +const xml_token_t XML_data_label_series = 431; +const xml_token_t XML_data_label_symbol = 432; +const xml_token_t XML_data_label_text = 433; +const xml_token_t XML_data_pilot_display_info = 434; +const xml_token_t XML_data_pilot_field = 435; +const xml_token_t XML_data_pilot_field_reference = 436; +const xml_token_t XML_data_pilot_group = 437; +const xml_token_t XML_data_pilot_group_member = 438; +const xml_token_t XML_data_pilot_groups = 439; +const xml_token_t XML_data_pilot_layout_info = 440; +const xml_token_t XML_data_pilot_level = 441; +const xml_token_t XML_data_pilot_member = 442; +const xml_token_t XML_data_pilot_members = 443; +const xml_token_t XML_data_pilot_sort_info = 444; +const xml_token_t XML_data_pilot_subtotal = 445; +const xml_token_t XML_data_pilot_subtotals = 446; +const xml_token_t XML_data_pilot_table = 447; +const xml_token_t XML_data_pilot_tables = 448; +const xml_token_t XML_data_point = 449; +const xml_token_t XML_data_source = 450; +const xml_token_t XML_data_source_has_labels = 451; +const xml_token_t XML_data_source_setting = 452; +const xml_token_t XML_data_source_setting_is_list = 453; +const xml_token_t XML_data_source_setting_name = 454; +const xml_token_t XML_data_source_setting_type = 455; +const xml_token_t XML_data_source_setting_value = 456; +const xml_token_t XML_data_source_settings = 457; +const xml_token_t XML_data_style_name = 458; +const xml_token_t XML_data_type = 459; +const xml_token_t XML_database = 460; +const xml_token_t XML_database_description = 461; +const xml_token_t XML_database_display = 462; +const xml_token_t XML_database_name = 463; +const xml_token_t XML_database_next = 464; +const xml_token_t XML_database_range = 465; +const xml_token_t XML_database_ranges = 466; +const xml_token_t XML_database_row_number = 467; +const xml_token_t XML_database_row_select = 468; +const xml_token_t XML_database_source_query = 469; +const xml_token_t XML_database_source_sql = 470; +const xml_token_t XML_database_source_table = 471; +const xml_token_t XML_database_table_name = 472; +const xml_token_t XML_datasource = 473; +const xml_token_t XML_datatype = 474; +const xml_token_t XML_date = 475; +const xml_token_t XML_date_adjust = 476; +const xml_token_t XML_date_end = 477; +const xml_token_t XML_date_start = 478; +const xml_token_t XML_date_string = 479; +const xml_token_t XML_date_style = 480; +const xml_token_t XML_date_time = 481; +const xml_token_t XML_date_time_decl = 482; +const xml_token_t XML_date_value = 483; +const xml_token_t XML_datetime = 484; +const xml_token_t XML_day = 485; +const xml_token_t XML_day_of_week = 486; +const xml_token_t XML_days = 487; +const xml_token_t XML_db = 488; +const xml_token_t XML_dc = 489; +const xml_token_t XML_dde_application = 490; +const xml_token_t XML_dde_connection = 491; +const xml_token_t XML_dde_connection_decl = 492; +const xml_token_t XML_dde_connection_decls = 493; +const xml_token_t XML_dde_item = 494; +const xml_token_t XML_dde_link = 495; +const xml_token_t XML_dde_links = 496; +const xml_token_t XML_dde_source = 497; +const xml_token_t XML_dde_topic = 498; +const xml_token_t XML_decelerate = 499; +const xml_token_t XML_decimal = 500; +const xml_token_t XML_decimal_places = 501; +const xml_token_t XML_decimal_replacement = 502; +const xml_token_t XML_decorative = 503; +const xml_token_t XML_deep = 504; +const xml_token_t XML_default = 505; +const xml_token_t XML_default_button = 506; +const xml_token_t XML_default_cell_style_name = 507; +const xml_token_t XML_default_outline_level = 508; +const xml_token_t XML_default_page_layout = 509; +const xml_token_t XML_default_row_style_name = 510; +const xml_token_t XML_default_style = 511; +const xml_token_t XML_default_style_name = 512; +const xml_token_t XML_definition_src = 513; +const xml_token_t XML_delay = 514; +const xml_token_t XML_delay_for_repeat = 515; +const xml_token_t XML_delete_rule = 516; +const xml_token_t XML_deletion = 517; +const xml_token_t XML_deletions = 518; +const xml_token_t XML_delimiter = 519; +const xml_token_t XML_denominator_value = 520; +const xml_token_t XML_dependencies = 521; +const xml_token_t XML_dependency = 522; +const xml_token_t XML_depth = 523; +const xml_token_t XML_desc = 524; +const xml_token_t XML_descending = 525; +const xml_token_t XML_descent = 526; +const xml_token_t XML_description = 527; +const xml_token_t XML_detail_fields = 528; +const xml_token_t XML_detective = 529; +const xml_token_t XML_diagonal_bl_tr = 530; +const xml_token_t XML_diagonal_bl_tr_widths = 531; +const xml_token_t XML_diagonal_tl_br = 532; +const xml_token_t XML_diagonal_tl_br_widths = 533; +const xml_token_t XML_diamond = 534; +const xml_token_t XML_diffuse_color = 535; +const xml_token_t XML_dim = 536; +const xml_token_t XML_dimension = 537; +const xml_token_t XML_direction = 538; +const xml_token_t XML_disable = 539; +const xml_token_t XML_disabled = 540; +const xml_token_t XML_disc = 541; +const xml_token_t XML_discrete = 542; +const xml_token_t XML_display = 543; +const xml_token_t XML_display_border = 544; +const xml_token_t XML_display_date_time = 545; +const xml_token_t XML_display_duplicates = 546; +const xml_token_t XML_display_equation = 547; +const xml_token_t XML_display_factor = 548; +const xml_token_t XML_display_filter_buttons = 549; +const xml_token_t XML_display_footer = 550; +const xml_token_t XML_display_header = 551; +const xml_token_t XML_display_label = 552; +const xml_token_t XML_display_levels = 553; +const xml_token_t XML_display_list = 554; +const xml_token_t XML_display_member_mode = 555; +const xml_token_t XML_display_name = 556; +const xml_token_t XML_display_outline_level = 557; +const xml_token_t XML_display_page_number = 558; +const xml_token_t XML_display_r_square = 559; +const xml_token_t XML_dissolve = 560; +const xml_token_t XML_distance = 561; +const xml_token_t XML_distance_after_sep = 562; +const xml_token_t XML_distance_before_sep = 563; +const xml_token_t XML_distinct = 564; +const xml_token_t XML_distribute_letter = 565; +const xml_token_t XML_distribute_space = 566; +const xml_token_t XML_document = 567; +const xml_token_t XML_document_content = 568; +const xml_token_t XML_document_meta = 569; +const xml_token_t XML_document_settings = 570; +const xml_token_t XML_document_statistic = 571; +const xml_token_t XML_document_styles = 572; +const xml_token_t XML_domain = 573; +const xml_token_t XML_dont_balance_text_columns = 574; +const xml_token_t XML_dot = 575; +const xml_token_t XML_dot_dash = 576; +const xml_token_t XML_dot_dashed = 577; +const xml_token_t XML_dot_dot_dash = 578; +const xml_token_t XML_dots1 = 579; +const xml_token_t XML_dots1_length = 580; +const xml_token_t XML_dots2 = 581; +const xml_token_t XML_dots2_length = 582; +const xml_token_t XML_dotted = 583; +const xml_token_t XML_double = 584; +const xml_token_t XML_double_sided = 585; +const xml_token_t XML_down = 586; +const xml_token_t XML_dr3d = 587; +const xml_token_t XML_draft = 588; +const xml_token_t XML_draw = 589; +const xml_token_t XML_draw_aspect = 590; +const xml_token_t XML_draw_count = 591; +const xml_token_t XML_drawing = 592; +const xml_token_t XML_drawing_page = 593; +const xml_token_t XML_drawing_page_properties = 594; +const xml_token_t XML_drawings = 595; +const xml_token_t XML_drill_down_on_double_click = 596; +const xml_token_t XML_driver_settings = 597; +const xml_token_t XML_drop_cap = 598; +const xml_token_t XML_drop_down = 599; +const xml_token_t XML_dropdown = 600; +const xml_token_t XML_dur = 601; +const xml_token_t XML_duration = 602; +const xml_token_t XML_dynamic = 603; +const xml_token_t XML_dynamic_spacing = 604; +const xml_token_t XML_echo_char = 605; +const xml_token_t XML_edge_rounding = 606; +const xml_token_t XML_edge_rounding_mode = 607; +const xml_token_t XML_editable = 608; +const xml_token_t XML_editing_cycles = 609; +const xml_token_t XML_editing_duration = 610; +const xml_token_t XML_edition = 611; +const xml_token_t XML_editor = 612; +const xml_token_t XML_effect = 613; +const xml_token_t XML_ellipse = 614; +const xml_token_t XML_ellipsoid = 615; +const xml_token_t XML_email = 616; +const xml_token_t XML_embed = 617; +const xml_token_t XML_embedded_number_behavior = 618; +const xml_token_t XML_embedded_text = 619; +const xml_token_t XML_embossed = 620; +const xml_token_t XML_emissive_color = 621; +const xml_token_t XML_emphasis = 622; +const xml_token_t XML_enable = 623; +const xml_token_t XML_enable_sql92_check = 624; +const xml_token_t XML_enabled = 625; +const xml_token_t XML_encoding = 626; +const xml_token_t XML_enctype = 627; +const xml_token_t XML_end = 628; +const xml_token_t XML_end_angle = 629; +const xml_token_t XML_end_cell_address = 630; +const xml_token_t XML_end_color = 631; +const xml_token_t XML_end_column = 632; +const xml_token_t XML_end_glue_point = 633; +const xml_token_t XML_end_guide = 634; +const xml_token_t XML_end_indent = 635; +const xml_token_t XML_end_intensity = 636; +const xml_token_t XML_end_line_spacing_horizontal = 637; +const xml_token_t XML_end_line_spacing_vertical = 638; +const xml_token_t XML_end_position = 639; +const xml_token_t XML_end_row = 640; +const xml_token_t XML_end_shape = 641; +const xml_token_t XML_end_table = 642; +const xml_token_t XML_end_x = 643; +const xml_token_t XML_end_y = 644; +const xml_token_t XML_endless = 645; +const xml_token_t XML_endnote = 646; +const xml_token_t XML_endsync = 647; +const xml_token_t XML_engine = 648; +const xml_token_t XML_engraved = 649; +const xml_token_t XML_enhanced_geometry = 650; +const xml_token_t XML_enhanced_path = 651; +const xml_token_t XML_entrance = 652; +const xml_token_t XML_equal_boolean = 653; +const xml_token_t XML_equal_integer = 654; +const xml_token_t XML_equal_use_only_zero = 655; +const xml_token_t XML_equation = 656; +const xml_token_t XML_era = 657; +const xml_token_t XML_error_category = 658; +const xml_token_t XML_error_indicator = 659; +const xml_token_t XML_error_lower_indicator = 660; +const xml_token_t XML_error_lower_limit = 661; +const xml_token_t XML_error_lower_range = 662; +const xml_token_t XML_error_macro = 663; +const xml_token_t XML_error_margin = 664; +const xml_token_t XML_error_message = 665; +const xml_token_t XML_error_percentage = 666; +const xml_token_t XML_error_upper_indicator = 667; +const xml_token_t XML_error_upper_limit = 668; +const xml_token_t XML_error_upper_range = 669; +const xml_token_t XML_escape_direction = 670; +const xml_token_t XML_escape_processing = 671; +const xml_token_t XML_even_columns = 672; +const xml_token_t XML_even_rows = 673; +const xml_token_t XML_evenodd = 674; +const xml_token_t XML_event_listener = 675; +const xml_token_t XML_event_listeners = 676; +const xml_token_t XML_event_name = 677; +const xml_token_t XML_execute = 678; +const xml_token_t XML_execute_macro = 679; +const xml_token_t XML_exit = 680; +const xml_token_t XML_expanded = 681; +const xml_token_t XML_exponent_interval = 682; +const xml_token_t XML_exponential = 683; +const xml_token_t XML_expression = 684; +const xml_token_t XML_extension = 685; +const xml_token_t XML_extra_condensed = 686; +const xml_token_t XML_extra_expanded = 687; +const xml_token_t XML_extrude = 688; +const xml_token_t XML_extrusion = 689; +const xml_token_t XML_extrusion_allowed = 690; +const xml_token_t XML_extrusion_brightness = 691; +const xml_token_t XML_extrusion_color = 692; +const xml_token_t XML_extrusion_depth = 693; +const xml_token_t XML_extrusion_diffusion = 694; +const xml_token_t XML_extrusion_first_light_direction = 695; +const xml_token_t XML_extrusion_first_light_harsh = 696; +const xml_token_t XML_extrusion_first_light_level = 697; +const xml_token_t XML_extrusion_light_face = 698; +const xml_token_t XML_extrusion_metal = 699; +const xml_token_t XML_extrusion_number_of_line_segments = 700; +const xml_token_t XML_extrusion_origin = 701; +const xml_token_t XML_extrusion_rotation_angle = 702; +const xml_token_t XML_extrusion_rotation_center = 703; +const xml_token_t XML_extrusion_second_light_direction = 704; +const xml_token_t XML_extrusion_second_light_harsh = 705; +const xml_token_t XML_extrusion_second_light_level = 706; +const xml_token_t XML_extrusion_shininess = 707; +const xml_token_t XML_extrusion_skew = 708; +const xml_token_t XML_extrusion_specularity = 709; +const xml_token_t XML_extrusion_viewpoint = 710; +const xml_token_t XML_fade = 711; +const xml_token_t XML_fade_from_bottom = 712; +const xml_token_t XML_fade_from_center = 713; +const xml_token_t XML_fade_from_left = 714; +const xml_token_t XML_fade_from_lowerleft = 715; +const xml_token_t XML_fade_from_lowerright = 716; +const xml_token_t XML_fade_from_right = 717; +const xml_token_t XML_fade_from_top = 718; +const xml_token_t XML_fade_from_upperleft = 719; +const xml_token_t XML_fade_from_upperright = 720; +const xml_token_t XML_fade_out = 721; +const xml_token_t XML_fade_to_center = 722; +const xml_token_t XML_fadeColor = 723; +const xml_token_t XML_false = 724; +const xml_token_t XML_family = 725; +const xml_token_t XML_fast = 726; +const xml_token_t XML_field = 727; +const xml_token_t XML_field_name = 728; +const xml_token_t XML_field_number = 729; +const xml_token_t XML_file = 730; +const xml_token_t XML_file_based_database = 731; +const xml_token_t XML_file_name = 732; +const xml_token_t XML_fill = 733; +const xml_token_t XML_fill_character = 734; +const xml_token_t XML_fill_color = 735; +const xml_token_t XML_fill_gradient_name = 736; +const xml_token_t XML_fill_hatch_name = 737; +const xml_token_t XML_fill_hatch_solid = 738; +const xml_token_t XML_fill_image = 739; +const xml_token_t XML_fill_image_height = 740; +const xml_token_t XML_fill_image_name = 741; +const xml_token_t XML_fill_image_ref_point = 742; +const xml_token_t XML_fill_image_ref_point_x = 743; +const xml_token_t XML_fill_image_ref_point_y = 744; +const xml_token_t XML_fill_image_width = 745; +const xml_token_t XML_fill_rule = 746; +const xml_token_t XML_fillDefault = 747; +const xml_token_t XML_filter = 748; +const xml_token_t XML_filter_and = 749; +const xml_token_t XML_filter_condition = 750; +const xml_token_t XML_filter_name = 751; +const xml_token_t XML_filter_options = 752; +const xml_token_t XML_filter_or = 753; +const xml_token_t XML_filter_set_item = 754; +const xml_token_t XML_filter_statement = 755; +const xml_token_t XML_first = 756; +const xml_token_t XML_first_column = 757; +const xml_token_t XML_first_page = 758; +const xml_token_t XML_first_page_number = 759; +const xml_token_t XML_first_row = 760; +const xml_token_t XML_first_row_end_column = 761; +const xml_token_t XML_first_row_start_column = 762; +const xml_token_t XML_fit_to_contour = 763; +const xml_token_t XML_fit_to_size = 764; +const xml_token_t XML_fix = 765; +const xml_token_t XML_fixed = 766; +const xml_token_t XML_fixed_text = 767; +const xml_token_t XML_flat = 768; +const xml_token_t XML_float = 769; +const xml_token_t XML_floating_frame = 770; +const xml_token_t XML_floor = 771; +const xml_token_t XML_flow_with_text = 772; +const xml_token_t XML_fly_away = 773; +const xml_token_t XML_fo = 774; +const xml_token_t XML_focal_length = 775; +const xml_token_t XML_focus_on_click = 776; +const xml_token_t XML_font_adornments = 777; +const xml_token_t XML_font_charset = 778; +const xml_token_t XML_font_charset_asian = 779; +const xml_token_t XML_font_charset_complex = 780; +const xml_token_t XML_font_color = 781; +const xml_token_t XML_font_face = 782; +const xml_token_t XML_font_face_decls = 783; +const xml_token_t XML_font_face_format = 784; +const xml_token_t XML_font_face_name = 785; +const xml_token_t XML_font_face_src = 786; +const xml_token_t XML_font_face_uri = 787; +const xml_token_t XML_font_family = 788; +const xml_token_t XML_font_family_asian = 789; +const xml_token_t XML_font_family_complex = 790; +const xml_token_t XML_font_family_generic = 791; +const xml_token_t XML_font_family_generic_asian = 792; +const xml_token_t XML_font_family_generic_complex = 793; +const xml_token_t XML_font_independent_line_spacing = 794; +const xml_token_t XML_font_name = 795; +const xml_token_t XML_font_name_asian = 796; +const xml_token_t XML_font_name_complex = 797; +const xml_token_t XML_font_pitch = 798; +const xml_token_t XML_font_pitch_asian = 799; +const xml_token_t XML_font_pitch_complex = 800; +const xml_token_t XML_font_relief = 801; +const xml_token_t XML_font_size = 802; +const xml_token_t XML_font_size_asian = 803; +const xml_token_t XML_font_size_complex = 804; +const xml_token_t XML_font_size_rel = 805; +const xml_token_t XML_font_size_rel_asian = 806; +const xml_token_t XML_font_size_rel_complex = 807; +const xml_token_t XML_font_stretch = 808; +const xml_token_t XML_font_style = 809; +const xml_token_t XML_font_style_asian = 810; +const xml_token_t XML_font_style_complex = 811; +const xml_token_t XML_font_style_name = 812; +const xml_token_t XML_font_style_name_asian = 813; +const xml_token_t XML_font_style_name_complex = 814; +const xml_token_t XML_font_variant = 815; +const xml_token_t XML_font_weight = 816; +const xml_token_t XML_font_weight_asian = 817; +const xml_token_t XML_font_weight_complex = 818; +const xml_token_t XML_footer = 819; +const xml_token_t XML_footer_decl = 820; +const xml_token_t XML_footer_first = 821; +const xml_token_t XML_footer_left = 822; +const xml_token_t XML_footer_style = 823; +const xml_token_t XML_footnote = 824; +const xml_token_t XML_footnote_max_height = 825; +const xml_token_t XML_footnote_sep = 826; +const xml_token_t XML_footnotes_position = 827; +const xml_token_t XML_for = 828; +const xml_token_t XML_force_manual = 829; +const xml_token_t XML_forced_exponent_sign = 830; +const xml_token_t XML_foreground = 831; +const xml_token_t XML_foreign = 832; +const xml_token_t XML_form = 833; +const xml_token_t XML_format_change = 834; +const xml_token_t XML_format_source = 835; +const xml_token_t XML_formatted_text = 836; +const xml_token_t XML_forms = 837; +const xml_token_t XML_formula = 838; +const xml_token_t XML_formula_hidden = 839; +const xml_token_t XML_formulas = 840; +const xml_token_t XML_forward = 841; +const xml_token_t XML_fraction = 842; +const xml_token_t XML_frame = 843; +const xml_token_t XML_frame_content = 844; +const xml_token_t XML_frame_count = 845; +const xml_token_t XML_frame_display_border = 846; +const xml_token_t XML_frame_display_scrollbar = 847; +const xml_token_t XML_frame_end_margin = 848; +const xml_token_t XML_frame_margin_horizontal = 849; +const xml_token_t XML_frame_margin_vertical = 850; +const xml_token_t XML_frame_name = 851; +const xml_token_t XML_frame_start_margin = 852; +const xml_token_t XML_free = 853; +const xml_token_t XML_freeze = 854; +const xml_token_t XML_from = 855; +const xml_token_t XML_from_another_table = 856; +const xml_token_t XML_from_bottom = 857; +const xml_token_t XML_from_center = 858; +const xml_token_t XML_from_inside = 859; +const xml_token_t XML_from_left = 860; +const xml_token_t XML_from_lower_left = 861; +const xml_token_t XML_from_lower_right = 862; +const xml_token_t XML_from_right = 863; +const xml_token_t XML_from_same_table = 864; +const xml_token_t XML_from_top = 865; +const xml_token_t XML_from_upper_left = 866; +const xml_token_t XML_from_upper_right = 867; +const xml_token_t XML_ft = 868; +const xml_token_t XML_full = 869; +const xml_token_t XML_full_screen = 870; +const xml_token_t XML_function = 871; +const xml_token_t XML_fx = 872; +const xml_token_t XML_fy = 873; +const xml_token_t XML_g = 874; +const xml_token_t XML_gamma = 875; +const xml_token_t XML_gap = 876; +const xml_token_t XML_gap_width = 877; +const xml_token_t XML_generator = 878; +const xml_token_t XML_generic_control = 879; +const xml_token_t XML_gengou = 880; +const xml_token_t XML_get = 881; +const xml_token_t XML_global = 882; +const xml_token_t XML_glue_point = 883; +const xml_token_t XML_glue_point_leaving_directions = 884; +const xml_token_t XML_glue_point_type = 885; +const xml_token_t XML_glue_points = 886; +const xml_token_t XML_glyph_orientation_vertical = 887; +const xml_token_t XML_gouraud = 888; +const xml_token_t XML_gradient = 889; +const xml_token_t XML_gradient_step_count = 890; +const xml_token_t XML_gradientTransform = 891; +const xml_token_t XML_gradientUnits = 892; +const xml_token_t XML_grand_total = 893; +const xml_token_t XML_graphic = 894; +const xml_token_t XML_graphic_properties = 895; +const xml_token_t XML_grddl = 896; +const xml_token_t XML_green = 897; +const xml_token_t XML_gregorian = 898; +const xml_token_t XML_greyscale = 899; +const xml_token_t XML_grid = 900; +const xml_token_t XML_group_bars_per_axis = 901; +const xml_token_t XML_group_by_field_number = 902; +const xml_token_t XML_group_id = 903; +const xml_token_t XML_grouped_by = 904; +const xml_token_t XML_grouping = 905; +const xml_token_t XML_guide_distance = 906; +const xml_token_t XML_guide_overhang = 907; +const xml_token_t XML_h = 908; +const xml_token_t XML_handle = 909; +const xml_token_t XML_handle_mirror_horizontal = 910; +const xml_token_t XML_handle_mirror_vertical = 911; +const xml_token_t XML_handle_polar = 912; +const xml_token_t XML_handle_position = 913; +const xml_token_t XML_handle_radius_range_maximum = 914; +const xml_token_t XML_handle_radius_range_minimum = 915; +const xml_token_t XML_handle_range_x_maximum = 916; +const xml_token_t XML_handle_range_x_minimum = 917; +const xml_token_t XML_handle_range_y_maximum = 918; +const xml_token_t XML_handle_range_y_minimum = 919; +const xml_token_t XML_handle_switched = 920; +const xml_token_t XML_handout = 921; +const xml_token_t XML_handout_master = 922; +const xml_token_t XML_hanging = 923; +const xml_token_t XML_hanja = 924; +const xml_token_t XML_hanja_yoil = 925; +const xml_token_t XML_has_persistent_data = 926; +const xml_token_t XML_hatch = 927; +const xml_token_t XML_header = 928; +const xml_token_t XML_header_decl = 929; +const xml_token_t XML_header_first = 930; +const xml_token_t XML_header_footer_properties = 931; +const xml_token_t XML_header_left = 932; +const xml_token_t XML_header_style = 933; +const xml_token_t XML_headers = 934; +const xml_token_t XML_height = 935; +const xml_token_t XML_help_message = 936; +const xml_token_t XML_hidden = 937; +const xml_token_t XML_hidden_and_protected = 938; +const xml_token_t XML_hidden_paragraph = 939; +const xml_token_t XML_hidden_text = 940; +const xml_token_t XML_hide = 941; +const xml_token_t XML_hide_shape = 942; +const xml_token_t XML_hide_text = 943; +const xml_token_t XML_high = 944; +const xml_token_t XML_highlighted_range = 945; +const xml_token_t XML_hijri = 946; +const xml_token_t XML_hold = 947; +const xml_token_t XML_hole_size = 948; +const xml_token_t XML_horizontal = 949; +const xml_token_t XML_horizontal_bar = 950; +const xml_token_t XML_horizontal_checkerboard = 951; +const xml_token_t XML_horizontal_lines = 952; +const xml_token_t XML_horizontal_on_even = 953; +const xml_token_t XML_horizontal_on_odd = 954; +const xml_token_t XML_horizontal_pos = 955; +const xml_token_t XML_horizontal_rel = 956; +const xml_token_t XML_horizontal_segments = 957; +const xml_token_t XML_horizontal_stripes = 958; +const xml_token_t XML_hostname = 959; +const xml_token_t XML_hourglass = 960; +const xml_token_t XML_hours = 961; +const xml_token_t XML_howpublished = 962; +const xml_token_t XML_href = 963; +const xml_token_t XML_hsl = 964; +const xml_token_t XML_hyperlink_behaviour = 965; +const xml_token_t XML_hyphenate = 966; +const xml_token_t XML_hyphenation_keep = 967; +const xml_token_t XML_hyphenation_ladder_count = 968; +const xml_token_t XML_hyphenation_push_char_count = 969; +const xml_token_t XML_hyphenation_remain_char_count = 970; +const xml_token_t XML_i = 971; +const xml_token_t XML_icon = 972; +const xml_token_t XML_id = 973; +const xml_token_t XML_identifier = 974; +const xml_token_t XML_identify_categories = 975; +const xml_token_t XML_ideograph_alpha = 976; +const xml_token_t XML_ideographic = 977; +const xml_token_t XML_ignore = 978; +const xml_token_t XML_ignore_case = 979; +const xml_token_t XML_ignore_driver_privileges = 980; +const xml_token_t XML_ignore_empty_rows = 981; +const xml_token_t XML_ignore_result = 982; +const xml_token_t XML_illustration_index = 983; +const xml_token_t XML_illustration_index_entry_template = 984; +const xml_token_t XML_illustration_index_source = 985; +const xml_token_t XML_image = 986; +const xml_token_t XML_image_align = 987; +const xml_token_t XML_image_count = 988; +const xml_token_t XML_image_data = 989; +const xml_token_t XML_image_frame = 990; +const xml_token_t XML_image_map = 991; +const xml_token_t XML_image_opacity = 992; +const xml_token_t XML_image_position = 993; +const xml_token_t XML_in = 994; +const xml_token_t XML_inbook = 995; +const xml_token_t XML_inch = 996; +const xml_token_t XML_include_hidden_cells = 997; +const xml_token_t XML_incollection = 998; +const xml_token_t XML_increment = 999; +const xml_token_t XML_indefinite = 1000; +const xml_token_t XML_index = 1001; +const xml_token_t XML_index_body = 1002; +const xml_token_t XML_index_column = 1003; +const xml_token_t XML_index_columns = 1004; +const xml_token_t XML_index_entry_bibliography = 1005; +const xml_token_t XML_index_entry_chapter = 1006; +const xml_token_t XML_index_entry_link_end = 1007; +const xml_token_t XML_index_entry_link_start = 1008; +const xml_token_t XML_index_entry_page_number = 1009; +const xml_token_t XML_index_entry_span = 1010; +const xml_token_t XML_index_entry_tab_stop = 1011; +const xml_token_t XML_index_entry_text = 1012; +const xml_token_t XML_index_name = 1013; +const xml_token_t XML_index_scope = 1014; +const xml_token_t XML_index_source_style = 1015; +const xml_token_t XML_index_source_styles = 1016; +const xml_token_t XML_index_title = 1017; +const xml_token_t XML_index_title_template = 1018; +const xml_token_t XML_indices = 1019; +const xml_token_t XML_information = 1020; +const xml_token_t XML_inherit = 1021; +const xml_token_t XML_initial_creator = 1022; +const xml_token_t XML_inner = 1023; +const xml_token_t XML_inproceedings = 1024; +const xml_token_t XML_insertion = 1025; +const xml_token_t XML_insertion_cut_off = 1026; +const xml_token_t XML_inside = 1027; +const xml_token_t XML_institution = 1028; +const xml_token_t XML_int = 1029; +const xml_token_t XML_integer = 1030; +const xml_token_t XML_intensity = 1031; +const xml_token_t XML_interactive_sequence = 1032; +const xml_token_t XML_interlocking_horizontal_left = 1033; +const xml_token_t XML_interlocking_horizontal_right = 1034; +const xml_token_t XML_interlocking_vertical_bottom = 1035; +const xml_token_t XML_interlocking_vertical_top = 1036; +const xml_token_t XML_interpolation = 1037; +const xml_token_t XML_interval_major = 1038; +const xml_token_t XML_interval_minor_divisor = 1039; +const xml_token_t XML_into_default_style_data_style = 1040; +const xml_token_t XML_into_english_number = 1041; +const xml_token_t XML_inverse = 1042; +const xml_token_t XML_is_active = 1043; +const xml_token_t XML_is_ascending = 1044; +const xml_token_t XML_is_autoincrement = 1045; +const xml_token_t XML_is_boolean = 1046; +const xml_token_t XML_is_clustered = 1047; +const xml_token_t XML_is_data_layout_field = 1048; +const xml_token_t XML_is_empty_allowed = 1049; +const xml_token_t XML_is_first_row_header_line = 1050; +const xml_token_t XML_is_hidden = 1051; +const xml_token_t XML_is_list_header = 1052; +const xml_token_t XML_is_nullable = 1053; +const xml_token_t XML_is_password_required = 1054; +const xml_token_t XML_is_selection = 1055; +const xml_token_t XML_is_sub_table = 1056; +const xml_token_t XML_is_table_name_length_limited = 1057; +const xml_token_t XML_is_tristate = 1058; +const xml_token_t XML_is_unique = 1059; +const xml_token_t XML_isbn = 1060; +const xml_token_t XML_issn = 1061; +const xml_token_t XML_italic = 1062; +const xml_token_t XML_item = 1063; +const xml_token_t XML_iterate = 1064; +const xml_token_t XML_iterate_interval = 1065; +const xml_token_t XML_iterate_type = 1066; +const xml_token_t XML_iteration = 1067; +const xml_token_t XML_iterative = 1068; +const xml_token_t XML_japanese_candle_stick = 1069; +const xml_token_t XML_jewish = 1070; +const xml_token_t XML_join_border = 1071; +const xml_token_t XML_journal = 1072; +const xml_token_t XML_justify = 1073; +const xml_token_t XML_justify_single_word = 1074; +const xml_token_t XML_keep_text = 1075; +const xml_token_t XML_keep_together = 1076; +const xml_token_t XML_keep_with_next = 1077; +const xml_token_t XML_key = 1078; +const xml_token_t XML_key_column = 1079; +const xml_token_t XML_key_columns = 1080; +const xml_token_t XML_key1 = 1081; +const xml_token_t XML_key1_phonetic = 1082; +const xml_token_t XML_key2 = 1083; +const xml_token_t XML_key2_phonetic = 1084; +const xml_token_t XML_keySplines = 1085; +const xml_token_t XML_keyTimes = 1086; +const xml_token_t XML_keys = 1087; +const xml_token_t XML_keyword = 1088; +const xml_token_t XML_keywords = 1089; +const xml_token_t XML_kind = 1090; +const xml_token_t XML_km = 1091; +const xml_token_t XML_label = 1092; +const xml_token_t XML_label_alignment = 1093; +const xml_token_t XML_label_arrangement = 1094; +const xml_token_t XML_label_cell_address = 1095; +const xml_token_t XML_label_cell_range_address = 1096; +const xml_token_t XML_label_followed_by = 1097; +const xml_token_t XML_label_position = 1098; +const xml_token_t XML_label_position_negative = 1099; +const xml_token_t XML_label_range = 1100; +const xml_token_t XML_label_ranges = 1101; +const xml_token_t XML_label_separator = 1102; +const xml_token_t XML_label_width_and_position = 1103; +const xml_token_t XML_landscape = 1104; +const xml_token_t XML_language = 1105; +const xml_token_t XML_language_asian = 1106; +const xml_token_t XML_language_complex = 1107; +const xml_token_t XML_laser = 1108; +const xml_token_t XML_last = 1109; +const xml_token_t XML_last_column = 1110; +const xml_token_t XML_last_column_spanned = 1111; +const xml_token_t XML_last_page = 1112; +const xml_token_t XML_last_row = 1113; +const xml_token_t XML_last_row_end_column = 1114; +const xml_token_t XML_last_row_spanned = 1115; +const xml_token_t XML_last_row_start_column = 1116; +const xml_token_t XML_last_visited_page = 1117; +const xml_token_t XML_latin = 1118; +const xml_token_t XML_layer = 1119; +const xml_token_t XML_layer_set = 1120; +const xml_token_t XML_layout_grid_base_height = 1121; +const xml_token_t XML_layout_grid_base_width = 1122; +const xml_token_t XML_layout_grid_color = 1123; +const xml_token_t XML_layout_grid_display = 1124; +const xml_token_t XML_layout_grid_lines = 1125; +const xml_token_t XML_layout_grid_mode = 1126; +const xml_token_t XML_layout_grid_print = 1127; +const xml_token_t XML_layout_grid_ruby_below = 1128; +const xml_token_t XML_layout_grid_ruby_height = 1129; +const xml_token_t XML_layout_grid_snap_to = 1130; +const xml_token_t XML_layout_grid_standard_mode = 1131; +const xml_token_t XML_layout_mode = 1132; +const xml_token_t XML_leader_char = 1133; +const xml_token_t XML_leader_color = 1134; +const xml_token_t XML_leader_style = 1135; +const xml_token_t XML_leader_text = 1136; +const xml_token_t XML_leader_text_style = 1137; +const xml_token_t XML_leader_type = 1138; +const xml_token_t XML_leader_width = 1139; +const xml_token_t XML_leave_gap = 1140; +const xml_token_t XML_left = 1141; +const xml_token_t XML_left_outside = 1142; +const xml_token_t XML_legend = 1143; +const xml_token_t XML_legend_align = 1144; +const xml_token_t XML_legend_expansion = 1145; +const xml_token_t XML_legend_expansion_aspect_ratio = 1146; +const xml_token_t XML_legend_position = 1147; +const xml_token_t XML_length = 1148; +const xml_token_t XML_letter_kerning = 1149; +const xml_token_t XML_letter_spacing = 1150; +const xml_token_t XML_letters = 1151; +const xml_token_t XML_level = 1152; +const xml_token_t XML_light = 1153; +const xml_token_t XML_lighting_mode = 1154; +const xml_token_t XML_line = 1155; +const xml_token_t XML_line_break = 1156; +const xml_token_t XML_line_distance = 1157; +const xml_token_t XML_line_height = 1158; +const xml_token_t XML_line_height_at_least = 1159; +const xml_token_t XML_line_number = 1160; +const xml_token_t XML_line_skew = 1161; +const xml_token_t XML_line_spacing = 1162; +const xml_token_t XML_line_style = 1163; +const xml_token_t XML_linear = 1164; +const xml_token_t XML_linearGradient = 1165; +const xml_token_t XML_linenumbering_configuration = 1166; +const xml_token_t XML_linenumbering_separator = 1167; +const xml_token_t XML_lines = 1168; +const xml_token_t XML_link_data_style_to_source = 1169; +const xml_token_t XML_link_to_source_data = 1170; +const xml_token_t XML_linked_cell = 1171; +const xml_token_t XML_list = 1172; +const xml_token_t XML_list_header = 1173; +const xml_token_t XML_list_id = 1174; +const xml_token_t XML_list_item = 1175; +const xml_token_t XML_list_level = 1176; +const xml_token_t XML_list_level_label_alignment = 1177; +const xml_token_t XML_list_level_position_and_space_mode = 1178; +const xml_token_t XML_list_level_properties = 1179; +const xml_token_t XML_list_level_style_bullet = 1180; +const xml_token_t XML_list_level_style_image = 1181; +const xml_token_t XML_list_level_style_number = 1182; +const xml_token_t XML_list_linkage_type = 1183; +const xml_token_t XML_list_property = 1184; +const xml_token_t XML_list_source = 1185; +const xml_token_t XML_list_source_type = 1186; +const xml_token_t XML_list_style = 1187; +const xml_token_t XML_list_style_name = 1188; +const xml_token_t XML_list_tab_stop_position = 1189; +const xml_token_t XML_list_value = 1190; +const xml_token_t XML_listbox = 1191; +const xml_token_t XML_listtab = 1192; +const xml_token_t XML_local_socket = 1193; +const xml_token_t XML_logarithmic = 1194; +const xml_token_t XML_login = 1195; +const xml_token_t XML_login_timeout = 1196; +const xml_token_t XML_long = 1197; +const xml_token_t XML_long_dash = 1198; +const xml_token_t XML_longvarbinary = 1199; +const xml_token_t XML_longvarchar = 1200; +const xml_token_t XML_lowercase = 1201; +const xml_token_t XML_lr = 1202; +const xml_token_t XML_lr_tb = 1203; +const xml_token_t XML_ltr = 1204; +const xml_token_t XML_luminance = 1205; +const xml_token_t XML_m = 1206; +const xml_token_t XML_macro_name = 1207; +const xml_token_t XML_main_entry = 1208; +const xml_token_t XML_main_entry_style_name = 1209; +const xml_token_t XML_main_sequence = 1210; +const xml_token_t XML_major = 1211; +const xml_token_t XML_manual = 1212; +const xml_token_t XML_map = 1213; +const xml_token_t XML_margin = 1214; +const xml_token_t XML_margin_bottom = 1215; +const xml_token_t XML_margin_left = 1216; +const xml_token_t XML_margin_right = 1217; +const xml_token_t XML_margin_top = 1218; +const xml_token_t XML_margins = 1219; +const xml_token_t XML_marked_invalid = 1220; +const xml_token_t XML_marker = 1221; +const xml_token_t XML_marker_end = 1222; +const xml_token_t XML_marker_end_center = 1223; +const xml_token_t XML_marker_end_width = 1224; +const xml_token_t XML_marker_start = 1225; +const xml_token_t XML_marker_start_center = 1226; +const xml_token_t XML_marker_start_width = 1227; +const xml_token_t XML_master_element = 1228; +const xml_token_t XML_master_fields = 1229; +const xml_token_t XML_master_page = 1230; +const xml_token_t XML_master_page_name = 1231; +const xml_token_t XML_master_styles = 1232; +const xml_token_t XML_mastersthesis = 1233; +const xml_token_t XML_math = 1234; +const xml_token_t XML_mathematical = 1235; +const xml_token_t XML_matrix_covered = 1236; +const xml_token_t XML_max = 1237; +const xml_token_t XML_max_denominator_value = 1238; +const xml_token_t XML_max_edge = 1239; +const xml_token_t XML_max_height = 1240; +const xml_token_t XML_max_length = 1241; +const xml_token_t XML_max_row_count = 1242; +const xml_token_t XML_max_value = 1243; +const xml_token_t XML_max_width = 1244; +const xml_token_t XML_maximum = 1245; +const xml_token_t XML_maximum_difference = 1246; +const xml_token_t XML_may_break_between_rows = 1247; +const xml_token_t XML_may_script = 1248; +const xml_token_t XML_mean_value = 1249; +const xml_token_t XML_measure = 1250; +const xml_token_t XML_measure_align = 1251; +const xml_token_t XML_measure_vertical_align = 1252; +const xml_token_t XML_media = 1253; +const xml_token_t XML_media_call = 1254; +const xml_token_t XML_media_type = 1255; +const xml_token_t XML_medium = 1256; +const xml_token_t XML_melt = 1257; +const xml_token_t XML_member_count = 1258; +const xml_token_t XML_member_difference = 1259; +const xml_token_t XML_member_name = 1260; +const xml_token_t XML_member_percentage = 1261; +const xml_token_t XML_member_percentage_difference = 1262; +const xml_token_t XML_member_type = 1263; +const xml_token_t XML_message_type = 1264; +const xml_token_t XML_meta = 1265; +const xml_token_t XML_meta_field = 1266; +const xml_token_t XML_method = 1267; +const xml_token_t XML_mi = 1268; +const xml_token_t XML_middle = 1269; +const xml_token_t XML_mime_type = 1270; +const xml_token_t XML_mimetype = 1271; +const xml_token_t XML_min = 1272; +const xml_token_t XML_min_decimal_places = 1273; +const xml_token_t XML_min_denominator_digits = 1274; +const xml_token_t XML_min_edge = 1275; +const xml_token_t XML_min_exponent_digits = 1276; +const xml_token_t XML_min_height = 1277; +const xml_token_t XML_min_integer_digits = 1278; +const xml_token_t XML_min_label_distance = 1279; +const xml_token_t XML_min_label_width = 1280; +const xml_token_t XML_min_numerator_digits = 1281; +const xml_token_t XML_min_row_height = 1282; +const xml_token_t XML_min_value = 1283; +const xml_token_t XML_min_width = 1284; +const xml_token_t XML_minimum = 1285; +const xml_token_t XML_minor = 1286; +const xml_token_t XML_minutes = 1287; +const xml_token_t XML_mirror = 1288; +const xml_token_t XML_mirror_horizontal = 1289; +const xml_token_t XML_mirror_vertical = 1290; +const xml_token_t XML_mirrored = 1291; +const xml_token_t XML_misc = 1292; +const xml_token_t XML_miter = 1293; +const xml_token_t XML_mm = 1294; +const xml_token_t XML_mode = 1295; +const xml_token_t XML_model = 1296; +const xml_token_t XML_modern = 1297; +const xml_token_t XML_modification_date = 1298; +const xml_token_t XML_modification_time = 1299; +const xml_token_t XML_modifiers = 1300; +const xml_token_t XML_modulate = 1301; +const xml_token_t XML_mono = 1302; +const xml_token_t XML_month = 1303; +const xml_token_t XML_months = 1304; +const xml_token_t XML_motion_path = 1305; +const xml_token_t XML_mouse_as_pen = 1306; +const xml_token_t XML_mouse_visible = 1307; +const xml_token_t XML_move = 1308; +const xml_token_t XML_move_from_bottom = 1309; +const xml_token_t XML_move_from_left = 1310; +const xml_token_t XML_move_from_lowerleft = 1311; +const xml_token_t XML_move_from_lowerright = 1312; +const xml_token_t XML_move_from_right = 1313; +const xml_token_t XML_move_from_top = 1314; +const xml_token_t XML_move_from_upperleft = 1315; +const xml_token_t XML_move_from_upperright = 1316; +const xml_token_t XML_move_short = 1317; +const xml_token_t XML_movement = 1318; +const xml_token_t XML_movement_cut_off = 1319; +const xml_token_t XML_moving_average = 1320; +const xml_token_t XML_multi_deletion_spanned = 1321; +const xml_token_t XML_multi_line = 1322; +const xml_token_t XML_multiple = 1323; +const xml_token_t XML_name = 1324; +const xml_token_t XML_name_and_extension = 1325; +const xml_token_t XML_named = 1326; +const xml_token_t XML_named_expression = 1327; +const xml_token_t XML_named_expressions = 1328; +const xml_token_t XML_named_range = 1329; +const xml_token_t XML_named_symbol = 1330; +const xml_token_t XML_nav_order = 1331; +const xml_token_t XML_navigation_mode = 1332; +const xml_token_t XML_near_axis = 1333; +const xml_token_t XML_near_axis_other_side = 1334; +const xml_token_t XML_near_origin = 1335; +const xml_token_t XML_never = 1336; +const xml_token_t XML_new = 1337; +const xml_token_t XML_next = 1338; +const xml_token_t XML_next_page = 1339; +const xml_token_t XML_next_style_name = 1340; +const xml_token_t XML_no_action = 1341; +const xml_token_t XML_no_limit = 1342; +const xml_token_t XML_no_nulls = 1343; +const xml_token_t XML_no_repeat = 1344; +const xml_token_t XML_no_wrap = 1345; +const xml_token_t XML_node_type = 1346; +const xml_token_t XML_nohref = 1347; +const xml_token_t XML_non_primitive = 1348; +const xml_token_t XML_non_whitespace_character_count = 1349; +const xml_token_t XML_none = 1350; +const xml_token_t XML_nonzero = 1351; +const xml_token_t XML_normal = 1352; +const xml_token_t XML_normals_direction = 1353; +const xml_token_t XML_normals_kind = 1354; +const xml_token_t XML_note = 1355; +const xml_token_t XML_note_body = 1356; +const xml_token_t XML_note_citation = 1357; +const xml_token_t XML_note_class = 1358; +const xml_token_t XML_note_continuation_notice_backward = 1359; +const xml_token_t XML_note_continuation_notice_forward = 1360; +const xml_token_t XML_note_ref = 1361; +const xml_token_t XML_notes = 1362; +const xml_token_t XML_notes_configuration = 1363; +const xml_token_t XML_nothing = 1364; +const xml_token_t XML_notify_on_update_of_ranges = 1365; +const xml_token_t XML_null_date = 1366; +const xml_token_t XML_null_year = 1367; +const xml_token_t XML_nullable = 1368; +const xml_token_t XML_num_format = 1369; +const xml_token_t XML_num_letter_sync = 1370; +const xml_token_t XML_num_prefix = 1371; +const xml_token_t XML_num_suffix = 1372; +const xml_token_t XML_number = 1373; +const xml_token_t XML_number_all_superior = 1374; +const xml_token_t XML_number_and_name = 1375; +const xml_token_t XML_number_columns_repeated = 1376; +const xml_token_t XML_number_columns_spanned = 1377; +const xml_token_t XML_number_lines = 1378; +const xml_token_t XML_number_matrix_columns_spanned = 1379; +const xml_token_t XML_number_matrix_rows_spanned = 1380; +const xml_token_t XML_number_no_superior = 1381; +const xml_token_t XML_number_position = 1382; +const xml_token_t XML_number_rows_repeated = 1383; +const xml_token_t XML_number_rows_spanned = 1384; +const xml_token_t XML_number_style = 1385; +const xml_token_t XML_number_wrapped_paragraphs = 1386; +const xml_token_t XML_numbered_entries = 1387; +const xml_token_t XML_numbered_paragraph = 1388; +const xml_token_t XML_numeric = 1389; +const xml_token_t XML_object = 1390; +const xml_token_t XML_object_count = 1391; +const xml_token_t XML_object_index = 1392; +const xml_token_t XML_object_index_entry_template = 1393; +const xml_token_t XML_object_index_source = 1394; +const xml_token_t XML_object_name = 1395; +const xml_token_t XML_object_ole = 1396; +const xml_token_t XML_objectBoundingBox = 1397; +const xml_token_t XML_objects = 1398; +const xml_token_t XML_oblique = 1399; +const xml_token_t XML_odd_columns = 1400; +const xml_token_t XML_odd_rows = 1401; +const xml_token_t XML_office = 1402; +const xml_token_t XML_offset = 1403; +const xml_token_t XML_ole_action = 1404; +const xml_token_t XML_ole_draw_aspect = 1405; +const xml_token_t XML_ole_object_count = 1406; +const xml_token_t XML_on_click = 1407; +const xml_token_t XML_on_update_keep_size = 1408; +const xml_token_t XML_on_update_keep_styles = 1409; +const xml_token_t XML_onLoad = 1410; +const xml_token_t XML_onRequest = 1411; +const xml_token_t XML_once_concurrent = 1412; +const xml_token_t XML_once_successive = 1413; +const xml_token_t XML_opacity = 1414; +const xml_token_t XML_opacity_name = 1415; +const xml_token_t XML_open = 1416; +const xml_token_t XML_open_horizontal = 1417; +const xml_token_t XML_open_vertical = 1418; +const xml_token_t XML_operation = 1419; +const xml_token_t XML_operator = 1420; +const xml_token_t XML_option = 1421; +const xml_token_t XML_order = 1422; +const xml_token_t XML_order_statement = 1423; +const xml_token_t XML_organizations = 1424; +const xml_token_t XML_orgchart = 1425; +const xml_token_t XML_orientation = 1426; +const xml_token_t XML_origin = 1427; +const xml_token_t XML_orphans = 1428; +const xml_token_t XML_other = 1429; +const xml_token_t XML_out = 1430; +const xml_token_t XML_outer = 1431; +const xml_token_t XML_outline = 1432; +const xml_token_t XML_outline_level = 1433; +const xml_token_t XML_outline_level_style = 1434; +const xml_token_t XML_outline_style = 1435; +const xml_token_t XML_outline_subtotals_bottom = 1436; +const xml_token_t XML_outline_subtotals_top = 1437; +const xml_token_t XML_outside = 1438; +const xml_token_t XML_outside_end = 1439; +const xml_token_t XML_outside_start = 1440; +const xml_token_t XML_overflow_behavior = 1441; +const xml_token_t XML_overlap = 1442; +const xml_token_t XML_overline_position = 1443; +const xml_token_t XML_overline_thickness = 1444; +const xml_token_t XML_p = 1445; +const xml_token_t XML_paced = 1446; +const xml_token_t XML_pad = 1447; +const xml_token_t XML_padding = 1448; +const xml_token_t XML_padding_bottom = 1449; +const xml_token_t XML_padding_left = 1450; +const xml_token_t XML_padding_right = 1451; +const xml_token_t XML_padding_top = 1452; +const xml_token_t XML_page = 1453; +const xml_token_t XML_page_adjust = 1454; +const xml_token_t XML_page_breaks_on_group_change = 1455; +const xml_token_t XML_page_content = 1456; +const xml_token_t XML_page_continuation = 1457; +const xml_token_t XML_page_count = 1458; +const xml_token_t XML_page_end_margin = 1459; +const xml_token_t XML_page_height = 1460; +const xml_token_t XML_page_layout = 1461; +const xml_token_t XML_page_layout_name = 1462; +const xml_token_t XML_page_layout_properties = 1463; +const xml_token_t XML_page_number = 1464; +const xml_token_t XML_page_sequence = 1465; +const xml_token_t XML_page_start_margin = 1466; +const xml_token_t XML_page_step_size = 1467; +const xml_token_t XML_page_thumbnail = 1468; +const xml_token_t XML_page_usage = 1469; +const xml_token_t XML_page_variable_get = 1470; +const xml_token_t XML_page_variable_set = 1471; +const xml_token_t XML_page_width = 1472; +const xml_token_t XML_pages = 1473; +const xml_token_t XML_panose_1 = 1474; +const xml_token_t XML_paper_tray_name = 1475; +const xml_token_t XML_par = 1476; +const xml_token_t XML_paragraph = 1477; +const xml_token_t XML_paragraph_content = 1478; +const xml_token_t XML_paragraph_count = 1479; +const xml_token_t XML_paragraph_end_margin = 1480; +const xml_token_t XML_paragraph_properties = 1481; +const xml_token_t XML_paragraph_start_margin = 1482; +const xml_token_t XML_paragraph_style_name = 1483; +const xml_token_t XML_parallel = 1484; +const xml_token_t XML_param = 1485; +const xml_token_t XML_parameter_name_substitution = 1486; +const xml_token_t XML_parent = 1487; +const xml_token_t XML_parent_style_name = 1488; +const xml_token_t XML_parse_sql_statement = 1489; +const xml_token_t XML_password = 1490; +const xml_token_t XML_path = 1491; +const xml_token_t XML_path_id = 1492; +const xml_token_t XML_path_stretchpoint_x = 1493; +const xml_token_t XML_path_stretchpoint_y = 1494; +const xml_token_t XML_pause = 1495; +const xml_token_t XML_pc = 1496; +const xml_token_t XML_pending = 1497; +const xml_token_t XML_percentage = 1498; +const xml_token_t XML_percentage_data_style_name = 1499; +const xml_token_t XML_percentage_style = 1500; +const xml_token_t XML_perspective = 1501; +const xml_token_t XML_phdthesis = 1502; +const xml_token_t XML_phong = 1503; +const xml_token_t XML_pie_offset = 1504; +const xml_token_t XML_placeholder = 1505; +const xml_token_t XML_placeholder_type = 1506; +const xml_token_t XML_placing = 1507; +const xml_token_t XML_plain_number = 1508; +const xml_token_t XML_plain_number_and_name = 1509; +const xml_token_t XML_play = 1510; +const xml_token_t XML_play_full = 1511; +const xml_token_t XML_plot_area = 1512; +const xml_token_t XML_plugin = 1513; +const xml_token_t XML_plus = 1514; +const xml_token_t XML_points = 1515; +const xml_token_t XML_polygon = 1516; +const xml_token_t XML_polyline = 1517; +const xml_token_t XML_polynomial = 1518; +const xml_token_t XML_port = 1519; +const xml_token_t XML_portrait = 1520; +const xml_token_t XML_position = 1521; +const xml_token_t XML_possessive_form = 1522; +const xml_token_t XML_post = 1523; +const xml_token_t XML_power = 1524; +const xml_token_t XML_precision = 1525; +const xml_token_t XML_precision_as_shown = 1526; +const xml_token_t XML_prefix = 1527; +const xml_token_t XML_presentation = 1528; +const xml_token_t XML_presentation_page_layout = 1529; +const xml_token_t XML_presentation_page_layout_name = 1530; +const xml_token_t XML_preset_class = 1531; +const xml_token_t XML_preset_id = 1532; +const xml_token_t XML_preset_sub_type = 1533; +const xml_token_t XML_previous = 1534; +const xml_token_t XML_previous_page = 1535; +const xml_token_t XML_primary = 1536; +const xml_token_t XML_print = 1537; +const xml_token_t XML_print_content = 1538; +const xml_token_t XML_print_date = 1539; +const xml_token_t XML_print_orientation = 1540; +const xml_token_t XML_print_page_order = 1541; +const xml_token_t XML_print_range = 1542; +const xml_token_t XML_print_ranges = 1543; +const xml_token_t XML_print_time = 1544; +const xml_token_t XML_print_view = 1545; +const xml_token_t XML_printable = 1546; +const xml_token_t XML_printed_by = 1547; +const xml_token_t XML_printer = 1548; +const xml_token_t XML_prior = 1549; +const xml_token_t XML_proceedings = 1550; +const xml_token_t XML_product = 1551; +const xml_token_t XML_projection = 1552; +const xml_token_t XML_properties = 1553; +const xml_token_t XML_property = 1554; +const xml_token_t XML_property_name = 1555; +const xml_token_t XML_protect = 1556; +const xml_token_t XML_protected = 1557; +const xml_token_t XML_protection_key = 1558; +const xml_token_t XML_protection_key_digest_algorithm = 1559; +const xml_token_t XML_pt = 1560; +const xml_token_t XML_publisher = 1561; +const xml_token_t XML_punctuation_wrap = 1562; +const xml_token_t XML_push = 1563; +const xml_token_t XML_pyramid = 1564; +const xml_token_t XML_quarter = 1565; +const xml_token_t XML_quarters = 1566; +const xml_token_t XML_queries = 1567; +const xml_token_t XML_query = 1568; +const xml_token_t XML_query_collection = 1569; +const xml_token_t XML_query_name = 1570; +const xml_token_t XML_r = 1571; +const xml_token_t XML_radial = 1572; +const xml_token_t XML_radialGradient = 1573; +const xml_token_t XML_radio = 1574; +const xml_token_t XML_random = 1575; +const xml_token_t XML_range_usable_as = 1576; +const xml_token_t XML_readonly = 1577; +const xml_token_t XML_real = 1578; +const xml_token_t XML_records = 1579; +const xml_token_t XML_recreate_on_edit = 1580; +const xml_token_t XML_rect = 1581; +const xml_token_t XML_rectangle = 1582; +const xml_token_t XML_rectangular = 1583; +const xml_token_t XML_red = 1584; +const xml_token_t XML_ref = 1585; +const xml_token_t XML_ref_name = 1586; +const xml_token_t XML_reference_format = 1587; +const xml_token_t XML_reference_mark = 1588; +const xml_token_t XML_reference_mark_end = 1589; +const xml_token_t XML_reference_mark_start = 1590; +const xml_token_t XML_referenced_table_name = 1591; +const xml_token_t XML_reflect = 1592; +const xml_token_t XML_refresh_delay = 1593; +const xml_token_t XML_region_center = 1594; +const xml_token_t XML_region_left = 1595; +const xml_token_t XML_region_right = 1596; +const xml_token_t XML_register_true = 1597; +const xml_token_t XML_register_truth_ref_style_name = 1598; +const xml_token_t XML_regression_curve = 1599; +const xml_token_t XML_regression_force_intercept = 1600; +const xml_token_t XML_regression_intercept_value = 1601; +const xml_token_t XML_regression_max_degree = 1602; +const xml_token_t XML_regression_moving_type = 1603; +const xml_token_t XML_regression_name = 1604; +const xml_token_t XML_regression_period = 1605; +const xml_token_t XML_regression_type = 1606; +const xml_token_t XML_regular_polygon = 1607; +const xml_token_t XML_rejected = 1608; +const xml_token_t XML_rejecting_change_id = 1609; +const xml_token_t XML_rel_column_width = 1610; +const xml_token_t XML_rel_height = 1611; +const xml_token_t XML_rel_width = 1612; +const xml_token_t XML_related_column_name = 1613; +const xml_token_t XML_relative_tab_stop_position = 1614; +const xml_token_t XML_remove = 1615; +const xml_token_t XML_remove_dependents = 1616; +const xml_token_t XML_remove_precedents = 1617; +const xml_token_t XML_repeat = 1618; +const xml_token_t XML_repeat_column = 1619; +const xml_token_t XML_repeat_content = 1620; +const xml_token_t XML_repeat_row = 1621; +const xml_token_t XML_repeatCount = 1622; +const xml_token_t XML_repeatDur = 1623; +const xml_token_t XML_repeated = 1624; +const xml_token_t XML_replace = 1625; +const xml_token_t XML_report_type = 1626; +const xml_token_t XML_reports = 1627; +const xml_token_t XML_reset = 1628; +const xml_token_t XML_restart = 1629; +const xml_token_t XML_restart_numbering = 1630; +const xml_token_t XML_restart_on_page = 1631; +const xml_token_t XML_restartDefault = 1632; +const xml_token_t XML_restrict = 1633; +const xml_token_t XML_reverse = 1634; +const xml_token_t XML_reverse_direction = 1635; +const xml_token_t XML_rfc_language_tag = 1636; +const xml_token_t XML_rfc_language_tag_asian = 1637; +const xml_token_t XML_rfc_language_tag_complex = 1638; +const xml_token_t XML_rgb = 1639; +const xml_token_t XML_right = 1640; +const xml_token_t XML_right_angled_axes = 1641; +const xml_token_t XML_right_outside = 1642; +const xml_token_t XML_rl = 1643; +const xml_token_t XML_rl_tb = 1644; +const xml_token_t XML_roll_from_bottom = 1645; +const xml_token_t XML_roll_from_left = 1646; +const xml_token_t XML_roll_from_right = 1647; +const xml_token_t XML_roll_from_top = 1648; +const xml_token_t XML_roman = 1649; +const xml_token_t XML_rotate = 1650; +const xml_token_t XML_rotation = 1651; +const xml_token_t XML_rotation_align = 1652; +const xml_token_t XML_rotation_angle = 1653; +const xml_token_t XML_round = 1654; +const xml_token_t XML_row = 1655; +const xml_token_t XML_row_count = 1656; +const xml_token_t XML_row_height = 1657; +const xml_token_t XML_row_mapping = 1658; +const xml_token_t XML_row_number = 1659; +const xml_token_t XML_row_percentage = 1660; +const xml_token_t XML_row_retrieving_statement = 1661; +const xml_token_t XML_rows = 1662; +const xml_token_t XML_ruby = 1663; +const xml_token_t XML_ruby_align = 1664; +const xml_token_t XML_ruby_base = 1665; +const xml_token_t XML_ruby_position = 1666; +const xml_token_t XML_ruby_properties = 1667; +const xml_token_t XML_ruby_text = 1668; +const xml_token_t XML_run_through = 1669; +const xml_token_t XML_running_total = 1670; +const xml_token_t XML_rx = 1671; +const xml_token_t XML_ry = 1672; +const xml_token_t XML_s = 1673; +const xml_token_t XML_scale = 1674; +const xml_token_t XML_scale_min = 1675; +const xml_token_t XML_scale_text = 1676; +const xml_token_t XML_scale_to = 1677; +const xml_token_t XML_scale_to_X = 1678; +const xml_token_t XML_scale_to_Y = 1679; +const xml_token_t XML_scale_to_pages = 1680; +const xml_token_t XML_scenario = 1681; +const xml_token_t XML_scenario_ranges = 1682; +const xml_token_t XML_scene = 1683; +const xml_token_t XML_schema_definition = 1684; +const xml_token_t XML_schema_name = 1685; +const xml_token_t XML_school = 1686; +const xml_token_t XML_scientific_number = 1687; +const xml_token_t XML_screen = 1688; +const xml_token_t XML_script = 1689; +const xml_token_t XML_script_asian = 1690; +const xml_token_t XML_script_complex = 1691; +const xml_token_t XML_script_type = 1692; +const xml_token_t XML_scripts = 1693; +const xml_token_t XML_scroll = 1694; +const xml_token_t XML_search_criteria_must_apply_to_whole_cell = 1695; +const xml_token_t XML_secondary_fill_color = 1696; +const xml_token_t XML_seconds = 1697; +const xml_token_t XML_section = 1698; +const xml_token_t XML_section_name = 1699; +const xml_token_t XML_section_properties = 1700; +const xml_token_t XML_section_source = 1701; +const xml_token_t XML_segments = 1702; +const xml_token_t XML_select_page = 1703; +const xml_token_t XML_selected = 1704; +const xml_token_t XML_selected_page = 1705; +const xml_token_t XML_selection = 1706; +const xml_token_t XML_selection_indices = 1707; +const xml_token_t XML_self = 1708; +const xml_token_t XML_semi_automatic = 1709; +const xml_token_t XML_semi_condensed = 1710; +const xml_token_t XML_semi_expanded = 1711; +const xml_token_t XML_sender_city = 1712; +const xml_token_t XML_sender_company = 1713; +const xml_token_t XML_sender_country = 1714; +const xml_token_t XML_sender_email = 1715; +const xml_token_t XML_sender_fax = 1716; +const xml_token_t XML_sender_firstname = 1717; +const xml_token_t XML_sender_initials = 1718; +const xml_token_t XML_sender_lastname = 1719; +const xml_token_t XML_sender_phone_private = 1720; +const xml_token_t XML_sender_phone_work = 1721; +const xml_token_t XML_sender_position = 1722; +const xml_token_t XML_sender_postal_code = 1723; +const xml_token_t XML_sender_state_or_province = 1724; +const xml_token_t XML_sender_street = 1725; +const xml_token_t XML_sender_title = 1726; +const xml_token_t XML_sentence_count = 1727; +const xml_token_t XML_separating = 1728; +const xml_token_t XML_separation_character = 1729; +const xml_token_t XML_separator = 1730; +const xml_token_t XML_seq = 1731; +const xml_token_t XML_sequence = 1732; +const xml_token_t XML_sequence_decl = 1733; +const xml_token_t XML_sequence_decls = 1734; +const xml_token_t XML_sequence_ref = 1735; +const xml_token_t XML_series = 1736; +const xml_token_t XML_series_source = 1737; +const xml_token_t XML_server_database = 1738; +const xml_token_t XML_server_map = 1739; +const xml_token_t XML_set = 1740; +const xml_token_t XML_set_default = 1741; +const xml_token_t XML_set_null = 1742; +const xml_token_t XML_settings = 1743; +const xml_token_t XML_shade_mode = 1744; +const xml_token_t XML_shadow = 1745; +const xml_token_t XML_shadow_color = 1746; +const xml_token_t XML_shadow_offset_x = 1747; +const xml_token_t XML_shadow_offset_y = 1748; +const xml_token_t XML_shadow_opacity = 1749; +const xml_token_t XML_shadow_slant = 1750; +const xml_token_t XML_shape = 1751; +const xml_token_t XML_shape_id = 1752; +const xml_token_t XML_shapes = 1753; +const xml_token_t XML_sharpness = 1754; +const xml_token_t XML_sheet_name = 1755; +const xml_token_t XML_shininess = 1756; +const xml_token_t XML_short = 1757; +const xml_token_t XML_show = 1758; +const xml_token_t XML_show_deleted = 1759; +const xml_token_t XML_show_details = 1760; +const xml_token_t XML_show_empty = 1761; +const xml_token_t XML_show_end_of_presentation_slide = 1762; +const xml_token_t XML_show_filter_button = 1763; +const xml_token_t XML_show_logo = 1764; +const xml_token_t XML_show_shape = 1765; +const xml_token_t XML_show_text = 1766; +const xml_token_t XML_show_unit = 1767; +const xml_token_t XML_shrink_to_fit = 1768; +const xml_token_t XML_side_by_side = 1769; +const xml_token_t XML_simple = 1770; +const xml_token_t XML_single = 1771; +const xml_token_t XML_size = 1772; +const xml_token_t XML_skewX = 1773; +const xml_token_t XML_skewY = 1774; +const xml_token_t XML_skip_white_space = 1775; +const xml_token_t XML_slide = 1776; +const xml_token_t XML_slope = 1777; +const xml_token_t XML_slow = 1778; +const xml_token_t XML_small_caps = 1779; +const xml_token_t XML_smallint = 1780; +const xml_token_t XML_smil = 1781; +const xml_token_t XML_snap_to_layout_grid = 1782; +const xml_token_t XML_soft_page_break = 1783; +const xml_token_t XML_solid = 1784; +const xml_token_t XML_solid_type = 1785; +const xml_token_t XML_sort = 1786; +const xml_token_t XML_sort_algorithm = 1787; +const xml_token_t XML_sort_ascending = 1788; +const xml_token_t XML_sort_by = 1789; +const xml_token_t XML_sort_by_position = 1790; +const xml_token_t XML_sort_by_x_values = 1791; +const xml_token_t XML_sort_groups = 1792; +const xml_token_t XML_sort_key = 1793; +const xml_token_t XML_sort_mode = 1794; +const xml_token_t XML_sound = 1795; +const xml_token_t XML_source = 1796; +const xml_token_t XML_source_cell_range = 1797; +const xml_token_t XML_source_cell_range_addresses = 1798; +const xml_token_t XML_source_field_name = 1799; +const xml_token_t XML_source_name = 1800; +const xml_token_t XML_source_range_address = 1801; +const xml_token_t XML_source_service = 1802; +const xml_token_t XML_space = 1803; +const xml_token_t XML_space_after = 1804; +const xml_token_t XML_space_before = 1805; +const xml_token_t XML_span = 1806; +const xml_token_t XML_specular = 1807; +const xml_token_t XML_specular_color = 1808; +const xml_token_t XML_speed = 1809; +const xml_token_t XML_sphere = 1810; +const xml_token_t XML_spin_button = 1811; +const xml_token_t XML_spiral_inward_left = 1812; +const xml_token_t XML_spiral_inward_right = 1813; +const xml_token_t XML_spiral_outward_left = 1814; +const xml_token_t XML_spiral_outward_right = 1815; +const xml_token_t XML_spiralin_left = 1816; +const xml_token_t XML_spiralin_right = 1817; +const xml_token_t XML_spiralout_left = 1818; +const xml_token_t XML_spiralout_right = 1819; +const xml_token_t XML_spline = 1820; +const xml_token_t XML_spline_order = 1821; +const xml_token_t XML_spline_resolution = 1822; +const xml_token_t XML_spreadMethod = 1823; +const xml_token_t XML_spreadsheet = 1824; +const xml_token_t XML_sql = 1825; +const xml_token_t XML_sql_pass_through = 1826; +const xml_token_t XML_sql_statement = 1827; +const xml_token_t XML_sqlnull = 1828; +const xml_token_t XML_square = 1829; +const xml_token_t XML_stacked = 1830; +const xml_token_t XML_stagger_even = 1831; +const xml_token_t XML_stagger_odd = 1832; +const xml_token_t XML_standard = 1833; +const xml_token_t XML_standard_deviation = 1834; +const xml_token_t XML_standard_error = 1835; +const xml_token_t XML_star = 1836; +const xml_token_t XML_start = 1837; +const xml_token_t XML_start_angle = 1838; +const xml_token_t XML_start_color = 1839; +const xml_token_t XML_start_column = 1840; +const xml_token_t XML_start_glue_point = 1841; +const xml_token_t XML_start_guide = 1842; +const xml_token_t XML_start_indent = 1843; +const xml_token_t XML_start_intensity = 1844; +const xml_token_t XML_start_line_spacing_horizontal = 1845; +const xml_token_t XML_start_line_spacing_vertical = 1846; +const xml_token_t XML_start_numbering_at = 1847; +const xml_token_t XML_start_page = 1848; +const xml_token_t XML_start_position = 1849; +const xml_token_t XML_start_row = 1850; +const xml_token_t XML_start_scale = 1851; +const xml_token_t XML_start_shape = 1852; +const xml_token_t XML_start_table = 1853; +const xml_token_t XML_start_value = 1854; +const xml_token_t XML_start_with_navigator = 1855; +const xml_token_t XML_state = 1856; +const xml_token_t XML_status = 1857; +const xml_token_t XML_stay_on_top = 1858; +const xml_token_t XML_stdev = 1859; +const xml_token_t XML_stdevp = 1860; +const xml_token_t XML_stemh = 1861; +const xml_token_t XML_stemv = 1862; +const xml_token_t XML_step = 1863; +const xml_token_t XML_step_center_x = 1864; +const xml_token_t XML_step_center_y = 1865; +const xml_token_t XML_step_end = 1866; +const xml_token_t XML_step_size = 1867; +const xml_token_t XML_step_start = 1868; +const xml_token_t XML_steps = 1869; +const xml_token_t XML_stock_gain_marker = 1870; +const xml_token_t XML_stock_loss_marker = 1871; +const xml_token_t XML_stock_range_line = 1872; +const xml_token_t XML_stop = 1873; +const xml_token_t XML_stop_color = 1874; +const xml_token_t XML_stop_opacity = 1875; +const xml_token_t XML_straight_line = 1876; +const xml_token_t XML_stretch = 1877; +const xml_token_t XML_stretch_from_bottom = 1878; +const xml_token_t XML_stretch_from_left = 1879; +const xml_token_t XML_stretch_from_right = 1880; +const xml_token_t XML_stretch_from_top = 1881; +const xml_token_t XML_strict = 1882; +const xml_token_t XML_strikethrough_position = 1883; +const xml_token_t XML_strikethrough_thickness = 1884; +const xml_token_t XML_string = 1885; +const xml_token_t XML_string_value = 1886; +const xml_token_t XML_string_value_if_false = 1887; +const xml_token_t XML_string_value_if_true = 1888; +const xml_token_t XML_string_value_phonetic = 1889; +const xml_token_t XML_stripes = 1890; +const xml_token_t XML_stroke = 1891; +const xml_token_t XML_stroke_color = 1892; +const xml_token_t XML_stroke_dash = 1893; +const xml_token_t XML_stroke_dash_names = 1894; +const xml_token_t XML_stroke_linecap = 1895; +const xml_token_t XML_stroke_linejoin = 1896; +const xml_token_t XML_stroke_opacity = 1897; +const xml_token_t XML_stroke_width = 1898; +const xml_token_t XML_struct = 1899; +const xml_token_t XML_structure_protected = 1900; +const xml_token_t XML_style = 1901; +const xml_token_t XML_style_name = 1902; +const xml_token_t XML_style_override = 1903; +const xml_token_t XML_styles = 1904; +const xml_token_t XML_sub = 1905; +const xml_token_t XML_sub_item = 1906; +const xml_token_t XML_subject = 1907; +const xml_token_t XML_submit = 1908; +const xml_token_t XML_subtitle = 1909; +const xml_token_t XML_subtotal_field = 1910; +const xml_token_t XML_subtotal_rule = 1911; +const xml_token_t XML_subtotal_rules = 1912; +const xml_token_t XML_subtype = 1913; +const xml_token_t XML_suffix = 1914; +const xml_token_t XML_sum = 1915; +const xml_token_t XML_super = 1916; +const xml_token_t XML_suppress_version_columns = 1917; +const xml_token_t XML_svg = 1918; +const xml_token_t XML_swiss = 1919; +const xml_token_t XML_syllable_count = 1920; +const xml_token_t XML_symbol_color = 1921; +const xml_token_t XML_symbol_height = 1922; +const xml_token_t XML_symbol_image = 1923; +const xml_token_t XML_symbol_name = 1924; +const xml_token_t XML_symbol_type = 1925; +const xml_token_t XML_symbol_width = 1926; +const xml_token_t XML_system = 1927; +const xml_token_t XML_system_driver_settings = 1928; +const xml_token_t XML_tab = 1929; +const xml_token_t XML_tab_color = 1930; +const xml_token_t XML_tab_cycle = 1931; +const xml_token_t XML_tab_index = 1932; +const xml_token_t XML_tab_ref = 1933; +const xml_token_t XML_tab_stop = 1934; +const xml_token_t XML_tab_stop_distance = 1935; +const xml_token_t XML_tab_stops = 1936; +const xml_token_t XML_table = 1937; +const xml_token_t XML_table_background = 1938; +const xml_token_t XML_table_cell = 1939; +const xml_token_t XML_table_cell_properties = 1940; +const xml_token_t XML_table_centering = 1941; +const xml_token_t XML_table_column = 1942; +const xml_token_t XML_table_column_group = 1943; +const xml_token_t XML_table_column_properties = 1944; +const xml_token_t XML_table_columns = 1945; +const xml_token_t XML_table_count = 1946; +const xml_token_t XML_table_definition = 1947; +const xml_token_t XML_table_definitions = 1948; +const xml_token_t XML_table_exclude_filter = 1949; +const xml_token_t XML_table_fields = 1950; +const xml_token_t XML_table_filter = 1951; +const xml_token_t XML_table_filter_pattern = 1952; +const xml_token_t XML_table_formula = 1953; +const xml_token_t XML_table_header_columns = 1954; +const xml_token_t XML_table_header_rows = 1955; +const xml_token_t XML_table_include_filter = 1956; +const xml_token_t XML_table_index = 1957; +const xml_token_t XML_table_index_entry_template = 1958; +const xml_token_t XML_table_index_source = 1959; +const xml_token_t XML_table_name = 1960; +const xml_token_t XML_table_of_content = 1961; +const xml_token_t XML_table_of_content_entry_template = 1962; +const xml_token_t XML_table_of_content_source = 1963; +const xml_token_t XML_table_properties = 1964; +const xml_token_t XML_table_representation = 1965; +const xml_token_t XML_table_representations = 1966; +const xml_token_t XML_table_row = 1967; +const xml_token_t XML_table_row_group = 1968; +const xml_token_t XML_table_row_properties = 1969; +const xml_token_t XML_table_rows = 1970; +const xml_token_t XML_table_setting = 1971; +const xml_token_t XML_table_settings = 1972; +const xml_token_t XML_table_source = 1973; +const xml_token_t XML_table_template = 1974; +const xml_token_t XML_table_type = 1975; +const xml_token_t XML_table_type_filter = 1976; +const xml_token_t XML_tabular_layout = 1977; +const xml_token_t XML_target_cell_address = 1978; +const xml_token_t XML_target_frame = 1979; +const xml_token_t XML_target_frame_name = 1980; +const xml_token_t XML_target_range_address = 1981; +const xml_token_t XML_targetElement = 1982; +const xml_token_t XML_tb = 1983; +const xml_token_t XML_tb_lr = 1984; +const xml_token_t XML_tb_rl = 1985; +const xml_token_t XML_techreport = 1986; +const xml_token_t XML_template = 1987; +const xml_token_t XML_template_name = 1988; +const xml_token_t XML_text = 1989; +const xml_token_t XML_text_align = 1990; +const xml_token_t XML_text_align_last = 1991; +const xml_token_t XML_text_align_source = 1992; +const xml_token_t XML_text_areas = 1993; +const xml_token_t XML_text_autospace = 1994; +const xml_token_t XML_text_blinking = 1995; +const xml_token_t XML_text_box = 1996; +const xml_token_t XML_text_combine = 1997; +const xml_token_t XML_text_combine_end_char = 1998; +const xml_token_t XML_text_combine_start_char = 1999; +const xml_token_t XML_text_content = 2000; +const xml_token_t XML_text_emphasize = 2001; +const xml_token_t XML_text_indent = 2002; +const xml_token_t XML_text_input = 2003; +const xml_token_t XML_text_line_through_color = 2004; +const xml_token_t XML_text_line_through_mode = 2005; +const xml_token_t XML_text_line_through_style = 2006; +const xml_token_t XML_text_line_through_text = 2007; +const xml_token_t XML_text_line_through_text_style = 2008; +const xml_token_t XML_text_line_through_type = 2009; +const xml_token_t XML_text_line_through_width = 2010; +const xml_token_t XML_text_outline = 2011; +const xml_token_t XML_text_overlap = 2012; +const xml_token_t XML_text_overline_color = 2013; +const xml_token_t XML_text_overline_mode = 2014; +const xml_token_t XML_text_overline_style = 2015; +const xml_token_t XML_text_overline_type = 2016; +const xml_token_t XML_text_overline_width = 2017; +const xml_token_t XML_text_path = 2018; +const xml_token_t XML_text_path_allowed = 2019; +const xml_token_t XML_text_path_mode = 2020; +const xml_token_t XML_text_path_same_letter_heights = 2021; +const xml_token_t XML_text_path_scale = 2022; +const xml_token_t XML_text_position = 2023; +const xml_token_t XML_text_properties = 2024; +const xml_token_t XML_text_rotate_angle = 2025; +const xml_token_t XML_text_rotation_angle = 2026; +const xml_token_t XML_text_rotation_scale = 2027; +const xml_token_t XML_text_scale = 2028; +const xml_token_t XML_text_shadow = 2029; +const xml_token_t XML_text_style = 2030; +const xml_token_t XML_text_style_name = 2031; +const xml_token_t XML_text_transform = 2032; +const xml_token_t XML_text_underline_color = 2033; +const xml_token_t XML_text_underline_mode = 2034; +const xml_token_t XML_text_underline_style = 2035; +const xml_token_t XML_text_underline_type = 2036; +const xml_token_t XML_text_underline_width = 2037; +const xml_token_t XML_textarea = 2038; +const xml_token_t XML_textarea_horizontal_align = 2039; +const xml_token_t XML_textarea_vertical_align = 2040; +const xml_token_t XML_textual = 2041; +const xml_token_t XML_texture_filter = 2042; +const xml_token_t XML_texture_generation_mode_x = 2043; +const xml_token_t XML_texture_generation_mode_y = 2044; +const xml_token_t XML_texture_kind = 2045; +const xml_token_t XML_texture_mode = 2046; +const xml_token_t XML_thick = 2047; +const xml_token_t XML_thin = 2048; +const xml_token_t XML_thousand = 2049; +const xml_token_t XML_three_dimensional = 2050; +const xml_token_t XML_thumbnail = 2051; +const xml_token_t XML_tick_mark_position = 2052; +const xml_token_t XML_tick_marks_major_inner = 2053; +const xml_token_t XML_tick_marks_major_outer = 2054; +const xml_token_t XML_tick_marks_minor_inner = 2055; +const xml_token_t XML_tick_marks_minor_outer = 2056; +const xml_token_t XML_tile_repeat_offset = 2057; +const xml_token_t XML_time = 2058; +const xml_token_t XML_time_adjust = 2059; +const xml_token_t XML_time_style = 2060; +const xml_token_t XML_time_value = 2061; +const xml_token_t XML_timestmp = 2062; +const xml_token_t XML_timing_root = 2063; +const xml_token_t XML_tinyint = 2064; +const xml_token_t XML_title = 2065; +const xml_token_t XML_to = 2066; +const xml_token_t XML_to_another_table = 2067; +const xml_token_t XML_to_bottom = 2068; +const xml_token_t XML_to_center = 2069; +const xml_token_t XML_to_left = 2070; +const xml_token_t XML_to_lower_left = 2071; +const xml_token_t XML_to_lower_right = 2072; +const xml_token_t XML_to_right = 2073; +const xml_token_t XML_to_top = 2074; +const xml_token_t XML_to_upper_left = 2075; +const xml_token_t XML_to_upper_right = 2076; +const xml_token_t XML_toc_mark = 2077; +const xml_token_t XML_toc_mark_end = 2078; +const xml_token_t XML_toc_mark_start = 2079; +const xml_token_t XML_toggle = 2080; +const xml_token_t XML_top = 2081; +const xml_token_t XML_top_end = 2082; +const xml_token_t XML_top_left = 2083; +const xml_token_t XML_top_right = 2084; +const xml_token_t XML_top_start = 2085; +const xml_token_t XML_total_percentage = 2086; +const xml_token_t XML_trace_dependents = 2087; +const xml_token_t XML_trace_errors = 2088; +const xml_token_t XML_trace_precedents = 2089; +const xml_token_t XML_track_changes = 2090; +const xml_token_t XML_tracked_changes = 2091; +const xml_token_t XML_transform = 2092; +const xml_token_t XML_transformation = 2093; +const xml_token_t XML_transition = 2094; +const xml_token_t XML_transition_on_click = 2095; +const xml_token_t XML_transition_speed = 2096; +const xml_token_t XML_transition_style = 2097; +const xml_token_t XML_transition_type = 2098; +const xml_token_t XML_transitionFilter = 2099; +const xml_token_t XML_translate = 2100; +const xml_token_t XML_transliteration_country = 2101; +const xml_token_t XML_transliteration_format = 2102; +const xml_token_t XML_transliteration_language = 2103; +const xml_token_t XML_transliteration_style = 2104; +const xml_token_t XML_transparent = 2105; +const xml_token_t XML_treat_empty_cells = 2106; +const xml_token_t XML_triple = 2107; +const xml_token_t XML_true = 2108; +const xml_token_t XML_truncate_on_overflow = 2109; +const xml_token_t XML_ttb = 2110; +const xml_token_t XML_type = 2111; +const xml_token_t XML_type_name = 2112; +const xml_token_t XML_ultra_condensed = 2113; +const xml_token_t XML_ultra_expanded = 2114; +const xml_token_t XML_unchecked = 2115; +const xml_token_t XML_uncover_to_bottom = 2116; +const xml_token_t XML_uncover_to_left = 2117; +const xml_token_t XML_uncover_to_lowerleft = 2118; +const xml_token_t XML_uncover_to_lowerright = 2119; +const xml_token_t XML_uncover_to_right = 2120; +const xml_token_t XML_uncover_to_top = 2121; +const xml_token_t XML_uncover_to_upperleft = 2122; +const xml_token_t XML_uncover_to_upperright = 2123; +const xml_token_t XML_underline_position = 2124; +const xml_token_t XML_underline_thickness = 2125; +const xml_token_t XML_unicode_range = 2126; +const xml_token_t XML_unique = 2127; +const xml_token_t XML_unit = 2128; +const xml_token_t XML_units_per_em = 2129; +const xml_token_t XML_unknown = 2130; +const xml_token_t XML_unpublished = 2131; +const xml_token_t XML_unsorted = 2132; +const xml_token_t XML_up = 2133; +const xml_token_t XML_update_rule = 2134; +const xml_token_t XML_update_table = 2135; +const xml_token_t XML_uppercase = 2136; +const xml_token_t XML_url = 2137; +const xml_token_t XML_use_banding_columns_styles = 2138; +const xml_token_t XML_use_banding_rows_styles = 2139; +const xml_token_t XML_use_caption = 2140; +const xml_token_t XML_use_catalog = 2141; +const xml_token_t XML_use_chart_objects = 2142; +const xml_token_t XML_use_date_time_name = 2143; +const xml_token_t XML_use_draw_objects = 2144; +const xml_token_t XML_use_first_column_styles = 2145; +const xml_token_t XML_use_first_row_styles = 2146; +const xml_token_t XML_use_floating_frames = 2147; +const xml_token_t XML_use_footer_name = 2148; +const xml_token_t XML_use_graphics = 2149; +const xml_token_t XML_use_header_name = 2150; +const xml_token_t XML_use_index_marks = 2151; +const xml_token_t XML_use_index_source_styles = 2152; +const xml_token_t XML_use_keys_as_entries = 2153; +const xml_token_t XML_use_labels = 2154; +const xml_token_t XML_use_last_column_styles = 2155; +const xml_token_t XML_use_last_row_styles = 2156; +const xml_token_t XML_use_math_objects = 2157; +const xml_token_t XML_use_objects = 2158; +const xml_token_t XML_use_optimal_column_width = 2159; +const xml_token_t XML_use_optimal_row_height = 2160; +const xml_token_t XML_use_other_objects = 2161; +const xml_token_t XML_use_outline_level = 2162; +const xml_token_t XML_use_regular_expressions = 2163; +const xml_token_t XML_use_soft_page_breaks = 2164; +const xml_token_t XML_use_spreadsheet_objects = 2165; +const xml_token_t XML_use_system_user = 2166; +const xml_token_t XML_use_tables = 2167; +const xml_token_t XML_use_wildcards = 2168; +const xml_token_t XML_use_window_font_color = 2169; +const xml_token_t XML_use_zero = 2170; +const xml_token_t XML_used_hierarchy = 2171; +const xml_token_t XML_user_defined = 2172; +const xml_token_t XML_user_field_decl = 2173; +const xml_token_t XML_user_field_decls = 2174; +const xml_token_t XML_user_field_get = 2175; +const xml_token_t XML_user_field_input = 2176; +const xml_token_t XML_user_index = 2177; +const xml_token_t XML_user_index_entry_template = 2178; +const xml_token_t XML_user_index_mark = 2179; +const xml_token_t XML_user_index_mark_end = 2180; +const xml_token_t XML_user_index_mark_start = 2181; +const xml_token_t XML_user_index_source = 2182; +const xml_token_t XML_user_name = 2183; +const xml_token_t XML_user_transformed = 2184; +const xml_token_t XML_v_alphabetic = 2185; +const xml_token_t XML_v_hanging = 2186; +const xml_token_t XML_v_ideographic = 2187; +const xml_token_t XML_v_mathematical = 2188; +const xml_token_t XML_validation = 2189; +const xml_token_t XML_value = 2190; +const xml_token_t XML_value_and_percentage = 2191; +const xml_token_t XML_value_list = 2192; +const xml_token_t XML_value_range = 2193; +const xml_token_t XML_value_type = 2194; +const xml_token_t XML_values = 2195; +const xml_token_t XML_values_cell_range_address = 2196; +const xml_token_t XML_var = 2197; +const xml_token_t XML_varbinary = 2198; +const xml_token_t XML_varchar = 2199; +const xml_token_t XML_variable = 2200; +const xml_token_t XML_variable_decl = 2201; +const xml_token_t XML_variable_decls = 2202; +const xml_token_t XML_variable_get = 2203; +const xml_token_t XML_variable_input = 2204; +const xml_token_t XML_variable_set = 2205; +const xml_token_t XML_variance = 2206; +const xml_token_t XML_varp = 2207; +const xml_token_t XML_verb = 2208; +const xml_token_t XML_version = 2209; +const xml_token_t XML_vertical = 2210; +const xml_token_t XML_vertical_align = 2211; +const xml_token_t XML_vertical_bar = 2212; +const xml_token_t XML_vertical_checkerboard = 2213; +const xml_token_t XML_vertical_lines = 2214; +const xml_token_t XML_vertical_pos = 2215; +const xml_token_t XML_vertical_rel = 2216; +const xml_token_t XML_vertical_segments = 2217; +const xml_token_t XML_vertical_stripes = 2218; +const xml_token_t XML_viewBox = 2219; +const xml_token_t XML_visibility = 2220; +const xml_token_t XML_visible = 2221; +const xml_token_t XML_visible_area_height = 2222; +const xml_token_t XML_visible_area_left = 2223; +const xml_token_t XML_visible_area_top = 2224; +const xml_token_t XML_visible_area_width = 2225; +const xml_token_t XML_visited_style_name = 2226; +const xml_token_t XML_visual_effect = 2227; +const xml_token_t XML_void = 2228; +const xml_token_t XML_volatile = 2229; +const xml_token_t XML_volume = 2230; +const xml_token_t XML_vpn = 2231; +const xml_token_t XML_vrp = 2232; +const xml_token_t XML_vup = 2233; +const xml_token_t XML_wall = 2234; +const xml_token_t XML_warning = 2235; +const xml_token_t XML_watermark = 2236; +const xml_token_t XML_wave = 2237; +const xml_token_t XML_wavyline = 2238; +const xml_token_t XML_wavyline_from_bottom = 2239; +const xml_token_t XML_wavyline_from_left = 2240; +const xml_token_t XML_wavyline_from_right = 2241; +const xml_token_t XML_wavyline_from_top = 2242; +const xml_token_t XML_week_of_year = 2243; +const xml_token_t XML_whenNotActive = 2244; +const xml_token_t XML_wide = 2245; +const xml_token_t XML_widows = 2246; +const xml_token_t XML_width = 2247; +const xml_token_t XML_widths = 2248; +const xml_token_t XML_with_previous = 2249; +const xml_token_t XML_word = 2250; +const xml_token_t XML_word_count = 2251; +const xml_token_t XML_wrap = 2252; +const xml_token_t XML_wrap_contour = 2253; +const xml_token_t XML_wrap_contour_mode = 2254; +const xml_token_t XML_wrap_dynamic_threshold = 2255; +const xml_token_t XML_wrap_influence_on_position = 2256; +const xml_token_t XML_wrap_option = 2257; +const xml_token_t XML_writing_mode = 2258; +const xml_token_t XML_writing_mode_automatic = 2259; +const xml_token_t XML_www = 2260; +const xml_token_t XML_x = 2261; +const xml_token_t XML_x_height = 2262; +const xml_token_t XML_x1 = 2263; +const xml_token_t XML_x2 = 2264; +const xml_token_t XML_xforms = 2265; +const xml_token_t XML_xforms_list_source = 2266; +const xml_token_t XML_xforms_submission = 2267; +const xml_token_t XML_xhtml = 2268; +const xml_token_t XML_xlink = 2269; +const xml_token_t XML_xml = 2270; +const xml_token_t XML_y = 2271; +const xml_token_t XML_y1 = 2272; +const xml_token_t XML_y2 = 2273; +const xml_token_t XML_year = 2274; +const xml_token_t XML_years = 2275; +const xml_token_t XML_z = 2276; +const xml_token_t XML_z_index = 2277; +const xml_token_t XML_zero_values = 2278; diff --git a/src/liborcus/odf_tokens.cpp b/src/liborcus/odf_tokens.cpp new file mode 100644 index 0000000..b20414d --- /dev/null +++ b/src/liborcus/odf_tokens.cpp @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "odf_tokens.hpp" + +namespace orcus { + +namespace { + +#include "odf_tokens.inl" + +} + +tokens odf_tokens = tokens(token_names, token_name_count); + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_tokens.hpp b/src/liborcus/odf_tokens.hpp new file mode 100644 index 0000000..db1befa --- /dev/null +++ b/src/liborcus/odf_tokens.hpp @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef __ORCUS_ODF_TOKENS_HPP__ +#define __ORCUS_ODF_TOKENS_HPP__ + +#include "orcus/tokens.hpp" + +namespace orcus { + +/** + * Singleton instance containing all ODF tokens. + */ +extern tokens odf_tokens; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_tokens.inl b/src/liborcus/odf_tokens.inl new file mode 100644 index 0000000..623c721 --- /dev/null +++ b/src/liborcus/odf_tokens.inl @@ -0,0 +1,2285 @@ +// This file has been auto-generated. Do not hand-edit this. + +const char* token_names[] = { + "??", // 0 + "0", // 1 + "0deg", // 2 + "0grad", // 3 + "0rad", // 4 + "1", // 5 + "1.3", // 6 + "100", // 7 + "2", // 8 + "200", // 9 + "3", // 10 + "300", // 11 + "3d", // 12 + "400", // 13 + "500", // 14 + "600", // 15 + "700", // 16 + "800", // 17 + "900", // 18 + "A", // 19 + "I", // 20 + "ROC", // 21 + "_blank", // 22 + "_parent", // 23 + "_self", // 24 + "_top", // 25 + "a", // 26 + "about", // 27 + "above", // 28 + "accelerate", // 29 + "accent", // 30 + "accent-height", // 31 + "acceptance-state", // 32 + "accepted", // 33 + "accumulate", // 34 + "action", // 35 + "active", // 36 + "actuate", // 37 + "add-empty-lines", // 38 + "additional-column-statement", // 39 + "additive", // 40 + "address", // 41 + "adjustment", // 42 + "after-previous", // 43 + "algorithm", // 44 + "align", // 45 + "all", // 46 + "allow-deletes", // 47 + "allow-empty-cell", // 48 + "allow-inserts", // 49 + "allow-updates", // 50 + "alpha-numeric", // 51 + "alphabetic", // 52 + "alphabetical-index", // 53 + "alphabetical-index-auto-mark-file", // 54 + "alphabetical-index-entry-template", // 55 + "alphabetical-index-mark", // 56 + "alphabetical-index-mark-end", // 57 + "alphabetical-index-mark-start", // 58 + "alphabetical-index-source", // 59 + "alphabetical-separators", // 60 + "alternate", // 61 + "always", // 62 + "am-pm", // 63 + "ambient-color", // 64 + "anchor-page-number", // 65 + "anchor-type", // 66 + "angle", // 67 + "angle-offset", // 68 + "angled-connector-line", // 69 + "angled-line", // 70 + "anim", // 71 + "animate", // 72 + "animateColor", // 73 + "animateMotion", // 74 + "animateTransform", // 75 + "animation", // 76 + "animation-delay", // 77 + "animation-direction", // 78 + "animation-group", // 79 + "animation-repeat", // 80 + "animation-start-inside", // 81 + "animation-steps", // 82 + "animation-stop-inside", // 83 + "animations", // 84 + "annotation", // 85 + "annotation-end", // 86 + "annotations", // 87 + "annote", // 88 + "appear", // 89 + "append-table-alias-name", // 90 + "applet", // 91 + "application-connection-settings", // 92 + "application-data", // 93 + "apply-command", // 94 + "apply-design-mode", // 95 + "apply-filter", // 96 + "apply-style-name", // 97 + "arc", // 98 + "archive", // 99 + "area", // 100 + "area-circle", // 101 + "area-polygon", // 102 + "area-rectangle", // 103 + "array", // 104 + "arrow-down", // 105 + "arrow-left", // 106 + "arrow-right", // 107 + "arrow-up", // 108 + "article", // 109 + "as-char", // 110 + "as-template", // 111 + "ascending", // 112 + "ascent", // 113 + "asian", // 114 + "asterisk", // 115 + "at-axis", // 116 + "at-labels", // 117 + "at-labels-and-axis", // 118 + "attached-axis", // 119 + "attractive", // 120 + "attributeName", // 121 + "audio", // 122 + "audio-level", // 123 + "author", // 124 + "author-initials", // 125 + "author-name", // 126 + "auto", // 127 + "auto-complete", // 128 + "auto-create-new-frame", // 129 + "auto-grow-height", // 130 + "auto-grow-width", // 131 + "auto-increment", // 132 + "auto-position", // 133 + "auto-reload", // 134 + "auto-size", // 135 + "auto-text-indent", // 136 + "auto-update", // 137 + "autoReverse", // 138 + "automatic", // 139 + "automatic-content", // 140 + "automatic-find-labels", // 141 + "automatic-focus", // 142 + "automatic-order", // 143 + "automatic-styles", // 144 + "automatic-update", // 145 + "average", // 146 + "averaged-abscissa", // 147 + "avoid-overlap", // 148 + "axial", // 149 + "axis", // 150 + "axis-label-position", // 151 + "axis-position", // 152 + "b-spline", // 153 + "back-scale", // 154 + "backface-culling", // 155 + "background", // 156 + "background-color", // 157 + "background-image", // 158 + "background-objects-visible", // 159 + "background-size", // 160 + "background-transparency", // 161 + "background-visible", // 162 + "balanced", // 163 + "base-cell-address", // 164 + "base-dn", // 165 + "base64Binary", // 166 + "baseline", // 167 + "bbox", // 168 + "begin", // 169 + "below", // 170 + "bevel", // 171 + "bibliography", // 172 + "bibliography-configuration", // 173 + "bibliography-data-field", // 174 + "bibliography-entry-template", // 175 + "bibliography-mark", // 176 + "bibliography-source", // 177 + "bibliography-type", // 178 + "biggest", // 179 + "bigint", // 180 + "binary", // 181 + "binary-data", // 182 + "bind", // 183 + "bind-styles-to-content", // 184 + "bit", // 185 + "bitmap", // 186 + "blend", // 187 + "blob", // 188 + "blue", // 189 + "body", // 190 + "bold", // 191 + "book", // 192 + "booklet", // 193 + "bookmark", // 194 + "bookmark-end", // 195 + "bookmark-start", // 196 + "booktitle", // 197 + "boolean", // 198 + "boolean-comparison-mode", // 199 + "boolean-style", // 200 + "boolean-value", // 201 + "border", // 202 + "border-bottom", // 203 + "border-color", // 204 + "border-left", // 205 + "border-line-width", // 206 + "border-line-width-bottom", // 207 + "border-line-width-left", // 208 + "border-line-width-right", // 209 + "border-line-width-top", // 210 + "border-model", // 211 + "border-right", // 212 + "border-top", // 213 + "both", // 214 + "bottom", // 215 + "bottom-end", // 216 + "bottom-left", // 217 + "bottom-right", // 218 + "bottom-start", // 219 + "bound-column", // 220 + "bow-tie", // 221 + "break-after", // 222 + "break-before", // 223 + "buddhist", // 224 + "bullet-char", // 225 + "bullet-relative-size", // 226 + "butt", // 227 + "button", // 228 + "button-type", // 229 + "buttons", // 230 + "by", // 231 + "c", // 232 + "calcMode", // 233 + "calculation-settings", // 234 + "calendar", // 235 + "cap-height", // 236 + "capitalize", // 237 + "capitalize-entries", // 238 + "caption", // 239 + "caption-angle", // 240 + "caption-angle-type", // 241 + "caption-escape", // 242 + "caption-escape-direction", // 243 + "caption-fit-line-length", // 244 + "caption-gap", // 245 + "caption-id", // 246 + "caption-line-length", // 247 + "caption-point-x", // 248 + "caption-point-y", // 249 + "caption-sequence-format", // 250 + "caption-sequence-name", // 251 + "caption-type", // 252 + "cascade", // 253 + "case-sensitive", // 254 + "catalog-name", // 255 + "categories", // 256 + "category-and-value", // 257 + "cell-address", // 258 + "cell-content-change", // 259 + "cell-content-deletion", // 260 + "cell-count", // 261 + "cell-protect", // 262 + "cell-range", // 263 + "cell-range-address", // 264 + "cell-range-source", // 265 + "center", // 266 + "central", // 267 + "chain-next-name", // 268 + "change", // 269 + "change-deletion", // 270 + "change-end", // 271 + "change-id", // 272 + "change-info", // 273 + "change-start", // 274 + "change-track-table-cell", // 275 + "changed-region", // 276 + "chapter", // 277 + "char", // 278 + "character-count", // 279 + "character-set", // 280 + "chart", // 281 + "chart-properties", // 282 + "charts", // 283 + "checkbox", // 284 + "checked", // 285 + "checkerboard", // 286 + "circle", // 287 + "citation-body-style-name", // 288 + "citation-style-name", // 289 + "class", // 290 + "class-id", // 291 + "class-names", // 292 + "clip", // 293 + "clob", // 294 + "clockwise", // 295 + "close", // 296 + "close-back", // 297 + "close-front", // 298 + "close-horizontal", // 299 + "close-vertical", // 300 + "cm", // 301 + "code", // 302 + "collapse", // 303 + "collapsing", // 304 + "color", // 305 + "color-interpolation", // 306 + "color-interpolation-direction", // 307 + "color-inversion", // 308 + "color-mode", // 309 + "column", // 310 + "column-count", // 311 + "column-definition", // 312 + "column-definitions", // 313 + "column-gap", // 314 + "column-mapping", // 315 + "column-name", // 316 + "column-percentage", // 317 + "column-sep", // 318 + "column-width", // 319 + "columns", // 320 + "combine-entries", // 321 + "combine-entries-with-dash", // 322 + "combine-entries-with-pp", // 323 + "combobox", // 324 + "comma-separated", // 325 + "command", // 326 + "command-type", // 327 + "comment", // 328 + "complex", // 329 + "component", // 330 + "component-collection", // 331 + "concave", // 332 + "concentric-gradient-fill-allowed", // 333 + "cond-style-name", // 334 + "condensed", // 335 + "condition", // 336 + "condition-source", // 337 + "condition-source-range-address", // 338 + "conditional-text", // 339 + "cone", // 340 + "conference", // 341 + "config", // 342 + "config-item", // 343 + "config-item-map-entry", // 344 + "config-item-map-indexed", // 345 + "config-item-map-named", // 346 + "config-item-set", // 347 + "connect-bars", // 348 + "connection-data", // 349 + "connection-name", // 350 + "connection-resource", // 351 + "connector", // 352 + "consecutive-numbering", // 353 + "consolidation", // 354 + "constant", // 355 + "contains-error", // 356 + "contains-header", // 357 + "content", // 358 + "content-validation", // 359 + "content-validation-name", // 360 + "content-validations", // 361 + "contextual-spacing", // 362 + "continue", // 363 + "continue-list", // 364 + "continue-numbering", // 365 + "continuous", // 366 + "contour-path", // 367 + "contour-polygon", // 368 + "contrast", // 369 + "control", // 370 + "control-implementation", // 371 + "conversion-mode", // 372 + "convert-empty-to-null", // 373 + "coordinate-region", // 374 + "copy-all", // 375 + "copy-back", // 376 + "copy-formulas", // 377 + "copy-of", // 378 + "copy-outline-levels", // 379 + "copy-results-only", // 380 + "copy-styles", // 381 + "corner-radius", // 382 + "corners", // 383 + "correct", // 384 + "count", // 385 + "count-empty-lines", // 386 + "count-in-text-boxes", // 387 + "counter-clockwise", // 388 + "counterclockwise", // 389 + "countnums", // 390 + "country", // 391 + "country-asian", // 392 + "country-complex", // 393 + "covered-table-cell", // 394 + "creation-date", // 395 + "creation-time", // 396 + "creator", // 397 + "creator-initials", // 398 + "cube", // 399 + "cubic-spline", // 400 + "cuboid", // 401 + "currency", // 402 + "currency-style", // 403 + "currency-symbol", // 404 + "current", // 405 + "current-date", // 406 + "current-selected", // 407 + "current-state", // 408 + "current-value", // 409 + "curve", // 410 + "custom", // 411 + "custom-shape", // 412 + "custom1", // 413 + "custom2", // 414 + "custom3", // 415 + "custom4", // 416 + "custom5", // 417 + "cut", // 418 + "cut-offs", // 419 + "cx", // 420 + "cy", // 421 + "cylinder", // 422 + "d", // 423 + "dash", // 424 + "dashed", // 425 + "data", // 426 + "data-cell-range-address", // 427 + "data-field", // 428 + "data-label", // 429 + "data-label-number", // 430 + "data-label-series", // 431 + "data-label-symbol", // 432 + "data-label-text", // 433 + "data-pilot-display-info", // 434 + "data-pilot-field", // 435 + "data-pilot-field-reference", // 436 + "data-pilot-group", // 437 + "data-pilot-group-member", // 438 + "data-pilot-groups", // 439 + "data-pilot-layout-info", // 440 + "data-pilot-level", // 441 + "data-pilot-member", // 442 + "data-pilot-members", // 443 + "data-pilot-sort-info", // 444 + "data-pilot-subtotal", // 445 + "data-pilot-subtotals", // 446 + "data-pilot-table", // 447 + "data-pilot-tables", // 448 + "data-point", // 449 + "data-source", // 450 + "data-source-has-labels", // 451 + "data-source-setting", // 452 + "data-source-setting-is-list", // 453 + "data-source-setting-name", // 454 + "data-source-setting-type", // 455 + "data-source-setting-value", // 456 + "data-source-settings", // 457 + "data-style-name", // 458 + "data-type", // 459 + "database", // 460 + "database-description", // 461 + "database-display", // 462 + "database-name", // 463 + "database-next", // 464 + "database-range", // 465 + "database-ranges", // 466 + "database-row-number", // 467 + "database-row-select", // 468 + "database-source-query", // 469 + "database-source-sql", // 470 + "database-source-table", // 471 + "database-table-name", // 472 + "datasource", // 473 + "datatype", // 474 + "date", // 475 + "date-adjust", // 476 + "date-end", // 477 + "date-start", // 478 + "date-string", // 479 + "date-style", // 480 + "date-time", // 481 + "date-time-decl", // 482 + "date-value", // 483 + "datetime", // 484 + "day", // 485 + "day-of-week", // 486 + "days", // 487 + "db", // 488 + "dc", // 489 + "dde-application", // 490 + "dde-connection", // 491 + "dde-connection-decl", // 492 + "dde-connection-decls", // 493 + "dde-item", // 494 + "dde-link", // 495 + "dde-links", // 496 + "dde-source", // 497 + "dde-topic", // 498 + "decelerate", // 499 + "decimal", // 500 + "decimal-places", // 501 + "decimal-replacement", // 502 + "decorative", // 503 + "deep", // 504 + "default", // 505 + "default-button", // 506 + "default-cell-style-name", // 507 + "default-outline-level", // 508 + "default-page-layout", // 509 + "default-row-style-name", // 510 + "default-style", // 511 + "default-style-name", // 512 + "definition-src", // 513 + "delay", // 514 + "delay-for-repeat", // 515 + "delete-rule", // 516 + "deletion", // 517 + "deletions", // 518 + "delimiter", // 519 + "denominator-value", // 520 + "dependencies", // 521 + "dependency", // 522 + "depth", // 523 + "desc", // 524 + "descending", // 525 + "descent", // 526 + "description", // 527 + "detail-fields", // 528 + "detective", // 529 + "diagonal-bl-tr", // 530 + "diagonal-bl-tr-widths", // 531 + "diagonal-tl-br", // 532 + "diagonal-tl-br-widths", // 533 + "diamond", // 534 + "diffuse-color", // 535 + "dim", // 536 + "dimension", // 537 + "direction", // 538 + "disable", // 539 + "disabled", // 540 + "disc", // 541 + "discrete", // 542 + "display", // 543 + "display-border", // 544 + "display-date-time", // 545 + "display-duplicates", // 546 + "display-equation", // 547 + "display-factor", // 548 + "display-filter-buttons", // 549 + "display-footer", // 550 + "display-header", // 551 + "display-label", // 552 + "display-levels", // 553 + "display-list", // 554 + "display-member-mode", // 555 + "display-name", // 556 + "display-outline-level", // 557 + "display-page-number", // 558 + "display-r-square", // 559 + "dissolve", // 560 + "distance", // 561 + "distance-after-sep", // 562 + "distance-before-sep", // 563 + "distinct", // 564 + "distribute-letter", // 565 + "distribute-space", // 566 + "document", // 567 + "document-content", // 568 + "document-meta", // 569 + "document-settings", // 570 + "document-statistic", // 571 + "document-styles", // 572 + "domain", // 573 + "dont-balance-text-columns", // 574 + "dot", // 575 + "dot-dash", // 576 + "dot-dashed", // 577 + "dot-dot-dash", // 578 + "dots1", // 579 + "dots1-length", // 580 + "dots2", // 581 + "dots2-length", // 582 + "dotted", // 583 + "double", // 584 + "double-sided", // 585 + "down", // 586 + "dr3d", // 587 + "draft", // 588 + "draw", // 589 + "draw-aspect", // 590 + "draw-count", // 591 + "drawing", // 592 + "drawing-page", // 593 + "drawing-page-properties", // 594 + "drawings", // 595 + "drill-down-on-double-click", // 596 + "driver-settings", // 597 + "drop-cap", // 598 + "drop-down", // 599 + "dropdown", // 600 + "dur", // 601 + "duration", // 602 + "dynamic", // 603 + "dynamic-spacing", // 604 + "echo-char", // 605 + "edge-rounding", // 606 + "edge-rounding-mode", // 607 + "editable", // 608 + "editing-cycles", // 609 + "editing-duration", // 610 + "edition", // 611 + "editor", // 612 + "effect", // 613 + "ellipse", // 614 + "ellipsoid", // 615 + "email", // 616 + "embed", // 617 + "embedded-number-behavior", // 618 + "embedded-text", // 619 + "embossed", // 620 + "emissive-color", // 621 + "emphasis", // 622 + "enable", // 623 + "enable-sql92-check", // 624 + "enabled", // 625 + "encoding", // 626 + "enctype", // 627 + "end", // 628 + "end-angle", // 629 + "end-cell-address", // 630 + "end-color", // 631 + "end-column", // 632 + "end-glue-point", // 633 + "end-guide", // 634 + "end-indent", // 635 + "end-intensity", // 636 + "end-line-spacing-horizontal", // 637 + "end-line-spacing-vertical", // 638 + "end-position", // 639 + "end-row", // 640 + "end-shape", // 641 + "end-table", // 642 + "end-x", // 643 + "end-y", // 644 + "endless", // 645 + "endnote", // 646 + "endsync", // 647 + "engine", // 648 + "engraved", // 649 + "enhanced-geometry", // 650 + "enhanced-path", // 651 + "entrance", // 652 + "equal-boolean", // 653 + "equal-integer", // 654 + "equal-use-only-zero", // 655 + "equation", // 656 + "era", // 657 + "error-category", // 658 + "error-indicator", // 659 + "error-lower-indicator", // 660 + "error-lower-limit", // 661 + "error-lower-range", // 662 + "error-macro", // 663 + "error-margin", // 664 + "error-message", // 665 + "error-percentage", // 666 + "error-upper-indicator", // 667 + "error-upper-limit", // 668 + "error-upper-range", // 669 + "escape-direction", // 670 + "escape-processing", // 671 + "even-columns", // 672 + "even-rows", // 673 + "evenodd", // 674 + "event-listener", // 675 + "event-listeners", // 676 + "event-name", // 677 + "execute", // 678 + "execute-macro", // 679 + "exit", // 680 + "expanded", // 681 + "exponent-interval", // 682 + "exponential", // 683 + "expression", // 684 + "extension", // 685 + "extra-condensed", // 686 + "extra-expanded", // 687 + "extrude", // 688 + "extrusion", // 689 + "extrusion-allowed", // 690 + "extrusion-brightness", // 691 + "extrusion-color", // 692 + "extrusion-depth", // 693 + "extrusion-diffusion", // 694 + "extrusion-first-light-direction", // 695 + "extrusion-first-light-harsh", // 696 + "extrusion-first-light-level", // 697 + "extrusion-light-face", // 698 + "extrusion-metal", // 699 + "extrusion-number-of-line-segments", // 700 + "extrusion-origin", // 701 + "extrusion-rotation-angle", // 702 + "extrusion-rotation-center", // 703 + "extrusion-second-light-direction", // 704 + "extrusion-second-light-harsh", // 705 + "extrusion-second-light-level", // 706 + "extrusion-shininess", // 707 + "extrusion-skew", // 708 + "extrusion-specularity", // 709 + "extrusion-viewpoint", // 710 + "fade", // 711 + "fade-from-bottom", // 712 + "fade-from-center", // 713 + "fade-from-left", // 714 + "fade-from-lowerleft", // 715 + "fade-from-lowerright", // 716 + "fade-from-right", // 717 + "fade-from-top", // 718 + "fade-from-upperleft", // 719 + "fade-from-upperright", // 720 + "fade-out", // 721 + "fade-to-center", // 722 + "fadeColor", // 723 + "false", // 724 + "family", // 725 + "fast", // 726 + "field", // 727 + "field-name", // 728 + "field-number", // 729 + "file", // 730 + "file-based-database", // 731 + "file-name", // 732 + "fill", // 733 + "fill-character", // 734 + "fill-color", // 735 + "fill-gradient-name", // 736 + "fill-hatch-name", // 737 + "fill-hatch-solid", // 738 + "fill-image", // 739 + "fill-image-height", // 740 + "fill-image-name", // 741 + "fill-image-ref-point", // 742 + "fill-image-ref-point-x", // 743 + "fill-image-ref-point-y", // 744 + "fill-image-width", // 745 + "fill-rule", // 746 + "fillDefault", // 747 + "filter", // 748 + "filter-and", // 749 + "filter-condition", // 750 + "filter-name", // 751 + "filter-options", // 752 + "filter-or", // 753 + "filter-set-item", // 754 + "filter-statement", // 755 + "first", // 756 + "first-column", // 757 + "first-page", // 758 + "first-page-number", // 759 + "first-row", // 760 + "first-row-end-column", // 761 + "first-row-start-column", // 762 + "fit-to-contour", // 763 + "fit-to-size", // 764 + "fix", // 765 + "fixed", // 766 + "fixed-text", // 767 + "flat", // 768 + "float", // 769 + "floating-frame", // 770 + "floor", // 771 + "flow-with-text", // 772 + "fly-away", // 773 + "fo", // 774 + "focal-length", // 775 + "focus-on-click", // 776 + "font-adornments", // 777 + "font-charset", // 778 + "font-charset-asian", // 779 + "font-charset-complex", // 780 + "font-color", // 781 + "font-face", // 782 + "font-face-decls", // 783 + "font-face-format", // 784 + "font-face-name", // 785 + "font-face-src", // 786 + "font-face-uri", // 787 + "font-family", // 788 + "font-family-asian", // 789 + "font-family-complex", // 790 + "font-family-generic", // 791 + "font-family-generic-asian", // 792 + "font-family-generic-complex", // 793 + "font-independent-line-spacing", // 794 + "font-name", // 795 + "font-name-asian", // 796 + "font-name-complex", // 797 + "font-pitch", // 798 + "font-pitch-asian", // 799 + "font-pitch-complex", // 800 + "font-relief", // 801 + "font-size", // 802 + "font-size-asian", // 803 + "font-size-complex", // 804 + "font-size-rel", // 805 + "font-size-rel-asian", // 806 + "font-size-rel-complex", // 807 + "font-stretch", // 808 + "font-style", // 809 + "font-style-asian", // 810 + "font-style-complex", // 811 + "font-style-name", // 812 + "font-style-name-asian", // 813 + "font-style-name-complex", // 814 + "font-variant", // 815 + "font-weight", // 816 + "font-weight-asian", // 817 + "font-weight-complex", // 818 + "footer", // 819 + "footer-decl", // 820 + "footer-first", // 821 + "footer-left", // 822 + "footer-style", // 823 + "footnote", // 824 + "footnote-max-height", // 825 + "footnote-sep", // 826 + "footnotes-position", // 827 + "for", // 828 + "force-manual", // 829 + "forced-exponent-sign", // 830 + "foreground", // 831 + "foreign", // 832 + "form", // 833 + "format-change", // 834 + "format-source", // 835 + "formatted-text", // 836 + "forms", // 837 + "formula", // 838 + "formula-hidden", // 839 + "formulas", // 840 + "forward", // 841 + "fraction", // 842 + "frame", // 843 + "frame-content", // 844 + "frame-count", // 845 + "frame-display-border", // 846 + "frame-display-scrollbar", // 847 + "frame-end-margin", // 848 + "frame-margin-horizontal", // 849 + "frame-margin-vertical", // 850 + "frame-name", // 851 + "frame-start-margin", // 852 + "free", // 853 + "freeze", // 854 + "from", // 855 + "from-another-table", // 856 + "from-bottom", // 857 + "from-center", // 858 + "from-inside", // 859 + "from-left", // 860 + "from-lower-left", // 861 + "from-lower-right", // 862 + "from-right", // 863 + "from-same-table", // 864 + "from-top", // 865 + "from-upper-left", // 866 + "from-upper-right", // 867 + "ft", // 868 + "full", // 869 + "full-screen", // 870 + "function", // 871 + "fx", // 872 + "fy", // 873 + "g", // 874 + "gamma", // 875 + "gap", // 876 + "gap-width", // 877 + "generator", // 878 + "generic-control", // 879 + "gengou", // 880 + "get", // 881 + "global", // 882 + "glue-point", // 883 + "glue-point-leaving-directions", // 884 + "glue-point-type", // 885 + "glue-points", // 886 + "glyph-orientation-vertical", // 887 + "gouraud", // 888 + "gradient", // 889 + "gradient-step-count", // 890 + "gradientTransform", // 891 + "gradientUnits", // 892 + "grand-total", // 893 + "graphic", // 894 + "graphic-properties", // 895 + "grddl", // 896 + "green", // 897 + "gregorian", // 898 + "greyscale", // 899 + "grid", // 900 + "group-bars-per-axis", // 901 + "group-by-field-number", // 902 + "group-id", // 903 + "grouped-by", // 904 + "grouping", // 905 + "guide-distance", // 906 + "guide-overhang", // 907 + "h", // 908 + "handle", // 909 + "handle-mirror-horizontal", // 910 + "handle-mirror-vertical", // 911 + "handle-polar", // 912 + "handle-position", // 913 + "handle-radius-range-maximum", // 914 + "handle-radius-range-minimum", // 915 + "handle-range-x-maximum", // 916 + "handle-range-x-minimum", // 917 + "handle-range-y-maximum", // 918 + "handle-range-y-minimum", // 919 + "handle-switched", // 920 + "handout", // 921 + "handout-master", // 922 + "hanging", // 923 + "hanja", // 924 + "hanja_yoil", // 925 + "has-persistent-data", // 926 + "hatch", // 927 + "header", // 928 + "header-decl", // 929 + "header-first", // 930 + "header-footer-properties", // 931 + "header-left", // 932 + "header-style", // 933 + "headers", // 934 + "height", // 935 + "help-message", // 936 + "hidden", // 937 + "hidden-and-protected", // 938 + "hidden-paragraph", // 939 + "hidden-text", // 940 + "hide", // 941 + "hide-shape", // 942 + "hide-text", // 943 + "high", // 944 + "highlighted-range", // 945 + "hijri", // 946 + "hold", // 947 + "hole-size", // 948 + "horizontal", // 949 + "horizontal-bar", // 950 + "horizontal-checkerboard", // 951 + "horizontal-lines", // 952 + "horizontal-on-even", // 953 + "horizontal-on-odd", // 954 + "horizontal-pos", // 955 + "horizontal-rel", // 956 + "horizontal-segments", // 957 + "horizontal-stripes", // 958 + "hostname", // 959 + "hourglass", // 960 + "hours", // 961 + "howpublished", // 962 + "href", // 963 + "hsl", // 964 + "hyperlink-behaviour", // 965 + "hyphenate", // 966 + "hyphenation-keep", // 967 + "hyphenation-ladder-count", // 968 + "hyphenation-push-char-count", // 969 + "hyphenation-remain-char-count", // 970 + "i", // 971 + "icon", // 972 + "id", // 973 + "identifier", // 974 + "identify-categories", // 975 + "ideograph-alpha", // 976 + "ideographic", // 977 + "ignore", // 978 + "ignore-case", // 979 + "ignore-driver-privileges", // 980 + "ignore-empty-rows", // 981 + "ignore-result", // 982 + "illustration-index", // 983 + "illustration-index-entry-template", // 984 + "illustration-index-source", // 985 + "image", // 986 + "image-align", // 987 + "image-count", // 988 + "image-data", // 989 + "image-frame", // 990 + "image-map", // 991 + "image-opacity", // 992 + "image-position", // 993 + "in", // 994 + "inbook", // 995 + "inch", // 996 + "include-hidden-cells", // 997 + "incollection", // 998 + "increment", // 999 + "indefinite", // 1000 + "index", // 1001 + "index-body", // 1002 + "index-column", // 1003 + "index-columns", // 1004 + "index-entry-bibliography", // 1005 + "index-entry-chapter", // 1006 + "index-entry-link-end", // 1007 + "index-entry-link-start", // 1008 + "index-entry-page-number", // 1009 + "index-entry-span", // 1010 + "index-entry-tab-stop", // 1011 + "index-entry-text", // 1012 + "index-name", // 1013 + "index-scope", // 1014 + "index-source-style", // 1015 + "index-source-styles", // 1016 + "index-title", // 1017 + "index-title-template", // 1018 + "indices", // 1019 + "information", // 1020 + "inherit", // 1021 + "initial-creator", // 1022 + "inner", // 1023 + "inproceedings", // 1024 + "insertion", // 1025 + "insertion-cut-off", // 1026 + "inside", // 1027 + "institution", // 1028 + "int", // 1029 + "integer", // 1030 + "intensity", // 1031 + "interactive-sequence", // 1032 + "interlocking-horizontal-left", // 1033 + "interlocking-horizontal-right", // 1034 + "interlocking-vertical-bottom", // 1035 + "interlocking-vertical-top", // 1036 + "interpolation", // 1037 + "interval-major", // 1038 + "interval-minor-divisor", // 1039 + "into-default-style-data-style", // 1040 + "into-english-number", // 1041 + "inverse", // 1042 + "is-active", // 1043 + "is-ascending", // 1044 + "is-autoincrement", // 1045 + "is-boolean", // 1046 + "is-clustered", // 1047 + "is-data-layout-field", // 1048 + "is-empty-allowed", // 1049 + "is-first-row-header-line", // 1050 + "is-hidden", // 1051 + "is-list-header", // 1052 + "is-nullable", // 1053 + "is-password-required", // 1054 + "is-selection", // 1055 + "is-sub-table", // 1056 + "is-table-name-length-limited", // 1057 + "is-tristate", // 1058 + "is-unique", // 1059 + "isbn", // 1060 + "issn", // 1061 + "italic", // 1062 + "item", // 1063 + "iterate", // 1064 + "iterate-interval", // 1065 + "iterate-type", // 1066 + "iteration", // 1067 + "iterative", // 1068 + "japanese-candle-stick", // 1069 + "jewish", // 1070 + "join-border", // 1071 + "journal", // 1072 + "justify", // 1073 + "justify-single-word", // 1074 + "keep-text", // 1075 + "keep-together", // 1076 + "keep-with-next", // 1077 + "key", // 1078 + "key-column", // 1079 + "key-columns", // 1080 + "key1", // 1081 + "key1-phonetic", // 1082 + "key2", // 1083 + "key2-phonetic", // 1084 + "keySplines", // 1085 + "keyTimes", // 1086 + "keys", // 1087 + "keyword", // 1088 + "keywords", // 1089 + "kind", // 1090 + "km", // 1091 + "label", // 1092 + "label-alignment", // 1093 + "label-arrangement", // 1094 + "label-cell-address", // 1095 + "label-cell-range-address", // 1096 + "label-followed-by", // 1097 + "label-position", // 1098 + "label-position-negative", // 1099 + "label-range", // 1100 + "label-ranges", // 1101 + "label-separator", // 1102 + "label-width-and-position", // 1103 + "landscape", // 1104 + "language", // 1105 + "language-asian", // 1106 + "language-complex", // 1107 + "laser", // 1108 + "last", // 1109 + "last-column", // 1110 + "last-column-spanned", // 1111 + "last-page", // 1112 + "last-row", // 1113 + "last-row-end-column", // 1114 + "last-row-spanned", // 1115 + "last-row-start-column", // 1116 + "last-visited-page", // 1117 + "latin", // 1118 + "layer", // 1119 + "layer-set", // 1120 + "layout-grid-base-height", // 1121 + "layout-grid-base-width", // 1122 + "layout-grid-color", // 1123 + "layout-grid-display", // 1124 + "layout-grid-lines", // 1125 + "layout-grid-mode", // 1126 + "layout-grid-print", // 1127 + "layout-grid-ruby-below", // 1128 + "layout-grid-ruby-height", // 1129 + "layout-grid-snap-to", // 1130 + "layout-grid-standard-mode", // 1131 + "layout-mode", // 1132 + "leader-char", // 1133 + "leader-color", // 1134 + "leader-style", // 1135 + "leader-text", // 1136 + "leader-text-style", // 1137 + "leader-type", // 1138 + "leader-width", // 1139 + "leave-gap", // 1140 + "left", // 1141 + "left-outside", // 1142 + "legend", // 1143 + "legend-align", // 1144 + "legend-expansion", // 1145 + "legend-expansion-aspect-ratio", // 1146 + "legend-position", // 1147 + "length", // 1148 + "letter-kerning", // 1149 + "letter-spacing", // 1150 + "letters", // 1151 + "level", // 1152 + "light", // 1153 + "lighting-mode", // 1154 + "line", // 1155 + "line-break", // 1156 + "line-distance", // 1157 + "line-height", // 1158 + "line-height-at-least", // 1159 + "line-number", // 1160 + "line-skew", // 1161 + "line-spacing", // 1162 + "line-style", // 1163 + "linear", // 1164 + "linearGradient", // 1165 + "linenumbering-configuration", // 1166 + "linenumbering-separator", // 1167 + "lines", // 1168 + "link-data-style-to-source", // 1169 + "link-to-source-data", // 1170 + "linked-cell", // 1171 + "list", // 1172 + "list-header", // 1173 + "list-id", // 1174 + "list-item", // 1175 + "list-level", // 1176 + "list-level-label-alignment", // 1177 + "list-level-position-and-space-mode", // 1178 + "list-level-properties", // 1179 + "list-level-style-bullet", // 1180 + "list-level-style-image", // 1181 + "list-level-style-number", // 1182 + "list-linkage-type", // 1183 + "list-property", // 1184 + "list-source", // 1185 + "list-source-type", // 1186 + "list-style", // 1187 + "list-style-name", // 1188 + "list-tab-stop-position", // 1189 + "list-value", // 1190 + "listbox", // 1191 + "listtab", // 1192 + "local-socket", // 1193 + "logarithmic", // 1194 + "login", // 1195 + "login-timeout", // 1196 + "long", // 1197 + "long-dash", // 1198 + "longvarbinary", // 1199 + "longvarchar", // 1200 + "lowercase", // 1201 + "lr", // 1202 + "lr-tb", // 1203 + "ltr", // 1204 + "luminance", // 1205 + "m", // 1206 + "macro-name", // 1207 + "main-entry", // 1208 + "main-entry-style-name", // 1209 + "main-sequence", // 1210 + "major", // 1211 + "manual", // 1212 + "map", // 1213 + "margin", // 1214 + "margin-bottom", // 1215 + "margin-left", // 1216 + "margin-right", // 1217 + "margin-top", // 1218 + "margins", // 1219 + "marked-invalid", // 1220 + "marker", // 1221 + "marker-end", // 1222 + "marker-end-center", // 1223 + "marker-end-width", // 1224 + "marker-start", // 1225 + "marker-start-center", // 1226 + "marker-start-width", // 1227 + "master-element", // 1228 + "master-fields", // 1229 + "master-page", // 1230 + "master-page-name", // 1231 + "master-styles", // 1232 + "mastersthesis", // 1233 + "math", // 1234 + "mathematical", // 1235 + "matrix-covered", // 1236 + "max", // 1237 + "max-denominator-value", // 1238 + "max-edge", // 1239 + "max-height", // 1240 + "max-length", // 1241 + "max-row-count", // 1242 + "max-value", // 1243 + "max-width", // 1244 + "maximum", // 1245 + "maximum-difference", // 1246 + "may-break-between-rows", // 1247 + "may-script", // 1248 + "mean-value", // 1249 + "measure", // 1250 + "measure-align", // 1251 + "measure-vertical-align", // 1252 + "media", // 1253 + "media-call", // 1254 + "media-type", // 1255 + "medium", // 1256 + "melt", // 1257 + "member-count", // 1258 + "member-difference", // 1259 + "member-name", // 1260 + "member-percentage", // 1261 + "member-percentage-difference", // 1262 + "member-type", // 1263 + "message-type", // 1264 + "meta", // 1265 + "meta-field", // 1266 + "method", // 1267 + "mi", // 1268 + "middle", // 1269 + "mime-type", // 1270 + "mimetype", // 1271 + "min", // 1272 + "min-decimal-places", // 1273 + "min-denominator-digits", // 1274 + "min-edge", // 1275 + "min-exponent-digits", // 1276 + "min-height", // 1277 + "min-integer-digits", // 1278 + "min-label-distance", // 1279 + "min-label-width", // 1280 + "min-numerator-digits", // 1281 + "min-row-height", // 1282 + "min-value", // 1283 + "min-width", // 1284 + "minimum", // 1285 + "minor", // 1286 + "minutes", // 1287 + "mirror", // 1288 + "mirror-horizontal", // 1289 + "mirror-vertical", // 1290 + "mirrored", // 1291 + "misc", // 1292 + "miter", // 1293 + "mm", // 1294 + "mode", // 1295 + "model", // 1296 + "modern", // 1297 + "modification-date", // 1298 + "modification-time", // 1299 + "modifiers", // 1300 + "modulate", // 1301 + "mono", // 1302 + "month", // 1303 + "months", // 1304 + "motion-path", // 1305 + "mouse-as-pen", // 1306 + "mouse-visible", // 1307 + "move", // 1308 + "move-from-bottom", // 1309 + "move-from-left", // 1310 + "move-from-lowerleft", // 1311 + "move-from-lowerright", // 1312 + "move-from-right", // 1313 + "move-from-top", // 1314 + "move-from-upperleft", // 1315 + "move-from-upperright", // 1316 + "move-short", // 1317 + "movement", // 1318 + "movement-cut-off", // 1319 + "moving-average", // 1320 + "multi-deletion-spanned", // 1321 + "multi-line", // 1322 + "multiple", // 1323 + "name", // 1324 + "name-and-extension", // 1325 + "named", // 1326 + "named-expression", // 1327 + "named-expressions", // 1328 + "named-range", // 1329 + "named-symbol", // 1330 + "nav-order", // 1331 + "navigation-mode", // 1332 + "near-axis", // 1333 + "near-axis-other-side", // 1334 + "near-origin", // 1335 + "never", // 1336 + "new", // 1337 + "next", // 1338 + "next-page", // 1339 + "next-style-name", // 1340 + "no-action", // 1341 + "no-limit", // 1342 + "no-nulls", // 1343 + "no-repeat", // 1344 + "no-wrap", // 1345 + "node-type", // 1346 + "nohref", // 1347 + "non-primitive", // 1348 + "non-whitespace-character-count", // 1349 + "none", // 1350 + "nonzero", // 1351 + "normal", // 1352 + "normals-direction", // 1353 + "normals-kind", // 1354 + "note", // 1355 + "note-body", // 1356 + "note-citation", // 1357 + "note-class", // 1358 + "note-continuation-notice-backward", // 1359 + "note-continuation-notice-forward", // 1360 + "note-ref", // 1361 + "notes", // 1362 + "notes-configuration", // 1363 + "nothing", // 1364 + "notify-on-update-of-ranges", // 1365 + "null-date", // 1366 + "null-year", // 1367 + "nullable", // 1368 + "num-format", // 1369 + "num-letter-sync", // 1370 + "num-prefix", // 1371 + "num-suffix", // 1372 + "number", // 1373 + "number-all-superior", // 1374 + "number-and-name", // 1375 + "number-columns-repeated", // 1376 + "number-columns-spanned", // 1377 + "number-lines", // 1378 + "number-matrix-columns-spanned", // 1379 + "number-matrix-rows-spanned", // 1380 + "number-no-superior", // 1381 + "number-position", // 1382 + "number-rows-repeated", // 1383 + "number-rows-spanned", // 1384 + "number-style", // 1385 + "number-wrapped-paragraphs", // 1386 + "numbered-entries", // 1387 + "numbered-paragraph", // 1388 + "numeric", // 1389 + "object", // 1390 + "object-count", // 1391 + "object-index", // 1392 + "object-index-entry-template", // 1393 + "object-index-source", // 1394 + "object-name", // 1395 + "object-ole", // 1396 + "objectBoundingBox", // 1397 + "objects", // 1398 + "oblique", // 1399 + "odd-columns", // 1400 + "odd-rows", // 1401 + "office", // 1402 + "offset", // 1403 + "ole-action", // 1404 + "ole-draw-aspect", // 1405 + "ole-object-count", // 1406 + "on-click", // 1407 + "on-update-keep-size", // 1408 + "on-update-keep-styles", // 1409 + "onLoad", // 1410 + "onRequest", // 1411 + "once-concurrent", // 1412 + "once-successive", // 1413 + "opacity", // 1414 + "opacity-name", // 1415 + "open", // 1416 + "open-horizontal", // 1417 + "open-vertical", // 1418 + "operation", // 1419 + "operator", // 1420 + "option", // 1421 + "order", // 1422 + "order-statement", // 1423 + "organizations", // 1424 + "orgchart", // 1425 + "orientation", // 1426 + "origin", // 1427 + "orphans", // 1428 + "other", // 1429 + "out", // 1430 + "outer", // 1431 + "outline", // 1432 + "outline-level", // 1433 + "outline-level-style", // 1434 + "outline-style", // 1435 + "outline-subtotals-bottom", // 1436 + "outline-subtotals-top", // 1437 + "outside", // 1438 + "outside-end", // 1439 + "outside-start", // 1440 + "overflow-behavior", // 1441 + "overlap", // 1442 + "overline-position", // 1443 + "overline-thickness", // 1444 + "p", // 1445 + "paced", // 1446 + "pad", // 1447 + "padding", // 1448 + "padding-bottom", // 1449 + "padding-left", // 1450 + "padding-right", // 1451 + "padding-top", // 1452 + "page", // 1453 + "page-adjust", // 1454 + "page-breaks-on-group-change", // 1455 + "page-content", // 1456 + "page-continuation", // 1457 + "page-count", // 1458 + "page-end-margin", // 1459 + "page-height", // 1460 + "page-layout", // 1461 + "page-layout-name", // 1462 + "page-layout-properties", // 1463 + "page-number", // 1464 + "page-sequence", // 1465 + "page-start-margin", // 1466 + "page-step-size", // 1467 + "page-thumbnail", // 1468 + "page-usage", // 1469 + "page-variable-get", // 1470 + "page-variable-set", // 1471 + "page-width", // 1472 + "pages", // 1473 + "panose-1", // 1474 + "paper-tray-name", // 1475 + "par", // 1476 + "paragraph", // 1477 + "paragraph-content", // 1478 + "paragraph-count", // 1479 + "paragraph-end-margin", // 1480 + "paragraph-properties", // 1481 + "paragraph-start-margin", // 1482 + "paragraph-style-name", // 1483 + "parallel", // 1484 + "param", // 1485 + "parameter-name-substitution", // 1486 + "parent", // 1487 + "parent-style-name", // 1488 + "parse-sql-statement", // 1489 + "password", // 1490 + "path", // 1491 + "path-id", // 1492 + "path-stretchpoint-x", // 1493 + "path-stretchpoint-y", // 1494 + "pause", // 1495 + "pc", // 1496 + "pending", // 1497 + "percentage", // 1498 + "percentage-data-style-name", // 1499 + "percentage-style", // 1500 + "perspective", // 1501 + "phdthesis", // 1502 + "phong", // 1503 + "pie-offset", // 1504 + "placeholder", // 1505 + "placeholder-type", // 1506 + "placing", // 1507 + "plain-number", // 1508 + "plain-number-and-name", // 1509 + "play", // 1510 + "play-full", // 1511 + "plot-area", // 1512 + "plugin", // 1513 + "plus", // 1514 + "points", // 1515 + "polygon", // 1516 + "polyline", // 1517 + "polynomial", // 1518 + "port", // 1519 + "portrait", // 1520 + "position", // 1521 + "possessive-form", // 1522 + "post", // 1523 + "power", // 1524 + "precision", // 1525 + "precision-as-shown", // 1526 + "prefix", // 1527 + "presentation", // 1528 + "presentation-page-layout", // 1529 + "presentation-page-layout-name", // 1530 + "preset-class", // 1531 + "preset-id", // 1532 + "preset-sub-type", // 1533 + "previous", // 1534 + "previous-page", // 1535 + "primary", // 1536 + "print", // 1537 + "print-content", // 1538 + "print-date", // 1539 + "print-orientation", // 1540 + "print-page-order", // 1541 + "print-range", // 1542 + "print-ranges", // 1543 + "print-time", // 1544 + "print-view", // 1545 + "printable", // 1546 + "printed-by", // 1547 + "printer", // 1548 + "prior", // 1549 + "proceedings", // 1550 + "product", // 1551 + "projection", // 1552 + "properties", // 1553 + "property", // 1554 + "property-name", // 1555 + "protect", // 1556 + "protected", // 1557 + "protection-key", // 1558 + "protection-key-digest-algorithm", // 1559 + "pt", // 1560 + "publisher", // 1561 + "punctuation-wrap", // 1562 + "push", // 1563 + "pyramid", // 1564 + "quarter", // 1565 + "quarters", // 1566 + "queries", // 1567 + "query", // 1568 + "query-collection", // 1569 + "query-name", // 1570 + "r", // 1571 + "radial", // 1572 + "radialGradient", // 1573 + "radio", // 1574 + "random", // 1575 + "range-usable-as", // 1576 + "readonly", // 1577 + "real", // 1578 + "records", // 1579 + "recreate-on-edit", // 1580 + "rect", // 1581 + "rectangle", // 1582 + "rectangular", // 1583 + "red", // 1584 + "ref", // 1585 + "ref-name", // 1586 + "reference-format", // 1587 + "reference-mark", // 1588 + "reference-mark-end", // 1589 + "reference-mark-start", // 1590 + "referenced-table-name", // 1591 + "reflect", // 1592 + "refresh-delay", // 1593 + "region-center", // 1594 + "region-left", // 1595 + "region-right", // 1596 + "register-true", // 1597 + "register-truth-ref-style-name", // 1598 + "regression-curve", // 1599 + "regression-force-intercept", // 1600 + "regression-intercept-value", // 1601 + "regression-max-degree", // 1602 + "regression-moving-type", // 1603 + "regression-name", // 1604 + "regression-period", // 1605 + "regression-type", // 1606 + "regular-polygon", // 1607 + "rejected", // 1608 + "rejecting-change-id", // 1609 + "rel-column-width", // 1610 + "rel-height", // 1611 + "rel-width", // 1612 + "related-column-name", // 1613 + "relative-tab-stop-position", // 1614 + "remove", // 1615 + "remove-dependents", // 1616 + "remove-precedents", // 1617 + "repeat", // 1618 + "repeat-column", // 1619 + "repeat-content", // 1620 + "repeat-row", // 1621 + "repeatCount", // 1622 + "repeatDur", // 1623 + "repeated", // 1624 + "replace", // 1625 + "report-type", // 1626 + "reports", // 1627 + "reset", // 1628 + "restart", // 1629 + "restart-numbering", // 1630 + "restart-on-page", // 1631 + "restartDefault", // 1632 + "restrict", // 1633 + "reverse", // 1634 + "reverse-direction", // 1635 + "rfc-language-tag", // 1636 + "rfc-language-tag-asian", // 1637 + "rfc-language-tag-complex", // 1638 + "rgb", // 1639 + "right", // 1640 + "right-angled-axes", // 1641 + "right-outside", // 1642 + "rl", // 1643 + "rl-tb", // 1644 + "roll-from-bottom", // 1645 + "roll-from-left", // 1646 + "roll-from-right", // 1647 + "roll-from-top", // 1648 + "roman", // 1649 + "rotate", // 1650 + "rotation", // 1651 + "rotation-align", // 1652 + "rotation-angle", // 1653 + "round", // 1654 + "row", // 1655 + "row-count", // 1656 + "row-height", // 1657 + "row-mapping", // 1658 + "row-number", // 1659 + "row-percentage", // 1660 + "row-retrieving-statement", // 1661 + "rows", // 1662 + "ruby", // 1663 + "ruby-align", // 1664 + "ruby-base", // 1665 + "ruby-position", // 1666 + "ruby-properties", // 1667 + "ruby-text", // 1668 + "run-through", // 1669 + "running-total", // 1670 + "rx", // 1671 + "ry", // 1672 + "s", // 1673 + "scale", // 1674 + "scale-min", // 1675 + "scale-text", // 1676 + "scale-to", // 1677 + "scale-to-X", // 1678 + "scale-to-Y", // 1679 + "scale-to-pages", // 1680 + "scenario", // 1681 + "scenario-ranges", // 1682 + "scene", // 1683 + "schema-definition", // 1684 + "schema-name", // 1685 + "school", // 1686 + "scientific-number", // 1687 + "screen", // 1688 + "script", // 1689 + "script-asian", // 1690 + "script-complex", // 1691 + "script-type", // 1692 + "scripts", // 1693 + "scroll", // 1694 + "search-criteria-must-apply-to-whole-cell", // 1695 + "secondary-fill-color", // 1696 + "seconds", // 1697 + "section", // 1698 + "section-name", // 1699 + "section-properties", // 1700 + "section-source", // 1701 + "segments", // 1702 + "select-page", // 1703 + "selected", // 1704 + "selected-page", // 1705 + "selection", // 1706 + "selection-indices", // 1707 + "self", // 1708 + "semi-automatic", // 1709 + "semi-condensed", // 1710 + "semi-expanded", // 1711 + "sender-city", // 1712 + "sender-company", // 1713 + "sender-country", // 1714 + "sender-email", // 1715 + "sender-fax", // 1716 + "sender-firstname", // 1717 + "sender-initials", // 1718 + "sender-lastname", // 1719 + "sender-phone-private", // 1720 + "sender-phone-work", // 1721 + "sender-position", // 1722 + "sender-postal-code", // 1723 + "sender-state-or-province", // 1724 + "sender-street", // 1725 + "sender-title", // 1726 + "sentence-count", // 1727 + "separating", // 1728 + "separation-character", // 1729 + "separator", // 1730 + "seq", // 1731 + "sequence", // 1732 + "sequence-decl", // 1733 + "sequence-decls", // 1734 + "sequence-ref", // 1735 + "series", // 1736 + "series-source", // 1737 + "server-database", // 1738 + "server-map", // 1739 + "set", // 1740 + "set-default", // 1741 + "set-null", // 1742 + "settings", // 1743 + "shade-mode", // 1744 + "shadow", // 1745 + "shadow-color", // 1746 + "shadow-offset-x", // 1747 + "shadow-offset-y", // 1748 + "shadow-opacity", // 1749 + "shadow-slant", // 1750 + "shape", // 1751 + "shape-id", // 1752 + "shapes", // 1753 + "sharpness", // 1754 + "sheet-name", // 1755 + "shininess", // 1756 + "short", // 1757 + "show", // 1758 + "show-deleted", // 1759 + "show-details", // 1760 + "show-empty", // 1761 + "show-end-of-presentation-slide", // 1762 + "show-filter-button", // 1763 + "show-logo", // 1764 + "show-shape", // 1765 + "show-text", // 1766 + "show-unit", // 1767 + "shrink-to-fit", // 1768 + "side-by-side", // 1769 + "simple", // 1770 + "single", // 1771 + "size", // 1772 + "skewX", // 1773 + "skewY", // 1774 + "skip-white-space", // 1775 + "slide", // 1776 + "slope", // 1777 + "slow", // 1778 + "small-caps", // 1779 + "smallint", // 1780 + "smil", // 1781 + "snap-to-layout-grid", // 1782 + "soft-page-break", // 1783 + "solid", // 1784 + "solid-type", // 1785 + "sort", // 1786 + "sort-algorithm", // 1787 + "sort-ascending", // 1788 + "sort-by", // 1789 + "sort-by-position", // 1790 + "sort-by-x-values", // 1791 + "sort-groups", // 1792 + "sort-key", // 1793 + "sort-mode", // 1794 + "sound", // 1795 + "source", // 1796 + "source-cell-range", // 1797 + "source-cell-range-addresses", // 1798 + "source-field-name", // 1799 + "source-name", // 1800 + "source-range-address", // 1801 + "source-service", // 1802 + "space", // 1803 + "space-after", // 1804 + "space-before", // 1805 + "span", // 1806 + "specular", // 1807 + "specular-color", // 1808 + "speed", // 1809 + "sphere", // 1810 + "spin-button", // 1811 + "spiral-inward-left", // 1812 + "spiral-inward-right", // 1813 + "spiral-outward-left", // 1814 + "spiral-outward-right", // 1815 + "spiralin-left", // 1816 + "spiralin-right", // 1817 + "spiralout-left", // 1818 + "spiralout-right", // 1819 + "spline", // 1820 + "spline-order", // 1821 + "spline-resolution", // 1822 + "spreadMethod", // 1823 + "spreadsheet", // 1824 + "sql", // 1825 + "sql-pass-through", // 1826 + "sql-statement", // 1827 + "sqlnull", // 1828 + "square", // 1829 + "stacked", // 1830 + "stagger-even", // 1831 + "stagger-odd", // 1832 + "standard", // 1833 + "standard-deviation", // 1834 + "standard-error", // 1835 + "star", // 1836 + "start", // 1837 + "start-angle", // 1838 + "start-color", // 1839 + "start-column", // 1840 + "start-glue-point", // 1841 + "start-guide", // 1842 + "start-indent", // 1843 + "start-intensity", // 1844 + "start-line-spacing-horizontal", // 1845 + "start-line-spacing-vertical", // 1846 + "start-numbering-at", // 1847 + "start-page", // 1848 + "start-position", // 1849 + "start-row", // 1850 + "start-scale", // 1851 + "start-shape", // 1852 + "start-table", // 1853 + "start-value", // 1854 + "start-with-navigator", // 1855 + "state", // 1856 + "status", // 1857 + "stay-on-top", // 1858 + "stdev", // 1859 + "stdevp", // 1860 + "stemh", // 1861 + "stemv", // 1862 + "step", // 1863 + "step-center-x", // 1864 + "step-center-y", // 1865 + "step-end", // 1866 + "step-size", // 1867 + "step-start", // 1868 + "steps", // 1869 + "stock-gain-marker", // 1870 + "stock-loss-marker", // 1871 + "stock-range-line", // 1872 + "stop", // 1873 + "stop-color", // 1874 + "stop-opacity", // 1875 + "straight-line", // 1876 + "stretch", // 1877 + "stretch-from-bottom", // 1878 + "stretch-from-left", // 1879 + "stretch-from-right", // 1880 + "stretch-from-top", // 1881 + "strict", // 1882 + "strikethrough-position", // 1883 + "strikethrough-thickness", // 1884 + "string", // 1885 + "string-value", // 1886 + "string-value-if-false", // 1887 + "string-value-if-true", // 1888 + "string-value-phonetic", // 1889 + "stripes", // 1890 + "stroke", // 1891 + "stroke-color", // 1892 + "stroke-dash", // 1893 + "stroke-dash-names", // 1894 + "stroke-linecap", // 1895 + "stroke-linejoin", // 1896 + "stroke-opacity", // 1897 + "stroke-width", // 1898 + "struct", // 1899 + "structure-protected", // 1900 + "style", // 1901 + "style-name", // 1902 + "style-override", // 1903 + "styles", // 1904 + "sub", // 1905 + "sub-item", // 1906 + "subject", // 1907 + "submit", // 1908 + "subtitle", // 1909 + "subtotal-field", // 1910 + "subtotal-rule", // 1911 + "subtotal-rules", // 1912 + "subtype", // 1913 + "suffix", // 1914 + "sum", // 1915 + "super", // 1916 + "suppress-version-columns", // 1917 + "svg", // 1918 + "swiss", // 1919 + "syllable-count", // 1920 + "symbol-color", // 1921 + "symbol-height", // 1922 + "symbol-image", // 1923 + "symbol-name", // 1924 + "symbol-type", // 1925 + "symbol-width", // 1926 + "system", // 1927 + "system-driver-settings", // 1928 + "tab", // 1929 + "tab-color", // 1930 + "tab-cycle", // 1931 + "tab-index", // 1932 + "tab-ref", // 1933 + "tab-stop", // 1934 + "tab-stop-distance", // 1935 + "tab-stops", // 1936 + "table", // 1937 + "table-background", // 1938 + "table-cell", // 1939 + "table-cell-properties", // 1940 + "table-centering", // 1941 + "table-column", // 1942 + "table-column-group", // 1943 + "table-column-properties", // 1944 + "table-columns", // 1945 + "table-count", // 1946 + "table-definition", // 1947 + "table-definitions", // 1948 + "table-exclude-filter", // 1949 + "table-fields", // 1950 + "table-filter", // 1951 + "table-filter-pattern", // 1952 + "table-formula", // 1953 + "table-header-columns", // 1954 + "table-header-rows", // 1955 + "table-include-filter", // 1956 + "table-index", // 1957 + "table-index-entry-template", // 1958 + "table-index-source", // 1959 + "table-name", // 1960 + "table-of-content", // 1961 + "table-of-content-entry-template", // 1962 + "table-of-content-source", // 1963 + "table-properties", // 1964 + "table-representation", // 1965 + "table-representations", // 1966 + "table-row", // 1967 + "table-row-group", // 1968 + "table-row-properties", // 1969 + "table-rows", // 1970 + "table-setting", // 1971 + "table-settings", // 1972 + "table-source", // 1973 + "table-template", // 1974 + "table-type", // 1975 + "table-type-filter", // 1976 + "tabular-layout", // 1977 + "target-cell-address", // 1978 + "target-frame", // 1979 + "target-frame-name", // 1980 + "target-range-address", // 1981 + "targetElement", // 1982 + "tb", // 1983 + "tb-lr", // 1984 + "tb-rl", // 1985 + "techreport", // 1986 + "template", // 1987 + "template-name", // 1988 + "text", // 1989 + "text-align", // 1990 + "text-align-last", // 1991 + "text-align-source", // 1992 + "text-areas", // 1993 + "text-autospace", // 1994 + "text-blinking", // 1995 + "text-box", // 1996 + "text-combine", // 1997 + "text-combine-end-char", // 1998 + "text-combine-start-char", // 1999 + "text-content", // 2000 + "text-emphasize", // 2001 + "text-indent", // 2002 + "text-input", // 2003 + "text-line-through-color", // 2004 + "text-line-through-mode", // 2005 + "text-line-through-style", // 2006 + "text-line-through-text", // 2007 + "text-line-through-text-style", // 2008 + "text-line-through-type", // 2009 + "text-line-through-width", // 2010 + "text-outline", // 2011 + "text-overlap", // 2012 + "text-overline-color", // 2013 + "text-overline-mode", // 2014 + "text-overline-style", // 2015 + "text-overline-type", // 2016 + "text-overline-width", // 2017 + "text-path", // 2018 + "text-path-allowed", // 2019 + "text-path-mode", // 2020 + "text-path-same-letter-heights", // 2021 + "text-path-scale", // 2022 + "text-position", // 2023 + "text-properties", // 2024 + "text-rotate-angle", // 2025 + "text-rotation-angle", // 2026 + "text-rotation-scale", // 2027 + "text-scale", // 2028 + "text-shadow", // 2029 + "text-style", // 2030 + "text-style-name", // 2031 + "text-transform", // 2032 + "text-underline-color", // 2033 + "text-underline-mode", // 2034 + "text-underline-style", // 2035 + "text-underline-type", // 2036 + "text-underline-width", // 2037 + "textarea", // 2038 + "textarea-horizontal-align", // 2039 + "textarea-vertical-align", // 2040 + "textual", // 2041 + "texture-filter", // 2042 + "texture-generation-mode-x", // 2043 + "texture-generation-mode-y", // 2044 + "texture-kind", // 2045 + "texture-mode", // 2046 + "thick", // 2047 + "thin", // 2048 + "thousand", // 2049 + "three-dimensional", // 2050 + "thumbnail", // 2051 + "tick-mark-position", // 2052 + "tick-marks-major-inner", // 2053 + "tick-marks-major-outer", // 2054 + "tick-marks-minor-inner", // 2055 + "tick-marks-minor-outer", // 2056 + "tile-repeat-offset", // 2057 + "time", // 2058 + "time-adjust", // 2059 + "time-style", // 2060 + "time-value", // 2061 + "timestmp", // 2062 + "timing-root", // 2063 + "tinyint", // 2064 + "title", // 2065 + "to", // 2066 + "to-another-table", // 2067 + "to-bottom", // 2068 + "to-center", // 2069 + "to-left", // 2070 + "to-lower-left", // 2071 + "to-lower-right", // 2072 + "to-right", // 2073 + "to-top", // 2074 + "to-upper-left", // 2075 + "to-upper-right", // 2076 + "toc-mark", // 2077 + "toc-mark-end", // 2078 + "toc-mark-start", // 2079 + "toggle", // 2080 + "top", // 2081 + "top-end", // 2082 + "top-left", // 2083 + "top-right", // 2084 + "top-start", // 2085 + "total-percentage", // 2086 + "trace-dependents", // 2087 + "trace-errors", // 2088 + "trace-precedents", // 2089 + "track-changes", // 2090 + "tracked-changes", // 2091 + "transform", // 2092 + "transformation", // 2093 + "transition", // 2094 + "transition-on-click", // 2095 + "transition-speed", // 2096 + "transition-style", // 2097 + "transition-type", // 2098 + "transitionFilter", // 2099 + "translate", // 2100 + "transliteration-country", // 2101 + "transliteration-format", // 2102 + "transliteration-language", // 2103 + "transliteration-style", // 2104 + "transparent", // 2105 + "treat-empty-cells", // 2106 + "triple", // 2107 + "true", // 2108 + "truncate-on-overflow", // 2109 + "ttb", // 2110 + "type", // 2111 + "type-name", // 2112 + "ultra-condensed", // 2113 + "ultra-expanded", // 2114 + "unchecked", // 2115 + "uncover-to-bottom", // 2116 + "uncover-to-left", // 2117 + "uncover-to-lowerleft", // 2118 + "uncover-to-lowerright", // 2119 + "uncover-to-right", // 2120 + "uncover-to-top", // 2121 + "uncover-to-upperleft", // 2122 + "uncover-to-upperright", // 2123 + "underline-position", // 2124 + "underline-thickness", // 2125 + "unicode-range", // 2126 + "unique", // 2127 + "unit", // 2128 + "units-per-em", // 2129 + "unknown", // 2130 + "unpublished", // 2131 + "unsorted", // 2132 + "up", // 2133 + "update-rule", // 2134 + "update-table", // 2135 + "uppercase", // 2136 + "url", // 2137 + "use-banding-columns-styles", // 2138 + "use-banding-rows-styles", // 2139 + "use-caption", // 2140 + "use-catalog", // 2141 + "use-chart-objects", // 2142 + "use-date-time-name", // 2143 + "use-draw-objects", // 2144 + "use-first-column-styles", // 2145 + "use-first-row-styles", // 2146 + "use-floating-frames", // 2147 + "use-footer-name", // 2148 + "use-graphics", // 2149 + "use-header-name", // 2150 + "use-index-marks", // 2151 + "use-index-source-styles", // 2152 + "use-keys-as-entries", // 2153 + "use-labels", // 2154 + "use-last-column-styles", // 2155 + "use-last-row-styles", // 2156 + "use-math-objects", // 2157 + "use-objects", // 2158 + "use-optimal-column-width", // 2159 + "use-optimal-row-height", // 2160 + "use-other-objects", // 2161 + "use-outline-level", // 2162 + "use-regular-expressions", // 2163 + "use-soft-page-breaks", // 2164 + "use-spreadsheet-objects", // 2165 + "use-system-user", // 2166 + "use-tables", // 2167 + "use-wildcards", // 2168 + "use-window-font-color", // 2169 + "use-zero", // 2170 + "used-hierarchy", // 2171 + "user-defined", // 2172 + "user-field-decl", // 2173 + "user-field-decls", // 2174 + "user-field-get", // 2175 + "user-field-input", // 2176 + "user-index", // 2177 + "user-index-entry-template", // 2178 + "user-index-mark", // 2179 + "user-index-mark-end", // 2180 + "user-index-mark-start", // 2181 + "user-index-source", // 2182 + "user-name", // 2183 + "user-transformed", // 2184 + "v-alphabetic", // 2185 + "v-hanging", // 2186 + "v-ideographic", // 2187 + "v-mathematical", // 2188 + "validation", // 2189 + "value", // 2190 + "value-and-percentage", // 2191 + "value-list", // 2192 + "value-range", // 2193 + "value-type", // 2194 + "values", // 2195 + "values-cell-range-address", // 2196 + "var", // 2197 + "varbinary", // 2198 + "varchar", // 2199 + "variable", // 2200 + "variable-decl", // 2201 + "variable-decls", // 2202 + "variable-get", // 2203 + "variable-input", // 2204 + "variable-set", // 2205 + "variance", // 2206 + "varp", // 2207 + "verb", // 2208 + "version", // 2209 + "vertical", // 2210 + "vertical-align", // 2211 + "vertical-bar", // 2212 + "vertical-checkerboard", // 2213 + "vertical-lines", // 2214 + "vertical-pos", // 2215 + "vertical-rel", // 2216 + "vertical-segments", // 2217 + "vertical-stripes", // 2218 + "viewBox", // 2219 + "visibility", // 2220 + "visible", // 2221 + "visible-area-height", // 2222 + "visible-area-left", // 2223 + "visible-area-top", // 2224 + "visible-area-width", // 2225 + "visited-style-name", // 2226 + "visual-effect", // 2227 + "void", // 2228 + "volatile", // 2229 + "volume", // 2230 + "vpn", // 2231 + "vrp", // 2232 + "vup", // 2233 + "wall", // 2234 + "warning", // 2235 + "watermark", // 2236 + "wave", // 2237 + "wavyline", // 2238 + "wavyline-from-bottom", // 2239 + "wavyline-from-left", // 2240 + "wavyline-from-right", // 2241 + "wavyline-from-top", // 2242 + "week-of-year", // 2243 + "whenNotActive", // 2244 + "wide", // 2245 + "widows", // 2246 + "width", // 2247 + "widths", // 2248 + "with-previous", // 2249 + "word", // 2250 + "word-count", // 2251 + "wrap", // 2252 + "wrap-contour", // 2253 + "wrap-contour-mode", // 2254 + "wrap-dynamic-threshold", // 2255 + "wrap-influence-on-position", // 2256 + "wrap-option", // 2257 + "writing-mode", // 2258 + "writing-mode-automatic", // 2259 + "www", // 2260 + "x", // 2261 + "x-height", // 2262 + "x1", // 2263 + "x2", // 2264 + "xforms", // 2265 + "xforms-list-source", // 2266 + "xforms-submission", // 2267 + "xhtml", // 2268 + "xlink", // 2269 + "xml", // 2270 + "y", // 2271 + "y1", // 2272 + "y2", // 2273 + "year", // 2274 + "years", // 2275 + "z", // 2276 + "z-index", // 2277 + "zero-values" // 2278 +}; + +size_t token_name_count = 2279;
\ No newline at end of file diff --git a/src/liborcus/ods_content_xml_context.cpp b/src/liborcus/ods_content_xml_context.cpp new file mode 100644 index 0000000..5f07594 --- /dev/null +++ b/src/liborcus/ods_content_xml_context.cpp @@ -0,0 +1,900 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ods_content_xml_context.hpp" +#include "odf_token_constants.hpp" +#include "odf_namespace_types.hpp" +#include "session_context.hpp" +#include "ods_session_data.hpp" +#include "impl_utils.hpp" + +#include <orcus/spreadsheet/import_interface.hpp> +#include <orcus/spreadsheet/import_interface_styles.hpp> + +#include <iostream> +#include <fstream> +#include <algorithm> +#include <cstring> + +#include <mdds/sorted_string_map.hpp> + +using namespace std; +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace { + +namespace cell_value { + +using map_type = mdds::sorted_string_map<ods_content_xml_context::cell_value_type, mdds::string_view_map_entry>; + +// Keys must be sorted. +map_type::entry entries[] = { + { "date", ods_content_xml_context::vt_date }, + { "float", ods_content_xml_context::vt_float }, + { "string", ods_content_xml_context::vt_string } +}; + +const map_type& get() +{ + static map_type cv_map( + entries, std::size(entries), ods_content_xml_context::vt_unknown); + + return cv_map; +} + +} // namespace cell_value + +void pick_up_named_range_or_expression( + session_context& cxt, const xml_token_attrs_t& attrs, xmlns_id_t exp_attr_ns, xml_token_t exp_attr_name, + ods_session_data::named_exp_type name_type, ss::sheet_t scope) +{ + std::string_view name; + std::string_view expression; + std::string_view base; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns == exp_attr_ns && attr.name == exp_attr_name) + { + expression = cxt.intern(attr); + continue; + } + + switch (attr.name) + { + case XML_name: + name = cxt.intern(attr); + break; + case XML_base_cell_address: + base = cxt.intern(attr); + break; + } + } + + auto& ods_data = cxt.get_data<ods_session_data>(); + + if (!name.empty() && !expression.empty() && !base.empty()) + ods_data.named_exps.emplace_back(name, expression, base, name_type, scope); +} + +} // anonymous namespace + +// ============================================================================ + +ods_content_xml_context::sheet_data::sheet_data() : + sheet(nullptr), index(-1) {} + +void ods_content_xml_context::sheet_data::reset() +{ + sheet = nullptr; + index = -1; +} + +ods_content_xml_context::row_attr::row_attr() : + number_rows_repeated(1) +{ +} + +ods_content_xml_context::cell_attr::cell_attr() : + number_columns_repeated(1), + type(vt_unknown), + value(0.0), + formula_grammar(spreadsheet::formula_grammar_t::ods) +{ +} + +// ============================================================================ + +ods_content_xml_context::ods_content_xml_context(session_context& session_cxt, const tokens& tokens, spreadsheet::iface::import_factory* factory) : + xml_context_base(session_cxt, tokens), + mp_factory(factory), + m_row(0), m_col(0), m_col_repeated(0), + m_para_index(0), + m_has_content(false), + m_styles(), + m_child_styles(session_cxt, tokens, mp_factory->get_styles()), + m_child_para(session_cxt, tokens, factory->get_shared_strings(), m_styles), + m_child_dde_links(session_cxt, tokens) +{ + register_child(&m_child_styles); + register_child(&m_child_para); + register_child(&m_child_dde_links); + + spreadsheet::iface::import_global_settings* gs = mp_factory->get_global_settings(); + if (gs) + { + // Set the default null date to 1899-12-30 per specification (19.614). + gs->set_origin_date(1899, 12, 30); + } +} + +ods_content_xml_context::~ods_content_xml_context() = default; + +xml_context_base* ods_content_xml_context::create_child_context(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_odf_text && name == XML_p) + { + m_child_para.reset(); + return &m_child_para; + } + + if (ns == NS_odf_office && name == XML_automatic_styles) + { + m_child_styles.reset(); + return &m_child_styles; + } + + if (ns == NS_odf_table && name == XML_dde_links) + { + m_child_dde_links.reset(); + return &m_child_dde_links; + } + + return nullptr; +} + +void ods_content_xml_context::end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) +{ + if (ns == NS_odf_text && name == XML_p) + { + text_para_context* para_context = static_cast<text_para_context*>(child); + m_has_content = !para_context->empty(); + m_para_index = para_context->get_string_index(); + } + else if (ns == NS_odf_office && name == XML_automatic_styles) + { + auto new_styles = m_child_styles.pop_styles(); + merge(m_styles, new_styles); + assert(new_styles.empty()); + + if (get_config().debug) + dump_state(m_styles, std::cout); + + spreadsheet::iface::import_styles* xstyles = mp_factory->get_styles(); + if (xstyles) + { + for (const auto& [style_name, style_value] : m_styles) + { + if (style_value->family == style_family_table_cell) + { + // TODO: Actually we need a boolean flag to see if it is an automatic style or a real style + // currently we have no way to set a real style to a cell anyway + const auto& cell = std::get<odf_style::cell>(style_value->data); + m_cell_format_map.insert(name2id_type::value_type(style_name, cell.xf)); + } + } + } + } +} + +void ods_content_xml_context::start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + + if (ns == NS_odf_office) + { + switch (name) + { + case XML_body: + break; + case XML_spreadsheet: + break; + default: + warn_unhandled(); + } + } + else if (ns == NS_odf_table) + { + switch (name) + { + case XML_calculation_settings: + break; + case XML_null_date: + xml_element_expected(parent, NS_odf_table, XML_calculation_settings); + start_null_date(attrs); + break; + case XML_table: + start_table(parent, attrs); + break; + case XML_table_column: + { + static const xml_elem_set_t expected = { + { NS_odf_table, XML_table }, + { NS_odf_table, XML_table_column_group }, + { NS_odf_table, XML_table_columns }, + { NS_odf_table, XML_table_header_columns } + }; + xml_element_expected(parent, expected); + start_column(attrs); + break; + } + case XML_table_row: + { + static const xml_elem_set_t expected = { + { NS_odf_table, XML_table }, + { NS_odf_table, XML_table_header_rows }, + { NS_odf_table, XML_table_row_group }, + }; + xml_element_expected(parent, expected); + start_row(attrs); + break; + } + case XML_table_cell: + xml_element_expected(parent, NS_odf_table, XML_table_row); + start_cell(attrs); + break; + case XML_dde_links: + xml_element_expected(parent, NS_odf_office, XML_spreadsheet); + break; + case XML_dde_link: + xml_element_expected(parent, NS_odf_table, XML_dde_links); + break; + case XML_named_expressions: + { + static const xml_elem_set_t expected = { + { NS_odf_office, XML_spreadsheet }, + { NS_odf_table, XML_table }, + }; + xml_element_expected(parent, expected); + break; + } + case XML_named_range: + start_named_range(parent, attrs); + break; + case XML_named_expression: + start_named_expression(parent, attrs); + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool ods_content_xml_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_odf_office) + { + switch (name) + { + case XML_body: + break; + case XML_spreadsheet: + end_spreadsheet(); + break; + default: + ; + } + } + else if (ns == NS_odf_table) + { + switch (name) + { + case XML_calculation_settings: + break; + case XML_null_date: + break; + case XML_table: + end_table(); + break; + case XML_table_column: + end_column(); + break; + case XML_table_row: + end_row(); + break; + case XML_table_cell: + end_cell(); + break; + case XML_named_range: + end_named_range(); + break; + case XML_named_expression: + end_named_expression(); + break; + default: + ; + } + } + return pop_stack(ns, name); +} + +void ods_content_xml_context::start_null_date(const xml_token_attrs_t& attrs) +{ + spreadsheet::iface::import_global_settings* gs = mp_factory->get_global_settings(); + if (!gs) + // Global settings not available. No point going further. + return; + + std::string_view null_date; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns == NS_odf_table && attr.name == XML_date_value) + null_date = attr.value; + } + + date_time_t val = date_time_t::from_chars(null_date); + + gs->set_origin_date(val.year, val.month, val.day); +} + +void ods_content_xml_context::start_table(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs) +{ + static const xml_elem_set_t expected = { + { NS_odf_office, XML_spreadsheet }, + { NS_odf_table, XML_dde_link }, + }; + xml_element_expected(parent, expected); + + if (parent == xml_token_pair_t(NS_odf_office, XML_spreadsheet)) + { + std::string_view name; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns == NS_odf_table && attr.name == XML_name) + name = attr.value; + } + + m_tables.push_back(mp_factory->append_sheet(m_tables.size(), name)); + m_cur_sheet.sheet = m_tables.back(); + m_cur_sheet.index = m_tables.size() - 1; + + if (get_config().debug) + cout << "start table " << name << endl; + + m_row = m_col = 0; + } + else if (parent == xml_token_pair_t(NS_odf_table, XML_dde_link)) + { + if (get_config().debug) + cout << "start table (DDE link)" << endl; + } +} + +void ods_content_xml_context::end_table() +{ + if (m_cur_sheet.sheet) + { + if (get_config().debug) + cout << "end table" << endl; + + m_cur_sheet.reset(); + } +} + +void ods_content_xml_context::start_named_range(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs) +{ + xml_element_expected(parent, NS_odf_table, XML_named_expressions); + + pick_up_named_range_or_expression( + get_session_context(), attrs, NS_odf_table, XML_cell_range_address, + ods_session_data::ne_range, m_cur_sheet.index); +} + +void ods_content_xml_context::end_named_range() +{ +} + +void ods_content_xml_context::start_named_expression(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs) +{ + xml_element_expected(parent, NS_odf_table, XML_named_expressions); + + pick_up_named_range_or_expression( + get_session_context(), attrs, NS_odf_table, XML_expression, + ods_session_data::ne_expression, m_cur_sheet.index); +} + +void ods_content_xml_context::end_named_expression() +{ +} + +void ods_content_xml_context::start_column(const xml_token_attrs_t& attrs) +{ + if (!m_cur_sheet.sheet) + return; + + spreadsheet::iface::import_sheet_properties* sheet_props = + m_cur_sheet.sheet->get_sheet_properties(); + + if (!sheet_props) + return; + + std::string_view style_name; + std::string_view default_cell_style_name; + m_col_repeated = 1; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns == NS_odf_table) + { + switch (attr.name) + { + case XML_style_name: + style_name = attr.value; + break; + case XML_default_cell_style_name: + default_cell_style_name = intern(attr); + break; + case XML_number_columns_repeated: + m_col_repeated = to_long(attr.value); + break; + } + } + } + + if (auto it = m_styles.find(style_name); it != m_styles.end()) + { + const odf_style& style = *it->second; + + sheet_props->set_column_width( + m_col, m_col_repeated, + std::get<odf_style::column>(style.data).width.value, + std::get<odf_style::column>(style.data).width.unit); + } + + push_default_column_cell_style(default_cell_style_name, m_col_repeated); +} + +void ods_content_xml_context::end_column() +{ + m_col += m_col_repeated; +} + +void ods_content_xml_context::start_row(const xml_token_attrs_t& attrs) +{ + m_col = 0; + m_row_attr = row_attr(); + + std::string_view style_name; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns == NS_odf_table) + { + switch (attr.name) + { + case XML_number_rows_repeated: + m_row_attr.number_rows_repeated = to_long(attr.value); + break; + case XML_style_name: + style_name = attr.value; + break; + } + } + } + + if (get_config().debug) + std::cout << "row: (style='" << style_name << "')" << std::endl; + + if (!m_cur_sheet.sheet) + return; + + // Pass row properties to the interface. + spreadsheet::iface::import_sheet_properties* sheet_props = + m_cur_sheet.sheet->get_sheet_properties(); + + if (sheet_props) + { + if (auto it = m_styles.find(style_name); it != m_styles.end()) + { + const odf_style& style = *it->second; + if (style.family == style_family_table_row) + { + const auto& data = std::get<odf_style::row>(style.data); + if (data.height_set) + sheet_props->set_row_height(m_row, data.height.value, data.height.unit); + } + } + } +} + +void ods_content_xml_context::end_row() +{ + if (m_row_attr.number_rows_repeated > 1) + { + // TODO: repeat this row. + if (get_config().debug) + cout << "TODO: repeat this row " << m_row_attr.number_rows_repeated << " times." << endl; + } + m_row += m_row_attr.number_rows_repeated; +} + +void ods_content_xml_context::start_cell(const xml_token_attrs_t& attrs) +{ + m_cell_attr = cell_attr(); + + /** + * Process the prefixed raw formula string stored as attribute value. + */ + auto process_formula = [](std::string_view str) -> std::string_view + { + if (str.empty()) + return {}; + + // Formula is prefixed with formula type, followed by a ':' + // then the actual formula content. + + // First, detect prefix if any. Only try up to the first 5 characters. + const char* p0 = str.data(); + const char* end = p0 + std::min<size_t>(str.size(), 5); + size_t prefix_size = 0; + for (const char* p = p0; p != end; ++p) + { + if (*p == ':') + { + // Prefix separator found. + prefix_size = p - p0; + break; + } + + if (!is_alpha(*p)) + // Only alphabets are allowed in the prefix space. + break; + } + + std::string_view prefix, formula; + if (prefix_size) + { + prefix = std::string_view(p0, prefix_size); + const char* p = p0; + p += prefix_size + 1; + end = p0 + str.size(); + formula = std::string_view(p, end - p); + } + else + { + // TODO : Handle cases where a formula doesn't have a prefix. + } + + // Formula needs to begin with '='. + if (formula.empty() || formula[0] != '=') + return {}; + + // Remove the '='. + formula = std::string_view(formula.data()+1, formula.size()-1); + + if (prefix == "of") + { + // ODF formula. No action needed. + } + + return formula; + }; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.value.empty()) + continue; + + if (attr.ns == NS_odf_table) + { + switch (attr.name) + { + case XML_style_name: + { + m_cell_attr.style_name = intern(attr); + break; + } + case XML_number_columns_repeated: + m_cell_attr.number_columns_repeated = to_long(attr.value); + break; + case XML_formula: + m_cell_attr.formula = process_formula(attr.value); + m_cell_attr.formula = intern(m_cell_attr.formula); + break; + default: + ; + } + } + + if (attr.ns == NS_odf_office) + { + switch (attr.name) + { + case XML_value: + { + const char* end = attr.value.data() + attr.value.size(); + char* endptr; + double val = strtod(attr.value.data(), &endptr); + if (endptr == end) + m_cell_attr.value = val; + break; + } + case XML_value_type: + m_cell_attr.type = cell_value::get().find(attr.value.data(), attr.value.size()); + break; + case XML_date_value: + m_cell_attr.date_value = attr.value; + break; + default: + ; + } + } + } +} + +void ods_content_xml_context::end_cell() +{ + push_cell_format(); + push_cell_value(); + + ++m_col; + if (m_cell_attr.number_columns_repeated > 1) + { + int col_upper = m_col + m_cell_attr.number_columns_repeated - 2; + for (; m_col <= col_upper; ++m_col) + push_cell_value(); + } + m_has_content = false; +} + +std::optional<std::size_t> ods_content_xml_context::push_named_cell_style(std::string_view style_name) +{ + ss::iface::import_styles* xstyles = mp_factory->get_styles(); + if (!xstyles) + return {}; + + const ods_session_data& ods_data = get_session_context().get_data<ods_session_data>(); + + auto it = ods_data.styles_map.find(style_name); + if (it == ods_data.styles_map.end()) + return {}; + + // found in the named styles store. + const odf_style& style = *it->second; + if (style.family != style_family_table_cell) + // it's a named style but not a cell style + return {}; + + // It references a named style. Create a direct cell (aka automatic) style + // that references this named style, and set that as the cell format since + // we can't reference a named style directly from a cell. + const auto& celldata = std::get<odf_style::cell>(style.data); + + ss::iface::import_xf* xf = xstyles->start_xf(ss::xf_category_t::cell); + ENSURE_INTERFACE(xf, import_xf); + xf->set_style_xf(celldata.xf); + std::size_t xfid = xf->commit(); + m_cell_format_map.insert({style_name, xfid}); + return xfid; +} + +void ods_content_xml_context::push_default_column_cell_style( + std::string_view style_name, ss::col_t span) +{ + if (span < 1) + { + std::ostringstream os; + os << "Column " << m_col << " on sheet " << m_cur_sheet.index << " has an invalid span of " << span; + warn(os.str()); + return; + } + + if (style_name.empty()) + return; + + if (!m_cur_sheet.sheet) + return; + + if (auto it = m_cell_format_map.find(style_name); it != m_cell_format_map.end()) + { + // automatic style already present for this name. + m_cur_sheet.sheet->set_column_format(m_col, span, it->second); + return; + } + + auto xfid = push_named_cell_style(style_name); + if (!xfid) + { + std::ostringstream os; + os << "failed to push a new cell style of name '" << style_name << "' to cache"; + warn(os.str()); + return; + } + + m_cur_sheet.sheet->set_column_format(m_col, span, *xfid); +} + +void ods_content_xml_context::push_cell_format() +{ + if (!m_cur_sheet.sheet) + return; + + if (auto it = m_cell_format_map.find(m_cell_attr.style_name); it != m_cell_format_map.end()) + { + for (ss::col_t col_offset = 0; col_offset < m_cell_attr.number_columns_repeated; ++col_offset) + m_cur_sheet.sheet->set_format(m_row, m_col + col_offset, it->second); + // style key found and direct cell format set. + return; + } + + auto xfid = push_named_cell_style(m_cell_attr.style_name); + if (!xfid) + return; + + for (ss::col_t col_offset = 0; col_offset < m_cell_attr.number_columns_repeated; ++col_offset) + m_cur_sheet.sheet->set_format(m_row, m_col + col_offset, *xfid); +} + +void ods_content_xml_context::push_cell_value() +{ + assert(m_cur_sheet.index >= 0); // this is expected to be called only within a valid sheet scope. + + bool has_formula = !m_cell_attr.formula.empty(); + if (has_formula) + { + // Store formula cell data for later processing. + auto& ods_data = get_session_context().get_data<ods_session_data>(); + ods_data.formulas.emplace_back( + m_cur_sheet.index, m_row, m_col, m_cell_attr.formula_grammar, m_cell_attr.formula); + + ods_session_data::formula& formula_data = ods_data.formulas.back(); + + // Store formula result. + switch (m_cell_attr.type) + { + case vt_float: + { + formula_data.result.type = orcus::ods_session_data::rt_numeric; + formula_data.result.numeric_value = m_cell_attr.value; + break; + } + case vt_string: + // TODO : pass string result here. We need to decide whether + // to pass a string ID or a raw string. + break; + default: + ; + } + return; + } + + if (m_cur_sheet.sheet) + { + switch (m_cell_attr.type) + { + case vt_float: + m_cur_sheet.sheet->set_value(m_row, m_col, m_cell_attr.value); + break; + case vt_string: + if (m_has_content) + m_cur_sheet.sheet->set_string(m_row, m_col, m_para_index); + break; + case vt_date: + { + date_time_t val = date_time_t::from_chars(m_cell_attr.date_value); + m_cur_sheet.sheet->set_date_time( + m_row, m_col, val.year, val.month, val.day, val.hour, val.minute, val.second); + break; + } + default: + ; + } + } +} + +void ods_content_xml_context::end_spreadsheet() +{ + auto& ods_data = get_session_context().get_data<ods_session_data>(); + + ss::iface::import_reference_resolver* resolver = + mp_factory->get_reference_resolver(ss::formula_ref_context_t::named_expression_base); + + if (resolver) + { + for (const ods_session_data::named_exp& data : ods_data.named_exps) + { + if (get_config().debug) + { + cout << "named expression: name='" << data.name + << "'; base='" << data.base + << "'; expression='" << data.expression + << "'; sheet-scope=" << data.scope + << endl; + } + + ss::src_address_t base = resolver->resolve_address(data.base); + + ss::iface::import_named_expression* named_exp = nullptr; + + if (data.scope >= 0) + { + // sheet local scope + assert(data.scope < ss::sheet_t(m_tables.size())); + named_exp = m_tables[data.scope]->get_named_expression(); + } + else + { + // global scope. + named_exp = mp_factory->get_named_expression(); + } + + if (named_exp) + { + named_exp->set_base_position(base); + switch (data.type) + { + case ods_session_data::ne_range: + named_exp->set_named_range(data.name, data.expression); + break; + case ods_session_data::ne_expression: + named_exp->set_named_expression(data.name, data.expression); + break; + default: + ; + } + named_exp->commit(); + } + } + } + + // Push all formula cells. Formula cells needs to be processed after all + // the sheet data have been imported, else 3D reference would fail to + // resolve. + for (ods_session_data::formula& data : ods_data.formulas) + { + if (data.sheet < 0 || static_cast<size_t>(data.sheet) >= m_tables.size()) + // Invalid sheet index. + continue; + + spreadsheet::iface::import_sheet* sheet = m_tables[data.sheet]; + if (sheet) + { + spreadsheet::iface::import_formula* formula = sheet->get_formula(); + if (formula) + { + formula->set_position(data.row, data.column); + formula->set_formula(data.grammar, data.exp); + + switch (data.result.type) + { + case ods_session_data::rt_numeric: + formula->set_result_value(data.result.numeric_value); + break; + case ods_session_data::rt_string: + case ods_session_data::rt_error: + case ods_session_data::rt_none: + default: + ; + } + + formula->commit(); + } + } + } + + // Clear the formula buffer. + ods_data.formulas.clear(); +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ods_content_xml_context.hpp b/src/liborcus/ods_content_xml_context.hpp new file mode 100644 index 0000000..bc50a67 --- /dev/null +++ b/src/liborcus/ods_content_xml_context.hpp @@ -0,0 +1,138 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_ODSCONTEXT_XML_CONTEXT_HPP +#define INCLUDED_ORCUS_ODSCONTEXT_XML_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "odf_para_context.hpp" +#include "ods_dde_links_context.hpp" +#include "odf_styles.hpp" +#include "odf_styles_context.hpp" +#include "orcus/spreadsheet/types.hpp" + +#include <vector> +#include <unordered_map> + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_factory; +class import_sheet; + +}} + +class ods_content_xml_context : public xml_context_base +{ + typedef std::unordered_map<std::string_view, std::size_t> name2id_type; + +public: + struct sheet_data + { + spreadsheet::iface::import_sheet* sheet; + spreadsheet::sheet_t index; + + sheet_data(); + + void reset(); + }; + + struct row_attr + { + long number_rows_repeated; + row_attr(); + }; + + enum cell_value_type { vt_unknown, vt_float, vt_string, vt_date }; + + struct cell_attr + { + long number_columns_repeated; + cell_value_type type; + double value; + std::string_view date_value; + std::string_view style_name; + + std::string_view formula; + spreadsheet::formula_grammar_t formula_grammar; + + cell_attr(); + }; + + ods_content_xml_context(session_context& session_cxt, const tokens& tokens, spreadsheet::iface::import_factory* factory); + virtual ~ods_content_xml_context() override; + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name) override; + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) override; + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) override; + virtual bool end_element(xmlns_id_t ns, xml_token_t name) override; + +private: + void start_null_date(const xml_token_attrs_t& attrs); + + void start_table(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs); + void end_table(); + + void start_named_range(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs); + void end_named_range(); + + void start_named_expression(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs); + void end_named_expression(); + + void start_column(const xml_token_attrs_t& attrs); + void end_column(); + + void start_row(const xml_token_attrs_t& attrs); + void end_row(); + + void start_cell(const xml_token_attrs_t& attrs); + void end_cell(); + + /** + * Push a named cell style as a parent style of an automatic style, as we + * cannot directly reference a named cell style from a cell, column etc. + * + * @param style_name name of the named cell style to push. + * + * @return xfid of the newly-created automatic style that "wraps" the named + * cell as its parent if the call is successful, else it's not set. + */ + std::optional<std::size_t> push_named_cell_style(std::string_view style_name); + void push_default_column_cell_style(std::string_view style_name, spreadsheet::col_t span); + void push_cell_format(); + void push_cell_value(); + + void end_spreadsheet(); + +private: + spreadsheet::iface::import_factory* mp_factory; + std::vector<spreadsheet::iface::import_sheet*> m_tables; + sheet_data m_cur_sheet; + + row_attr m_row_attr; + cell_attr m_cell_attr; /// attributes of current cell. + + int m_row; + int m_col; + int m_col_repeated; + size_t m_para_index; + bool m_has_content; + + odf_styles_map_type m_styles; /// map storing all automatic styles by their names. + name2id_type m_cell_format_map; /// map of automatic style names to cell format (xf) IDs. + + styles_context m_child_styles; + text_para_context m_child_para; + ods_dde_links_context m_child_dde_links; +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ods_dde_links_context.cpp b/src/liborcus/ods_dde_links_context.cpp new file mode 100644 index 0000000..4b644a2 --- /dev/null +++ b/src/liborcus/ods_dde_links_context.cpp @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ods_dde_links_context.hpp" + +namespace orcus { + +ods_dde_links_context::ods_dde_links_context(session_context& session_cxt, const tokens& tokens) : + xml_context_base(session_cxt, tokens) {} + +ods_dde_links_context::~ods_dde_links_context() {} + +xml_context_base* ods_dde_links_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void ods_dde_links_context::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void ods_dde_links_context::start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& /*attrs*/) +{ + xml_token_pair_t parent = push_stack(ns, name); + (void)parent; + + warn_unhandled(); +} + +bool ods_dde_links_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + return pop_stack(ns, name); +} + +void ods_dde_links_context::characters(std::string_view /*str*/, bool /*transient*/) +{ +} + +void ods_dde_links_context::reset() +{ +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ods_dde_links_context.hpp b/src/liborcus/ods_dde_links_context.hpp new file mode 100644 index 0000000..0abba49 --- /dev/null +++ b/src/liborcus/ods_dde_links_context.hpp @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ODS_DDE_LINKS_CONTEXT_HPP +#define INCLUDED_ODS_DDE_LINKS_CONTEXT_HPP + +#include "xml_context_base.hpp" + +namespace orcus { + +/** + * Handle <table:dde-links> element structure. For now, this context exists + * only to ignore all DDE related data. + */ +class ods_dde_links_context : public xml_context_base +{ +public: + ods_dde_links_context(session_context& session_cxt, const tokens& tokens); + virtual ~ods_dde_links_context(); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name) override; + + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base *child) override; + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t> &attrs) override; + + virtual bool end_element(xmlns_id_t ns, xml_token_t name) override; + + virtual void characters(std::string_view str, bool transient) override; + + void reset(); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ods_session_data.cpp b/src/liborcus/ods_session_data.cpp new file mode 100644 index 0000000..c039e05 --- /dev/null +++ b/src/liborcus/ods_session_data.cpp @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ods_session_data.hpp" + +#include <limits> + +namespace orcus { + +ods_session_data::formula_result::formula_result() : + type(rt_none), numeric_value(std::numeric_limits<double>::quiet_NaN()) {} + +ods_session_data::formula::formula( + spreadsheet::sheet_t _sheet, spreadsheet::row_t _row, spreadsheet::col_t _col, + spreadsheet::formula_grammar_t _grammar, std::string_view _exp) : + sheet(_sheet), row(_row), column(_col), grammar(_grammar), exp(_exp) {} + +ods_session_data::named_exp::named_exp( + std::string_view _name, std::string_view _expression, std::string_view _base, named_exp_type _type, spreadsheet::sheet_t _scope) : + name(_name), expression(_expression), base(_base), type(_type), scope(_scope) {} + +std::string_view ods_session_data::number_formats_store::get_code(std::string_view name) const +{ + auto it_name = name2id_map.find(name); + if (it_name == name2id_map.end()) + return {}; + + std::size_t id = it_name->second; + auto it_code = id2code_map.find(id); + if (it_code == id2code_map.end()) + return {}; + + return it_code->second; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ods_session_data.hpp b/src/liborcus/ods_session_data.hpp new file mode 100644 index 0000000..4223095 --- /dev/null +++ b/src/liborcus/ods_session_data.hpp @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_ODS_SESSION_DATA_HPP +#define INCLUDED_ORCUS_ODS_SESSION_DATA_HPP + +#include "session_context.hpp" +#include "odf_styles.hpp" + +#include <orcus/spreadsheet/types.hpp> + +#include <deque> + +namespace orcus { + +struct ods_session_data : public session_context::custom_data +{ + enum formula_result_type { rt_none, rt_numeric, rt_string, rt_error }; + enum named_exp_type { ne_unknown, ne_range, ne_expression }; + + struct formula_result + { + formula_result_type type; + double numeric_value; + std::string_view string_value; + + formula_result(); + }; + + struct formula + { + spreadsheet::sheet_t sheet; + spreadsheet::row_t row; + spreadsheet::col_t column; + + spreadsheet::formula_grammar_t grammar; + std::string_view exp; + + formula_result result; + + formula( + spreadsheet::sheet_t _sheet, spreadsheet::row_t _row, spreadsheet::col_t _col, + spreadsheet::formula_grammar_t _grammar, std::string_view _exp); + }; + + struct named_exp + { + std::string_view name; + std::string_view expression; + std::string_view base; + + named_exp_type type; + spreadsheet::sheet_t scope; // >= 0 for sheet scope, or < 0 for global scope. + + named_exp(std::string_view _name, std::string_view _expression, std::string_view _base, named_exp_type _type, spreadsheet::sheet_t _scope); + }; + + std::deque<formula> formulas; + std::deque<named_exp> named_exps; + + odf_styles_map_type styles_map; + + struct number_formats_store + { + std::map<std::string_view, std::size_t> name2id_map; + std::map<std::size_t, std::string> id2code_map; + + std::string_view get_code(std::string_view name) const; + }; + + number_formats_store number_formats; +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ooxml_content_types.cpp b/src/liborcus/ooxml_content_types.cpp new file mode 100644 index 0000000..eb614c7 --- /dev/null +++ b/src/liborcus/ooxml_content_types.cpp @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ooxml_content_types.hpp" + +namespace orcus { + +const content_type_t CT_ooxml_extended_properties = "application/vnd.openxmlformats-officedocument.extended-properties+xml"; +const content_type_t CT_ooxml_drawing = "application/vnd.openxmlformats-officedocument.drawing+xml"; +const content_type_t CT_ooxml_vml_drawing = "application/vnd.openxmlformats-officedocument.vmlDrawing"; +const content_type_t CT_ooxml_xlsx_calc_chain = "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml"; +const content_type_t CT_ooxml_xlsx_comments = "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"; +const content_type_t CT_ooxml_xlsx_connections = "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml"; +const content_type_t CT_ooxml_xlsx_external_link = "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml"; +const content_type_t CT_ooxml_xlsx_pivot_cache_def = "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml"; +const content_type_t CT_ooxml_xlsx_pivot_cache_rec = "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml"; +const content_type_t CT_ooxml_xlsx_pivot_table = "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml"; +const content_type_t CT_ooxml_xlsx_printer_settings = "application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings"; +const content_type_t CT_ooxml_xlsx_query_table = "application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml"; +const content_type_t CT_ooxml_xlsx_shared_strings = "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"; +const content_type_t CT_ooxml_xlsx_sheet_main = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"; +const content_type_t CT_ooxml_xlsx_styles = "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"; +const content_type_t CT_ooxml_xlsx_table = "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml"; +const content_type_t CT_ooxml_xlsx_worksheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"; +const content_type_t CT_ooxml_xlsx_usernames = "application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml"; +const content_type_t CT_ooxml_xlsx_rev_headers = "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml"; +const content_type_t CT_ooxml_xlsx_rev_log = "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml"; +const content_type_t CT_ooxml_theme = "application/vnd.openxmlformats-officedocument.theme+xml"; +const content_type_t CT_opc_core_properties = "application/vnd.openxmlformats-package.core-properties+xml"; +const content_type_t CT_opc_relationships = "application/vnd.openxmlformats-package.relationships+xml"; +const content_type_t CT_xml = "application/xml"; +const content_type_t CT_image_png = "image/png"; + +namespace { + +content_type_t cts[] = { + CT_ooxml_extended_properties, + CT_ooxml_drawing, + CT_ooxml_vml_drawing, + CT_ooxml_xlsx_calc_chain, + CT_ooxml_xlsx_comments, + CT_ooxml_xlsx_connections, + CT_ooxml_xlsx_external_link, + CT_ooxml_xlsx_pivot_cache_def, + CT_ooxml_xlsx_pivot_cache_rec, + CT_ooxml_xlsx_pivot_table, + CT_ooxml_xlsx_printer_settings, + CT_ooxml_xlsx_query_table, + CT_ooxml_xlsx_shared_strings, + CT_ooxml_xlsx_sheet_main, + CT_ooxml_xlsx_styles, + CT_ooxml_xlsx_table, + CT_ooxml_xlsx_worksheet, + CT_ooxml_xlsx_usernames, + CT_ooxml_xlsx_rev_headers, + CT_ooxml_xlsx_rev_log, + CT_ooxml_theme, + CT_opc_core_properties, + CT_opc_relationships, + CT_xml, + CT_image_png, + nullptr +}; + +} + +const content_type_t* CT_all = cts; + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ooxml_content_types.hpp b/src/liborcus/ooxml_content_types.hpp new file mode 100644 index 0000000..d82dd53 --- /dev/null +++ b/src/liborcus/ooxml_content_types.hpp @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_OOXML_CONTENT_TYPES_HPP +#define INCLUDED_ORCUS_OOXML_CONTENT_TYPES_HPP + +#include "ooxml_types.hpp" + +namespace orcus { + +extern const content_type_t CT_ooxml_extended_properties; +extern const content_type_t CT_ooxml_drawing; +extern const content_type_t CT_ooxml_vml_drawing; +extern const content_type_t CT_ooxml_xlsx_calc_chain; +extern const content_type_t CT_ooxml_xlsx_comments; +extern const content_type_t CT_ooxml_xlsx_connections; +extern const content_type_t CT_ooxml_xlsx_external_link; +extern const content_type_t CT_ooxml_xlsx_pivot_cache_def; +extern const content_type_t CT_ooxml_xlsx_pivot_cache_rec; +extern const content_type_t CT_ooxml_xlsx_pivot_table; +extern const content_type_t CT_ooxml_xlsx_printer_settings; +extern const content_type_t CT_ooxml_xlsx_query_table; +extern const content_type_t CT_ooxml_xlsx_shared_strings; +extern const content_type_t CT_ooxml_xlsx_sheet_main; +extern const content_type_t CT_ooxml_xlsx_styles; +extern const content_type_t CT_ooxml_xlsx_table; +extern const content_type_t CT_ooxml_xlsx_worksheet; +extern const content_type_t CT_ooxml_xlsx_usernames; +extern const content_type_t CT_ooxml_xlsx_rev_headers; +extern const content_type_t CT_ooxml_xlsx_rev_log; +extern const content_type_t CT_ooxml_theme; +extern const content_type_t CT_opc_core_properties; +extern const content_type_t CT_opc_relationships; +extern const content_type_t CT_xml; +extern const content_type_t CT_image_png; + +/** + * Null-terminated array of all content types. + */ +extern const content_type_t* CT_all; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ooxml_global.cpp b/src/liborcus/ooxml_global.cpp new file mode 100644 index 0000000..6c6d93b --- /dev/null +++ b/src/liborcus/ooxml_global.cpp @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ooxml_global.hpp" +#include "ooxml_types.hpp" +#include "ooxml_token_constants.hpp" +#include "ooxml_namespace_types.hpp" +#include "xml_context_base.hpp" + +#include <iostream> +#include <sstream> + +namespace orcus { + +void print_opc_rel::operator() (const opc_rel_t& v) const +{ + std::cout << v.rid << ": " << v.target << " (" << v.type << ")" << std::endl; +} + +std::string resolve_file_path(const std::string& dir_path, const std::string& file_name) +{ + if (dir_path.empty()) + return file_name; + + const char* p = &dir_path[0]; + const char* p_end = p + dir_path.size(); + + bool has_root = *p == '/'; + if (has_root) + ++p; + + std::vector<std::string_view> dir_stack; + const char* p_head = nullptr; + for (; p != p_end; ++p) + { + if (*p == '/') + { + if (!p_head) + // invalid directory path. + return file_name; + + size_t len = p - p_head; + std::string_view dir(p_head, len); + if (dir == "..") + { + if (dir_stack.empty()) + // invalid directory path. + return file_name; + + dir_stack.pop_back(); + } + else + dir_stack.push_back(dir); + + p_head = nullptr; + } + else if (p_head) + { + // Do nothing. + } + else + p_head = p; + } + + if (p_head) + { + // directory path must end with '/'. This one doesn't. + return file_name; + } + + std::ostringstream full_path; + if (has_root) + full_path << '/'; + + for (auto dir : dir_stack) + full_path << dir << '/'; + + full_path << file_name; + + return full_path.str(); +} + +void init_ooxml_context(xml_context_base& cxt) +{ + cxt.set_always_allowed_elements({ + { NS_mc, XML_Choice }, + { NS_mc, XML_Fallback }, + }); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ooxml_global.hpp b/src/liborcus/ooxml_global.hpp new file mode 100644 index 0000000..853c4e9 --- /dev/null +++ b/src/liborcus/ooxml_global.hpp @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_OOXML_GLOBAL_HPP +#define ORCUS_OOXML_GLOBAL_HPP + +#include "orcus/types.hpp" +#include "ooxml_types.hpp" + +#include <string> +#include <functional> + +namespace orcus { + +struct opc_rel_t; +struct xml_token_attr_t; +class xml_context_base; + +/** + * Function object to print relationship information. + */ +struct print_opc_rel +{ + void operator() (const opc_rel_t& v) const; +}; + +/** + * Given a directory path and a file name, return a full path that combines + * the two while resolving any parent directory path ".." markers. + * + * @param dir_path directory path. It can optionally start with a '/', but + * it must end with a '/'. + * @param file_name file name. + * + * @return full file path. + */ +std::string resolve_file_path(const std::string& dir_path, const std::string& file_name); + +void init_ooxml_context(xml_context_base& cxt); + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ooxml_namespace_types.cpp b/src/liborcus/ooxml_namespace_types.cpp new file mode 100644 index 0000000..8c1224b --- /dev/null +++ b/src/liborcus/ooxml_namespace_types.cpp @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ooxml_namespace_types.hpp" + +namespace orcus { + +const xmlns_id_t NS_ooxml_a = "http://schemas.openxmlformats.org/drawingml/2006/main"; +const xmlns_id_t NS_ooxml_r = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"; +const xmlns_id_t NS_ooxml_xdr = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"; +const xmlns_id_t NS_ooxml_xlsx = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; + +const xmlns_id_t NS_opc_ct = "http://schemas.openxmlformats.org/package/2006/content-types"; +const xmlns_id_t NS_opc_rel = "http://schemas.openxmlformats.org/package/2006/relationships"; + +const xmlns_id_t NS_mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"; +const xmlns_id_t NS_mso_x14 = "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"; + +namespace { + +xmlns_id_t ooxml_ns[] = { + NS_ooxml_a, + NS_ooxml_r, + NS_ooxml_xdr, + NS_ooxml_xlsx, + nullptr +}; + +xmlns_id_t opc_ns[] = { + NS_opc_ct, + NS_opc_rel, + nullptr +}; + +xmlns_id_t misc_ns[] = { + NS_mc, + NS_mso_x14, + nullptr +}; + +} + +const xmlns_id_t* NS_ooxml_all = ooxml_ns; +const xmlns_id_t* NS_opc_all = opc_ns; +const xmlns_id_t* NS_misc_all = misc_ns; + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ooxml_namespace_types.hpp b/src/liborcus/ooxml_namespace_types.hpp new file mode 100644 index 0000000..8183bf8 --- /dev/null +++ b/src/liborcus/ooxml_namespace_types.hpp @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_OOXML_NAMESPACE_TYPES_HPP +#define INCLUDED_ORCUS_OOXML_NAMESPACE_TYPES_HPP + +#include "orcus/types.hpp" + +namespace orcus { + +extern const xmlns_id_t NS_ooxml_a; +extern const xmlns_id_t NS_ooxml_r; +extern const xmlns_id_t NS_ooxml_xlsx; +extern const xmlns_id_t NS_ooxml_xdr; + +extern const xmlns_id_t NS_opc_ct; +extern const xmlns_id_t NS_opc_rel; + +extern const xmlns_id_t NS_mc; +extern const xmlns_id_t NS_mso_x14; + +/** + * Null-terminated array of all ooxml namespaces. + */ +extern const xmlns_id_t* NS_ooxml_all; + +/** + * Null-terminated array of all opc namespaces. + */ +extern const xmlns_id_t* NS_opc_all; + +/** + * Null-terminated array of all the other namespaces. + */ +extern const xmlns_id_t* NS_misc_all; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ooxml_schemas.cpp b/src/liborcus/ooxml_schemas.cpp new file mode 100644 index 0000000..b0e86e4 --- /dev/null +++ b/src/liborcus/ooxml_schemas.cpp @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ooxml_schemas.hpp" + +namespace orcus { + +schema_t SCH_mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"; +schema_t SCH_opc_content_types = "http://schemas.openxmlformats.org/package/2006/content-types"; +schema_t SCH_opc_rels = "http://schemas.openxmlformats.org/package/2006/relationships"; +schema_t SCH_opc_rels_metadata_core_props = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"; +schema_t SCH_od_rels_calc_chain = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/calcChain"; +schema_t SCH_od_rels_connections = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/connections"; +schema_t SCH_od_rels_printer_settings = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings"; +schema_t SCH_od_rels_rev_headers = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/revisionHeaders"; +schema_t SCH_od_rels_rev_log = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/revisionLog"; +schema_t SCH_od_rels_shared_strings = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"; +schema_t SCH_od_rels_styles = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"; +schema_t SCH_od_rels_theme = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"; +schema_t SCH_od_rels_usernames = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/usernames"; +schema_t SCH_od_rels_worksheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"; +schema_t SCH_od_rels_extended_props = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties"; +schema_t SCH_od_rels_office_doc = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"; +schema_t SCH_od_rels_table = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table"; +schema_t SCH_od_rels_pivot_cache_def = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition"; +schema_t SCH_od_rels_pivot_cache_rec = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheRecords"; +schema_t SCH_od_rels_pivot_table = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable"; +schema_t SCH_od_rels_drawing = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing"; +schema_t SCH_xlsx_main = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; +schema_t SCH_mso_x14ac = "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"; + +namespace { + +schema_t schs[] = { + SCH_mc, + SCH_opc_content_types, + SCH_opc_rels, + SCH_opc_rels_metadata_core_props, + SCH_od_rels_calc_chain, + SCH_od_rels_connections, + SCH_od_rels_printer_settings, + SCH_od_rels_rev_headers, + SCH_od_rels_rev_log, + SCH_od_rels_shared_strings, + SCH_od_rels_styles, + SCH_od_rels_theme, + SCH_od_rels_usernames, + SCH_od_rels_worksheet, + SCH_od_rels_extended_props, + SCH_od_rels_office_doc, + SCH_od_rels_table, + SCH_od_rels_pivot_cache_def, + SCH_od_rels_pivot_cache_rec, + SCH_od_rels_pivot_table, + SCH_od_rels_drawing, + SCH_xlsx_main, + SCH_mso_x14ac, + nullptr +}; + +} + +schema_t* SCH_all = schs; + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ooxml_schemas.hpp b/src/liborcus/ooxml_schemas.hpp new file mode 100644 index 0000000..85adb6f --- /dev/null +++ b/src/liborcus/ooxml_schemas.hpp @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_OOXML_SCHEMAS_HPP +#define INCLUDED_ORCUS_OOXML_SCHEMAS_HPP + +#include "ooxml_types.hpp" + +namespace orcus { + +extern schema_t SCH_mc; +extern schema_t SCH_opc_content_types; +extern schema_t SCH_opc_rels; +extern schema_t SCH_opc_rels_metadata_core_props; +extern schema_t SCH_od_rels_calc_chain; +extern schema_t SCH_od_rels_connections; +extern schema_t SCH_od_rels_printer_settings; +extern schema_t SCH_od_rels_rev_headers; +extern schema_t SCH_od_rels_rev_log; +extern schema_t SCH_od_rels_shared_strings; +extern schema_t SCH_od_rels_styles; +extern schema_t SCH_od_rels_theme; +extern schema_t SCH_od_rels_usernames; +extern schema_t SCH_od_rels_worksheet; +extern schema_t SCH_od_rels_extended_props; +extern schema_t SCH_od_rels_office_doc; +extern schema_t SCH_od_rels_table; +extern schema_t SCH_od_rels_pivot_cache_def; +extern schema_t SCH_od_rels_pivot_cache_rec; +extern schema_t SCH_od_rels_pivot_table; +extern schema_t SCH_od_rels_drawing; +extern schema_t SCH_xlsx_main; +extern schema_t SCH_mso_x14ac; + +/** + * Null-terminated array of all schema types. + */ +extern schema_t* SCH_all; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ooxml_token_constants.hpp b/src/liborcus/ooxml_token_constants.hpp new file mode 100644 index 0000000..13f7fcf --- /dev/null +++ b/src/liborcus/ooxml_token_constants.hpp @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef __ORCUS_OOXML_TOKEN_CONSTANTS_HPP__ +#define __ORCUS_OOXML_TOKEN_CONSTANTS_HPP__ + +#include "orcus/types.hpp" + +namespace orcus { + +#include "ooxml_token_constants.inl" + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ooxml_token_constants.inl b/src/liborcus/ooxml_token_constants.inl new file mode 100644 index 0000000..c2a047d --- /dev/null +++ b/src/liborcus/ooxml_token_constants.inl @@ -0,0 +1,3519 @@ +// This file has been auto-generated. Do not hand-edit this. + +const xml_token_t XML_AbbreviatedCaseNumber = 1; +const xml_token_t XML_Accel = 2; +const xml_token_t XML_Accel2 = 3; +const xml_token_t XML_AlbumTitle = 4; +const xml_token_t XML_AlternateContent = 5; +const xml_token_t XML_Anchor = 6; +const xml_token_t XML_AppVersion = 7; +const xml_token_t XML_Append = 8; +const xml_token_t XML_Application = 9; +const xml_token_t XML_Artist = 10; +const xml_token_t XML_Author = 11; +const xml_token_t XML_AutoFill = 12; +const xml_token_t XML_AutoFit = 13; +const xml_token_t XML_AutoLine = 14; +const xml_token_t XML_AutoPict = 15; +const xml_token_t XML_AutoScale = 16; +const xml_token_t XML_BookAuthor = 17; +const xml_token_t XML_BookTitle = 18; +const xml_token_t XML_BroadcastTitle = 19; +const xml_token_t XML_Broadcaster = 20; +const xml_token_t XML_CF = 21; +const xml_token_t XML_Camera = 22; +const xml_token_t XML_Cancel = 23; +const xml_token_t XML_CaseNumber = 24; +const xml_token_t XML_ChapterNumber = 25; +const xml_token_t XML_Characters = 26; +const xml_token_t XML_CharactersWithSpaces = 27; +const xml_token_t XML_Checked = 28; +const xml_token_t XML_Choice = 29; +const xml_token_t XML_City = 30; +const xml_token_t XML_ClientData = 31; +const xml_token_t XML_ColHidden = 32; +const xml_token_t XML_Colored = 33; +const xml_token_t XML_Column = 34; +const xml_token_t XML_Comments = 35; +const xml_token_t XML_Company = 36; +const xml_token_t XML_Compiler = 37; +const xml_token_t XML_Composer = 38; +const xml_token_t XML_Conductor = 39; +const xml_token_t XML_ConferenceName = 40; +const xml_token_t XML_ConnectionID = 41; +const xml_token_t XML_Corporate = 42; +const xml_token_t XML_Counsel = 43; +const xml_token_t XML_CountryRegion = 44; +const xml_token_t XML_Court = 45; +const xml_token_t XML_DDE = 46; +const xml_token_t XML_DataBinding = 47; +const xml_token_t XML_DataBindingLoadMode = 48; +const xml_token_t XML_DataBindingName = 49; +const xml_token_t XML_Day = 50; +const xml_token_t XML_DayAccessed = 51; +const xml_token_t XML_Default = 52; +const xml_token_t XML_DefaultSize = 53; +const xml_token_t XML_Department = 54; +const xml_token_t XML_DigSig = 55; +const xml_token_t XML_Director = 56; +const xml_token_t XML_Disabled = 57; +const xml_token_t XML_Dismiss = 58; +const xml_token_t XML_Distributor = 59; +const xml_token_t XML_DocSecurity = 60; +const xml_token_t XML_DrawAspect = 61; +const xml_token_t XML_DropLines = 62; +const xml_token_t XML_DropStyle = 63; +const xml_token_t XML_Dx = 64; +const xml_token_t XML_Edition = 65; +const xml_token_t XML_Editor = 66; +const xml_token_t XML_Fallback = 67; +const xml_token_t XML_FieldCodes = 68; +const xml_token_t XML_FileBinding = 69; +const xml_token_t XML_FileBindingName = 70; +const xml_token_t XML_First = 71; +const xml_token_t XML_FirstButton = 72; +const xml_token_t XML_FmlaGroup = 73; +const xml_token_t XML_FmlaLink = 74; +const xml_token_t XML_FmlaMacro = 75; +const xml_token_t XML_FmlaPict = 76; +const xml_token_t XML_FmlaRange = 77; +const xml_token_t XML_FmlaTxbx = 78; +const xml_token_t XML_Guid = 79; +const xml_token_t XML_HLinks = 80; +const xml_token_t XML_HeadingPairs = 81; +const xml_token_t XML_Help = 82; +const xml_token_t XML_HiddenSlides = 83; +const xml_token_t XML_Horiz = 84; +const xml_token_t XML_HyperlinkBase = 85; +const xml_token_t XML_HyperlinksChanged = 86; +const xml_token_t XML_ID = 87; +const xml_token_t XML_Inc = 88; +const xml_token_t XML_Institution = 89; +const xml_token_t XML_InternetSiteTitle = 90; +const xml_token_t XML_Interviewee = 91; +const xml_token_t XML_Interviewer = 92; +const xml_token_t XML_Inventor = 93; +const xml_token_t XML_Issue = 94; +const xml_token_t XML_JournalName = 95; +const xml_token_t XML_JustLastX = 96; +const xml_token_t XML_LCID = 97; +const xml_token_t XML_LCT = 98; +const xml_token_t XML_Last = 99; +const xml_token_t XML_Lines = 100; +const xml_token_t XML_LinkType = 101; +const xml_token_t XML_LinksUpToDate = 102; +const xml_token_t XML_ListItem = 103; +const xml_token_t XML_LockText = 104; +const xml_token_t XML_Locked = 105; +const xml_token_t XML_LockedField = 106; +const xml_token_t XML_MMClips = 107; +const xml_token_t XML_Manager = 108; +const xml_token_t XML_Map = 109; +const xml_token_t XML_MapInfo = 110; +const xml_token_t XML_MapOCX = 111; +const xml_token_t XML_Max = 112; +const xml_token_t XML_Medium = 113; +const xml_token_t XML_Middle = 114; +const xml_token_t XML_Min = 115; +const xml_token_t XML_Month = 116; +const xml_token_t XML_MonthAccessed = 117; +const xml_token_t XML_MoveWithCells = 118; +const xml_token_t XML_MultiLine = 119; +const xml_token_t XML_MultiSel = 120; +const xml_token_t XML_Name = 121; +const xml_token_t XML_NameList = 122; +const xml_token_t XML_Namespace = 123; +const xml_token_t XML_NoThreeD = 124; +const xml_token_t XML_NoThreeD2 = 125; +const xml_token_t XML_Notes = 126; +const xml_token_t XML_NumberVolumes = 127; +const xml_token_t XML_OLEObject = 128; +const xml_token_t XML_ObjectID = 129; +const xml_token_t XML_ObjectType = 130; +const xml_token_t XML_Page = 131; +const xml_token_t XML_Pages = 132; +const xml_token_t XML_Paragraphs = 133; +const xml_token_t XML_PatentNumber = 134; +const xml_token_t XML_Performer = 135; +const xml_token_t XML_PeriodicalTitle = 136; +const xml_token_t XML_Person = 137; +const xml_token_t XML_PresentationFormat = 138; +const xml_token_t XML_PreserveFormat = 139; +const xml_token_t XML_PreserveSortAFLayout = 140; +const xml_token_t XML_PrintObject = 141; +const xml_token_t XML_ProducerName = 142; +const xml_token_t XML_ProductionCompany = 143; +const xml_token_t XML_ProgID = 144; +const xml_token_t XML_Properties = 145; +const xml_token_t XML_PublicationTitle = 146; +const xml_token_t XML_Publisher = 147; +const xml_token_t XML_RecalcAlways = 148; +const xml_token_t XML_RecordingNumber = 149; +const xml_token_t XML_RefOrder = 150; +const xml_token_t XML_Reporter = 151; +const xml_token_t XML_RootElement = 152; +const xml_token_t XML_Row = 153; +const xml_token_t XML_RowHidden = 154; +const xml_token_t XML_ScaleCrop = 155; +const xml_token_t XML_Schema = 156; +const xml_token_t XML_SchemaID = 157; +const xml_token_t XML_SchemaRef = 158; +const xml_token_t XML_ScriptExtended = 159; +const xml_token_t XML_ScriptLanguage = 160; +const xml_token_t XML_ScriptLocation = 161; +const xml_token_t XML_ScriptText = 162; +const xml_token_t XML_SecretEdit = 163; +const xml_token_t XML_Sel = 164; +const xml_token_t XML_SelType = 165; +const xml_token_t XML_SelectedStyle = 166; +const xml_token_t XML_SelectionNamespaces = 167; +const xml_token_t XML_ShapeID = 168; +const xml_token_t XML_SharedDoc = 169; +const xml_token_t XML_ShortTitle = 170; +const xml_token_t XML_ShowImportExportValidationErrors = 171; +const xml_token_t XML_SizeWithCells = 172; +const xml_token_t XML_Slides = 173; +const xml_token_t XML_Source = 174; +const xml_token_t XML_SourceType = 175; +const xml_token_t XML_Sources = 176; +const xml_token_t XML_StandardNumber = 177; +const xml_token_t XML_StateProvince = 178; +const xml_token_t XML_Station = 179; +const xml_token_t XML_StyleName = 180; +const xml_token_t XML_Tag = 181; +const xml_token_t XML_Template = 182; +const xml_token_t XML_TextHAlign = 183; +const xml_token_t XML_TextVAlign = 184; +const xml_token_t XML_Theater = 185; +const xml_token_t XML_ThesisType = 186; +const xml_token_t XML_Title = 187; +const xml_token_t XML_TitlesOfParts = 188; +const xml_token_t XML_TotalTime = 189; +const xml_token_t XML_Translator = 190; +const xml_token_t XML_Type = 191; +const xml_token_t XML_UIObj = 192; +const xml_token_t XML_URI = 193; +const xml_token_t XML_URL = 194; +const xml_token_t XML_UpdateMode = 195; +const xml_token_t XML_VScroll = 196; +const xml_token_t XML_VTEdit = 197; +const xml_token_t XML_Val = 198; +const xml_token_t XML_ValidIds = 199; +const xml_token_t XML_Version = 200; +const xml_token_t XML_Visible = 201; +const xml_token_t XML_Volume = 202; +const xml_token_t XML_WidthMin = 203; +const xml_token_t XML_Words = 204; +const xml_token_t XML_Writer = 205; +const xml_token_t XML_Year = 206; +const xml_token_t XML_YearAccessed = 207; +const xml_token_t XML_a = 208; +const xml_token_t XML_aboveAverage = 209; +const xml_token_t XML_absSizeAnchor = 210; +const xml_token_t XML_absoluteAnchor = 211; +const xml_token_t XML_abstractNum = 212; +const xml_token_t XML_abstractNumId = 213; +const xml_token_t XML_aca = 214; +const xml_token_t XML_acc = 215; +const xml_token_t XML_accPr = 216; +const xml_token_t XML_accel = 217; +const xml_token_t XML_accent1 = 218; +const xml_token_t XML_accent2 = 219; +const xml_token_t XML_accent3 = 220; +const xml_token_t XML_accent4 = 221; +const xml_token_t XML_accent5 = 222; +const xml_token_t XML_accent6 = 223; +const xml_token_t XML_accentbar = 224; +const xml_token_t XML_accumulate = 225; +const xml_token_t XML_action = 226; +const xml_token_t XML_active = 227; +const xml_token_t XML_activeCell = 228; +const xml_token_t XML_activeCellId = 229; +const xml_token_t XML_activeCol = 230; +const xml_token_t XML_activePane = 231; +const xml_token_t XML_activeRecord = 232; +const xml_token_t XML_activeRow = 233; +const xml_token_t XML_activeSheetId = 234; +const xml_token_t XML_activeTab = 235; +const xml_token_t XML_activeWritingStyle = 236; +const xml_token_t XML_actualPg = 237; +const xml_token_t XML_additionalCharacteristics = 238; +const xml_token_t XML_additive = 239; +const xml_token_t XML_addlxml = 240; +const xml_token_t XML_addressFieldName = 241; +const xml_token_t XML_adj = 242; +const xml_token_t XML_adjLst = 243; +const xml_token_t XML_adjust = 244; +const xml_token_t XML_adjustColumnWidth = 245; +const xml_token_t XML_adjustLineHeightInTable = 246; +const xml_token_t XML_adjustRightInd = 247; +const xml_token_t XML_adjusthandles = 248; +const xml_token_t XML_advAuto = 249; +const xml_token_t XML_advClick = 250; +const xml_token_t XML_advTm = 251; +const xml_token_t XML_advise = 252; +const xml_token_t XML_after = 253; +const xml_token_t XML_afterAutospacing = 254; +const xml_token_t XML_afterEffect = 255; +const xml_token_t XML_afterLines = 256; +const xml_token_t XML_ahLst = 257; +const xml_token_t XML_ahPolar = 258; +const xml_token_t XML_ahXY = 259; +const xml_token_t XML_alg = 260; +const xml_token_t XML_algIdExt = 261; +const xml_token_t XML_algIdExtSource = 262; +const xml_token_t XML_algn = 263; +const xml_token_t XML_alias = 264; +const xml_token_t XML_aliases = 265; +const xml_token_t XML_align = 266; +const xml_token_t XML_alignBordersAndEdges = 267; +const xml_token_t XML_alignTablesRowByRow = 268; +const xml_token_t XML_alignWithMargins = 269; +const xml_token_t XML_alignment = 270; +const xml_token_t XML_alignshape = 271; +const xml_token_t XML_all = 272; +const xml_token_t XML_allCaption = 273; +const xml_token_t XML_allDrilled = 274; +const xml_token_t XML_allUniqueName = 275; +const xml_token_t XML_allowBlank = 276; +const xml_token_t XML_allowOverlap = 277; +const xml_token_t XML_allowPNG = 278; +const xml_token_t XML_allowPng = 279; +const xml_token_t XML_allowRefreshQuery = 280; +const xml_token_t XML_allowSpaceOfSameStyleInTable = 281; +const xml_token_t XML_allowcomments = 282; +const xml_token_t XML_allowincell = 283; +const xml_token_t XML_allowoverlap = 284; +const xml_token_t XML_aln = 285; +const xml_token_t XML_alnAt = 286; +const xml_token_t XML_alnScr = 287; +const xml_token_t XML_alpha = 288; +const xml_token_t XML_alphaBiLevel = 289; +const xml_token_t XML_alphaCeiling = 290; +const xml_token_t XML_alphaFloor = 291; +const xml_token_t XML_alphaInv = 292; +const xml_token_t XML_alphaMod = 293; +const xml_token_t XML_alphaModFix = 294; +const xml_token_t XML_alphaOff = 295; +const xml_token_t XML_alphaOutset = 296; +const xml_token_t XML_alphaRepl = 297; +const xml_token_t XML_alt = 298; +const xml_token_t XML_altChunk = 299; +const xml_token_t XML_altChunkPr = 300; +const xml_token_t XML_altLang = 301; +const xml_token_t XML_altName = 302; +const xml_token_t XML_althref = 303; +const xml_token_t XML_alwaysMergeEmptyNamespace = 304; +const xml_token_t XML_alwaysShow = 305; +const xml_token_t XML_alwaysShowPlaceholderText = 306; +const xml_token_t XML_amt = 307; +const xml_token_t XML_anchor = 308; +const xml_token_t XML_anchorCtr = 309; +const xml_token_t XML_anchorLock = 310; +const xml_token_t XML_anchorlock = 311; +const xml_token_t XML_anchorx = 312; +const xml_token_t XML_anchory = 313; +const xml_token_t XML_and = 314; +const xml_token_t XML_ang = 315; +const xml_token_t XML_angle = 316; +const xml_token_t XML_anim = 317; +const xml_token_t XML_animBg = 318; +const xml_token_t XML_animClr = 319; +const xml_token_t XML_animEffect = 320; +const xml_token_t XML_animLvl = 321; +const xml_token_t XML_animMotion = 322; +const xml_token_t XML_animOne = 323; +const xml_token_t XML_animRot = 324; +const xml_token_t XML_animScale = 325; +const xml_token_t XML_annotation = 326; +const xml_token_t XML_annotationRef = 327; +const xml_token_t XML_appName = 328; +const xml_token_t XML_applyAlignment = 329; +const xml_token_t XML_applyAlignmentFormats = 330; +const xml_token_t XML_applyBorder = 331; +const xml_token_t XML_applyBorderFormats = 332; +const xml_token_t XML_applyBreakingRules = 333; +const xml_token_t XML_applyFill = 334; +const xml_token_t XML_applyFont = 335; +const xml_token_t XML_applyFontFormats = 336; +const xml_token_t XML_applyNumberFormat = 337; +const xml_token_t XML_applyNumberFormats = 338; +const xml_token_t XML_applyPatternFormats = 339; +const xml_token_t XML_applyProtection = 340; +const xml_token_t XML_applyStyles = 341; +const xml_token_t XML_applyToEnd = 342; +const xml_token_t XML_applyToFront = 343; +const xml_token_t XML_applyToSides = 344; +const xml_token_t XML_applyWidthHeightFormats = 345; +const xml_token_t XML_arc = 346; +const xml_token_t XML_arcTo = 347; +const xml_token_t XML_arcsize = 348; +const xml_token_t XML_area3DChart = 349; +const xml_token_t XML_areaChart = 350; +const xml_token_t XML_arg = 351; +const xml_token_t XML_argPr = 352; +const xml_token_t XML_argSz = 353; +const xml_token_t XML_array = 354; +const xml_token_t XML_arrowok = 355; +const xml_token_t XML_ascii = 356; +const xml_token_t XML_asciiTheme = 357; +const xml_token_t XML_aspect = 358; +const xml_token_t XML_aspectratio = 359; +const xml_token_t XML_assign = 360; +const xml_token_t XML_asteriskTotals = 361; +const xml_token_t XML_attachedSchema = 362; +const xml_token_t XML_attachedTemplate = 363; +const xml_token_t XML_attr = 364; +const xml_token_t XML_attrName = 365; +const xml_token_t XML_attrNameLst = 366; +const xml_token_t XML_attribute = 367; +const xml_token_t XML_audio = 368; +const xml_token_t XML_audioCd = 369; +const xml_token_t XML_audioFile = 370; +const xml_token_t XML_author = 371; +const xml_token_t XML_authorId = 372; +const xml_token_t XML_authors = 373; +const xml_token_t XML_auto = 374; +const xml_token_t XML_autoAdjust = 375; +const xml_token_t XML_autoCaption = 376; +const xml_token_t XML_autoCaptions = 377; +const xml_token_t XML_autoCompressPictures = 378; +const xml_token_t XML_autoEnd = 379; +const xml_token_t XML_autoFilter = 380; +const xml_token_t XML_autoFilterDateGrouping = 381; +const xml_token_t XML_autoFormatId = 382; +const xml_token_t XML_autoFormatOverride = 383; +const xml_token_t XML_autoHyphenation = 384; +const xml_token_t XML_autoLoad = 385; +const xml_token_t XML_autoPage = 386; +const xml_token_t XML_autoPageBreaks = 387; +const xml_token_t XML_autoRecover = 388; +const xml_token_t XML_autoRedefine = 389; +const xml_token_t XML_autoRepublish = 390; +const xml_token_t XML_autoRev = 391; +const xml_token_t XML_autoShow = 392; +const xml_token_t XML_autoSortScope = 393; +const xml_token_t XML_autoSpaceDE = 394; +const xml_token_t XML_autoSpaceDN = 395; +const xml_token_t XML_autoSpaceLikeWord95 = 396; +const xml_token_t XML_autoStart = 397; +const xml_token_t XML_autoTitleDeleted = 398; +const xml_token_t XML_autoUpdate = 399; +const xml_token_t XML_autoUpdateAnimBg = 400; +const xml_token_t XML_autofitToFirstFixedWidthCell = 401; +const xml_token_t XML_autoformat = 402; +const xml_token_t XML_autolayout = 403; +const xml_token_t XML_autorotationcenter = 404; +const xml_token_t XML_avLst = 405; +const xml_token_t XML_avgSubtotal = 406; +const xml_token_t XML_axId = 407; +const xml_token_t XML_axPos = 408; +const xml_token_t XML_axis = 409; +const xml_token_t XML_b = 410; +const xml_token_t XML_bCs = 411; +const xml_token_t XML_bIns = 412; +const xml_token_t XML_backWall = 413; +const xml_token_t XML_backdepth = 414; +const xml_token_t XML_backdrop = 415; +const xml_token_t XML_background = 416; +const xml_token_t XML_backgroundQuery = 417; +const xml_token_t XML_backgroundRefresh = 418; +const xml_token_t XML_backupFile = 419; +const xml_token_t XML_backward = 420; +const xml_token_t XML_backwards = 421; +const xml_token_t XML_balanceSingleByteDoubleByteWidth = 422; +const xml_token_t XML_band1H = 423; +const xml_token_t XML_band1V = 424; +const xml_token_t XML_band2H = 425; +const xml_token_t XML_band2V = 426; +const xml_token_t XML_bandCol = 427; +const xml_token_t XML_bandFmt = 428; +const xml_token_t XML_bandFmts = 429; +const xml_token_t XML_bandRow = 430; +const xml_token_t XML_bar = 431; +const xml_token_t XML_bar3DChart = 432; +const xml_token_t XML_barChart = 433; +const xml_token_t XML_barDir = 434; +const xml_token_t XML_barPr = 435; +const xml_token_t XML_base = 436; +const xml_token_t XML_baseColWidth = 437; +const xml_token_t XML_baseField = 438; +const xml_token_t XML_baseItem = 439; +const xml_token_t XML_baseJc = 440; +const xml_token_t XML_baseTimeUnit = 441; +const xml_token_t XML_baseType = 442; +const xml_token_t XML_basedOn = 443; +const xml_token_t XML_baseline = 444; +const xml_token_t XML_bc = 445; +const xml_token_t XML_bdr = 446; +const xml_token_t XML_before = 447; +const xml_token_t XML_beforeAutospacing = 448; +const xml_token_t XML_beforeLines = 449; +const xml_token_t XML_begChr = 450; +const xml_token_t XML_behavior = 451; +const xml_token_t XML_behaviors = 452; +const xml_token_t XML_behindDoc = 453; +const xml_token_t XML_bestFit = 454; +const xml_token_t XML_between = 455; +const xml_token_t XML_bevel = 456; +const xml_token_t XML_bevelB = 457; +const xml_token_t XML_bevelT = 458; +const xml_token_t XML_bg = 459; +const xml_token_t XML_bg1 = 460; +const xml_token_t XML_bg2 = 461; +const xml_token_t XML_bgClr = 462; +const xml_token_t XML_bgColor = 463; +const xml_token_t XML_bgFillStyleLst = 464; +const xml_token_t XML_bgPr = 465; +const xml_token_t XML_bgRef = 466; +const xml_token_t XML_biLevel = 467; +const xml_token_t XML_bibliography = 468; +const xml_token_t XML_bidi = 469; +const xml_token_t XML_bidiVisual = 470; +const xml_token_t XML_bilevel = 471; +const xml_token_t XML_bk = 472; +const xml_token_t XML_blackAndWhite = 473; +const xml_token_t XML_blacklevel = 474; +const xml_token_t XML_blank = 475; +const xml_token_t XML_bld = 476; +const xml_token_t XML_bldAsOne = 477; +const xml_token_t XML_bldChart = 478; +const xml_token_t XML_bldDgm = 479; +const xml_token_t XML_bldGraphic = 480; +const xml_token_t XML_bldLst = 481; +const xml_token_t XML_bldLvl = 482; +const xml_token_t XML_bldOleChart = 483; +const xml_token_t XML_bldP = 484; +const xml_token_t XML_bldStep = 485; +const xml_token_t XML_bldSub = 486; +const xml_token_t XML_blend = 487; +const xml_token_t XML_blinds = 488; +const xml_token_t XML_blip = 489; +const xml_token_t XML_blipFill = 490; +const xml_token_t XML_blipPhldr = 491; +const xml_token_t XML_blob = 492; +const xml_token_t XML_blockQuote = 493; +const xml_token_t XML_blue = 494; +const xml_token_t XML_blueMod = 495; +const xml_token_t XML_blueOff = 496; +const xml_token_t XML_blur = 497; +const xml_token_t XML_blurRad = 498; +const xml_token_t XML_bmk = 499; +const xml_token_t XML_body = 500; +const xml_token_t XML_bodyDiv = 501; +const xml_token_t XML_bodyPr = 502; +const xml_token_t XML_bodyStyle = 503; +const xml_token_t XML_bold = 504; +const xml_token_t XML_boldItalic = 505; +const xml_token_t XML_bookFoldPrinting = 506; +const xml_token_t XML_bookFoldPrintingSheets = 507; +const xml_token_t XML_bookFoldRevPrinting = 508; +const xml_token_t XML_bookViews = 509; +const xml_token_t XML_bookmarkEnd = 510; +const xml_token_t XML_bookmarkIdSeed = 511; +const xml_token_t XML_bookmarkStart = 512; +const xml_token_t XML_bool = 513; +const xml_token_t XML_boolVal = 514; +const xml_token_t XML_boolean = 515; +const xml_token_t XML_border = 516; +const xml_token_t XML_borderBox = 517; +const xml_token_t XML_borderBoxPr = 518; +const xml_token_t XML_borderId = 519; +const xml_token_t XML_borderbottom = 520; +const xml_token_t XML_borderbottomcolor = 521; +const xml_token_t XML_borderleft = 522; +const xml_token_t XML_borderleftcolor = 523; +const xml_token_t XML_borderright = 524; +const xml_token_t XML_borderrightcolor = 525; +const xml_token_t XML_borders = 526; +const xml_token_t XML_bordersDoNotSurroundFooter = 527; +const xml_token_t XML_bordersDoNotSurroundHeader = 528; +const xml_token_t XML_bordertop = 529; +const xml_token_t XML_bordertopcolor = 530; +const xml_token_t XML_bottom = 531; +const xml_token_t XML_bottomFromText = 532; +const xml_token_t XML_box = 533; +const xml_token_t XML_boxPr = 534; +const xml_token_t XML_br = 535; +const xml_token_t XML_bright = 536; +const xml_token_t XML_brightness = 537; +const xml_token_t XML_brk = 538; +const xml_token_t XML_brkBin = 539; +const xml_token_t XML_brkBinSub = 540; +const xml_token_t XML_browse = 541; +const xml_token_t XML_bstr = 542; +const xml_token_t XML_buAutoNum = 543; +const xml_token_t XML_buBlip = 544; +const xml_token_t XML_buChar = 545; +const xml_token_t XML_buClr = 546; +const xml_token_t XML_buClrTx = 547; +const xml_token_t XML_buFont = 548; +const xml_token_t XML_buFontTx = 549; +const xml_token_t XML_buNone = 550; +const xml_token_t XML_buSzPct = 551; +const xml_token_t XML_buSzPts = 552; +const xml_token_t XML_buSzTx = 553; +const xml_token_t XML_bubble3D = 554; +const xml_token_t XML_bubbleChart = 555; +const xml_token_t XML_bubbleScale = 556; +const xml_token_t XML_bubbleSize = 557; +const xml_token_t XML_build = 558; +const xml_token_t XML_builtIn = 559; +const xml_token_t XML_builtInGroupCount = 560; +const xml_token_t XML_builtInUnit = 561; +const xml_token_t XML_builtinId = 562; +const xml_token_t XML_bullet = 563; +const xml_token_t XML_bulletEnabled = 564; +const xml_token_t XML_button = 565; +const xml_token_t XML_bw = 566; +const xml_token_t XML_bwMode = 567; +const xml_token_t XML_bwmode = 568; +const xml_token_t XML_bwnormal = 569; +const xml_token_t XML_bwpure = 570; +const xml_token_t XML_bx = 571; +const xml_token_t XML_by = 572; +const xml_token_t XML_byPosition = 573; +const xml_token_t XML_c = 574; +const xml_token_t XML_cBhvr = 575; +const xml_token_t XML_cGp = 576; +const xml_token_t XML_cGpRule = 577; +const xml_token_t XML_cMediaNode = 578; +const xml_token_t XML_cNvCxnSpPr = 579; +const xml_token_t XML_cNvGraphicFramePr = 580; +const xml_token_t XML_cNvGrpSpPr = 581; +const xml_token_t XML_cNvPicPr = 582; +const xml_token_t XML_cNvPr = 583; +const xml_token_t XML_cNvSpPr = 584; +const xml_token_t XML_cSld = 585; +const xml_token_t XML_cSldViewPr = 586; +const xml_token_t XML_cSp = 587; +const xml_token_t XML_cTn = 588; +const xml_token_t XML_cViewPr = 589; +const xml_token_t XML_ca = 590; +const xml_token_t XML_cacheField = 591; +const xml_token_t XML_cacheFields = 592; +const xml_token_t XML_cacheHierarchies = 593; +const xml_token_t XML_cacheHierarchy = 594; +const xml_token_t XML_cacheId = 595; +const xml_token_t XML_cacheIndex = 596; +const xml_token_t XML_cacheSource = 597; +const xml_token_t XML_cachedColBalance = 598; +const xml_token_t XML_calcChain = 599; +const xml_token_t XML_calcCompleted = 600; +const xml_token_t XML_calcId = 601; +const xml_token_t XML_calcMode = 602; +const xml_token_t XML_calcOnExit = 603; +const xml_token_t XML_calcOnSave = 604; +const xml_token_t XML_calcPr = 605; +const xml_token_t XML_calcmode = 606; +const xml_token_t XML_calculatedColumn = 607; +const xml_token_t XML_calculatedColumnFormula = 608; +const xml_token_t XML_calculatedItem = 609; +const xml_token_t XML_calculatedItems = 610; +const xml_token_t XML_calculatedMember = 611; +const xml_token_t XML_calculatedMembers = 612; +const xml_token_t XML_calendar = 613; +const xml_token_t XML_calendarType = 614; +const xml_token_t XML_callout = 615; +const xml_token_t XML_camera = 616; +const xml_token_t XML_cantSplit = 617; +const xml_token_t XML_cap = 618; +const xml_token_t XML_caps = 619; +const xml_token_t XML_caption = 620; +const xml_token_t XML_captions = 621; +const xml_token_t XML_caseSensitive = 622; +const xml_token_t XML_cat = 623; +const xml_token_t XML_catAx = 624; +const xml_token_t XML_catLst = 625; +const xml_token_t XML_category = 626; +const xml_token_t XML_categoryIdx = 627; +const xml_token_t XML_cell = 628; +const xml_token_t XML_cell3D = 629; +const xml_token_t XML_cellColor = 630; +const xml_token_t XML_cellComments = 631; +const xml_token_t XML_cellDel = 632; +const xml_token_t XML_cellIns = 633; +const xml_token_t XML_cellMerge = 634; +const xml_token_t XML_cellMeta = 635; +const xml_token_t XML_cellMetadata = 636; +const xml_token_t XML_cellSmartTag = 637; +const xml_token_t XML_cellSmartTagPr = 638; +const xml_token_t XML_cellSmartTags = 639; +const xml_token_t XML_cellStyle = 640; +const xml_token_t XML_cellStyleXfs = 641; +const xml_token_t XML_cellStyles = 642; +const xml_token_t XML_cellWatch = 643; +const xml_token_t XML_cellWatches = 644; +const xml_token_t XML_cellXfs = 645; +const xml_token_t XML_cf = 646; +const xml_token_t XML_cfRule = 647; +const xml_token_t XML_cfvo = 648; +const xml_token_t XML_chExt = 649; +const xml_token_t XML_chMax = 650; +const xml_token_t XML_chOff = 651; +const xml_token_t XML_chOrder = 652; +const xml_token_t XML_chPref = 653; +const xml_token_t XML_changesSavedWin = 654; +const xml_token_t XML_chapNum = 655; +const xml_token_t XML_chapSep = 656; +const xml_token_t XML_chapStyle = 657; +const xml_token_t XML_char = 658; +const xml_token_t XML_charRg = 659; +const xml_token_t XML_charSpace = 660; +const xml_token_t XML_characterSpacingControl = 661; +const xml_token_t XML_characteristic = 662; +const xml_token_t XML_charset = 663; +const xml_token_t XML_chart = 664; +const xml_token_t XML_chartFormat = 665; +const xml_token_t XML_chartFormats = 666; +const xml_token_t XML_chartObject = 667; +const xml_token_t XML_chartSpace = 668; +const xml_token_t XML_chartsheet = 669; +const xml_token_t XML_checkBox = 670; +const xml_token_t XML_checkCompatibility = 671; +const xml_token_t XML_checkErrors = 672; +const xml_token_t XML_checkStyle = 673; +const xml_token_t XML_checked = 674; +const xml_token_t XML_checker = 675; +const xml_token_t XML_childTnLst = 676; +const xml_token_t XML_choose = 677; +const xml_token_t XML_chr = 678; +const xml_token_t XML_chromakey = 679; +const xml_token_t XML_circle = 680; +const xml_token_t XML_citation = 681; +const xml_token_t XML_class = 682; +const xml_token_t XML_clear = 683; +const xml_token_t XML_clearAll = 684; +const xml_token_t XML_clearComments = 685; +const xml_token_t XML_clearContents = 686; +const xml_token_t XML_clearFormats = 687; +const xml_token_t XML_click = 688; +const xml_token_t XML_clickAndTypeStyle = 689; +const xml_token_t XML_clientData = 690; +const xml_token_t XML_clientInsertedTime = 691; +const xml_token_t XML_clip = 692; +const xml_token_t XML_clippath = 693; +const xml_token_t XML_clipped = 694; +const xml_token_t XML_cliptowrap = 695; +const xml_token_t XML_close = 696; +const xml_token_t XML_clr = 697; +const xml_token_t XML_clrChange = 698; +const xml_token_t XML_clrData = 699; +const xml_token_t XML_clrFrom = 700; +const xml_token_t XML_clrIdx = 701; +const xml_token_t XML_clrMap = 702; +const xml_token_t XML_clrMapOvr = 703; +const xml_token_t XML_clrMode = 704; +const xml_token_t XML_clrMru = 705; +const xml_token_t XML_clrRepl = 706; +const xml_token_t XML_clrScheme = 707; +const xml_token_t XML_clrSchemeMapping = 708; +const xml_token_t XML_clrSpc = 709; +const xml_token_t XML_clrTo = 710; +const xml_token_t XML_clrVal = 711; +const xml_token_t XML_clsid = 712; +const xml_token_t XML_cm = 713; +const xml_token_t XML_cmAuthor = 714; +const xml_token_t XML_cmAuthorLst = 715; +const xml_token_t XML_cmLst = 716; +const xml_token_t XML_cmd = 717; +const xml_token_t XML_cmpd = 718; +const xml_token_t XML_cnfStyle = 719; +const xml_token_t XML_cnt = 720; +const xml_token_t XML_code = 721; +const xml_token_t XML_codeName = 722; +const xml_token_t XML_codePage = 723; +const xml_token_t XML_coerce = 724; +const xml_token_t XML_coherent3DOff = 725; +const xml_token_t XML_col = 726; +const xml_token_t XML_colBreaks = 727; +const xml_token_t XML_colDelim = 728; +const xml_token_t XML_colFields = 729; +const xml_token_t XML_colFirst = 730; +const xml_token_t XML_colGrandTotals = 731; +const xml_token_t XML_colHeaderCaption = 732; +const xml_token_t XML_colHierarchiesUsage = 733; +const xml_token_t XML_colHierarchyUsage = 734; +const xml_token_t XML_colId = 735; +const xml_token_t XML_colItems = 736; +const xml_token_t XML_colLast = 737; +const xml_token_t XML_colOff = 738; +const xml_token_t XML_colPageCount = 739; +const xml_token_t XML_collapse = 740; +const xml_token_t XML_collapsed = 741; +const xml_token_t XML_collapsedLevelsAreSubtotals = 742; +const xml_token_t XML_color = 743; +const xml_token_t XML_color2 = 744; +const xml_token_t XML_colorFilter = 745; +const xml_token_t XML_colorId = 746; +const xml_token_t XML_colorScale = 747; +const xml_token_t XML_colormenu = 748; +const xml_token_t XML_colormode = 749; +const xml_token_t XML_colormru = 750; +const xml_token_t XML_colors = 751; +const xml_token_t XML_colorsDef = 752; +const xml_token_t XML_colorsDefHdr = 753; +const xml_token_t XML_colorsDefHdrLst = 754; +const xml_token_t XML_cols = 755; +const xml_token_t XML_column = 756; +const xml_token_t XML_columnSort = 757; +const xml_token_t XML_comb = 758; +const xml_token_t XML_combine = 759; +const xml_token_t XML_combineBrackets = 760; +const xml_token_t XML_comboBox = 761; +const xml_token_t XML_comma = 762; +const xml_token_t XML_command = 763; +const xml_token_t XML_commandType = 764; +const xml_token_t XML_comment = 765; +const xml_token_t XML_commentList = 766; +const xml_token_t XML_commentRangeEnd = 767; +const xml_token_t XML_commentRangeStart = 768; +const xml_token_t XML_commentReference = 769; +const xml_token_t XML_comments = 770; +const xml_token_t XML_comp = 771; +const xml_token_t XML_compact = 772; +const xml_token_t XML_compactData = 773; +const xml_token_t XML_compat = 774; +const xml_token_t XML_compatLnSpc = 775; +const xml_token_t XML_compatMode = 776; +const xml_token_t XML_complex = 777; +const xml_token_t XML_concurrent = 778; +const xml_token_t XML_concurrentCalc = 779; +const xml_token_t XML_concurrentManualCount = 780; +const xml_token_t XML_cond = 781; +const xml_token_t XML_condense = 782; +const xml_token_t XML_conditionalFormat = 783; +const xml_token_t XML_conditionalFormats = 784; +const xml_token_t XML_conditionalFormatting = 785; +const xml_token_t XML_connectString = 786; +const xml_token_t XML_connectangles = 787; +const xml_token_t XML_connection = 788; +const xml_token_t XML_connectionId = 789; +const xml_token_t XML_connections = 790; +const xml_token_t XML_connectloc = 791; +const xml_token_t XML_connectlocs = 792; +const xml_token_t XML_connectortype = 793; +const xml_token_t XML_connecttype = 794; +const xml_token_t XML_consecutive = 795; +const xml_token_t XML_consecutiveHyphenLimit = 796; +const xml_token_t XML_consolidation = 797; +const xml_token_t XML_constr = 798; +const xml_token_t XML_constrLst = 799; +const xml_token_t XML_constrainbounds = 800; +const xml_token_t XML_cont = 801; +const xml_token_t XML_containsBlank = 802; +const xml_token_t XML_containsDate = 803; +const xml_token_t XML_containsInteger = 804; +const xml_token_t XML_containsMixedTypes = 805; +const xml_token_t XML_containsNonDate = 806; +const xml_token_t XML_containsNumber = 807; +const xml_token_t XML_containsSemiMixedTypes = 808; +const xml_token_t XML_containsString = 809; +const xml_token_t XML_content = 810; +const xml_token_t XML_contextualSpacing = 811; +const xml_token_t XML_continuationSeparator = 812; +const xml_token_t XML_contourClr = 813; +const xml_token_t XML_contourW = 814; +const xml_token_t XML_contrast = 815; +const xml_token_t XML_control = 816; +const xml_token_t XML_control1 = 817; +const xml_token_t XML_control2 = 818; +const xml_token_t XML_controls = 819; +const xml_token_t XML_convMailMergeEsc = 820; +const xml_token_t XML_coordorigin = 821; +const xml_token_t XML_coordsize = 822; +const xml_token_t XML_copies = 823; +const xml_token_t XML_copy = 824; +const xml_token_t XML_count = 825; +const xml_token_t XML_countASubtotal = 826; +const xml_token_t XML_countBy = 827; +const xml_token_t XML_countSubtotal = 828; +const xml_token_t XML_cover = 829; +const xml_token_t XML_cp = 830; +const xml_token_t XML_cr = 831; +const xml_token_t XML_crashSave = 832; +const xml_token_t XML_createdVersion = 833; +const xml_token_t XML_credentials = 834; +const xml_token_t XML_cropbottom = 835; +const xml_token_t XML_cropleft = 836; +const xml_token_t XML_cropping = 837; +const xml_token_t XML_cropright = 838; +const xml_token_t XML_croptop = 839; +const xml_token_t XML_crossAx = 840; +const xml_token_t XML_crossBetween = 841; +const xml_token_t XML_crosses = 842; +const xml_token_t XML_crossesAt = 843; +const xml_token_t XML_cryptAlgorithmClass = 844; +const xml_token_t XML_cryptAlgorithmSid = 845; +const xml_token_t XML_cryptAlgorithmType = 846; +const xml_token_t XML_cryptProvider = 847; +const xml_token_t XML_cryptProviderType = 848; +const xml_token_t XML_cryptProviderTypeExt = 849; +const xml_token_t XML_cryptProviderTypeExtSource = 850; +const xml_token_t XML_cryptSpinCount = 851; +const xml_token_t XML_cs = 852; +const xml_token_t XML_csCatId = 853; +const xml_token_t XML_csTypeId = 854; +const xml_token_t XML_csb0 = 855; +const xml_token_t XML_csb1 = 856; +const xml_token_t XML_css = 857; +const xml_token_t XML_cstate = 858; +const xml_token_t XML_cstheme = 859; +const xml_token_t XML_ct = 860; +const xml_token_t XML_ctrlPr = 861; +const xml_token_t XML_cubicBezTo = 862; +const xml_token_t XML_culture = 863; +const xml_token_t XML_current = 864; +const xml_token_t XML_curve = 865; +const xml_token_t XML_custAng = 866; +const xml_token_t XML_custClr = 867; +const xml_token_t XML_custClrLst = 868; +const xml_token_t XML_custDash = 869; +const xml_token_t XML_custData = 870; +const xml_token_t XML_custDataLst = 871; +const xml_token_t XML_custFlipHor = 872; +const xml_token_t XML_custFlipVert = 873; +const xml_token_t XML_custGeom = 874; +const xml_token_t XML_custLinFactNeighborX = 875; +const xml_token_t XML_custLinFactNeighborY = 876; +const xml_token_t XML_custLinFactX = 877; +const xml_token_t XML_custLinFactY = 878; +const xml_token_t XML_custRadScaleInc = 879; +const xml_token_t XML_custRadScaleRad = 880; +const xml_token_t XML_custScaleX = 881; +const xml_token_t XML_custScaleY = 882; +const xml_token_t XML_custShow = 883; +const xml_token_t XML_custShowLst = 884; +const xml_token_t XML_custSplit = 885; +const xml_token_t XML_custSzX = 886; +const xml_token_t XML_custSzY = 887; +const xml_token_t XML_custT = 888; +const xml_token_t XML_custUnit = 889; +const xml_token_t XML_customBuiltin = 890; +const xml_token_t XML_customFilter = 891; +const xml_token_t XML_customFilters = 892; +const xml_token_t XML_customFormat = 893; +const xml_token_t XML_customHeight = 894; +const xml_token_t XML_customList = 895; +const xml_token_t XML_customListSort = 896; +const xml_token_t XML_customMarkFollows = 897; +const xml_token_t XML_customMenu = 898; +const xml_token_t XML_customPr = 899; +const xml_token_t XML_customProperties = 900; +const xml_token_t XML_customRollUp = 901; +const xml_token_t XML_customSheetView = 902; +const xml_token_t XML_customSheetViews = 903; +const xml_token_t XML_customStyle = 904; +const xml_token_t XML_customView = 905; +const xml_token_t XML_customWidth = 906; +const xml_token_t XML_customWorkbookView = 907; +const xml_token_t XML_customWorkbookViews = 908; +const xml_token_t XML_customXml = 909; +const xml_token_t XML_customXmlDelRangeEnd = 910; +const xml_token_t XML_customXmlDelRangeStart = 911; +const xml_token_t XML_customXmlInsRangeEnd = 912; +const xml_token_t XML_customXmlInsRangeStart = 913; +const xml_token_t XML_customXmlMoveFromRangeEnd = 914; +const xml_token_t XML_customXmlMoveFromRangeStart = 915; +const xml_token_t XML_customXmlMoveToRangeEnd = 916; +const xml_token_t XML_customXmlMoveToRangeStart = 917; +const xml_token_t XML_customXmlPr = 918; +const xml_token_t XML_cut = 919; +const xml_token_t XML_cx = 920; +const xml_token_t XML_cxn = 921; +const xml_token_t XML_cxnId = 922; +const xml_token_t XML_cxnLst = 923; +const xml_token_t XML_cxnSp = 924; +const xml_token_t XML_cxnSpLocks = 925; +const xml_token_t XML_cy = 926; +const xml_token_t XML_d = 927; +const xml_token_t XML_dLbl = 928; +const xml_token_t XML_dLblPos = 929; +const xml_token_t XML_dLbls = 930; +const xml_token_t XML_dPr = 931; +const xml_token_t XML_dPt = 932; +const xml_token_t XML_dTable = 933; +const xml_token_t XML_dashstyle = 934; +const xml_token_t XML_data = 935; +const xml_token_t XML_dataBar = 936; +const xml_token_t XML_dataBinding = 937; +const xml_token_t XML_dataBound = 938; +const xml_token_t XML_dataCaption = 939; +const xml_token_t XML_dataCellStyle = 940; +const xml_token_t XML_dataConsolidate = 941; +const xml_token_t XML_dataDxfId = 942; +const xml_token_t XML_dataExtractLoad = 943; +const xml_token_t XML_dataField = 944; +const xml_token_t XML_dataFields = 945; +const xml_token_t XML_dataModel = 946; +const xml_token_t XML_dataOnRows = 947; +const xml_token_t XML_dataOnly = 948; +const xml_token_t XML_dataPosition = 949; +const xml_token_t XML_dataRef = 950; +const xml_token_t XML_dataRefs = 951; +const xml_token_t XML_dataSource = 952; +const xml_token_t XML_dataSourceSort = 953; +const xml_token_t XML_dataType = 954; +const xml_token_t XML_dataValidation = 955; +const xml_token_t XML_dataValidations = 956; +const xml_token_t XML_databaseField = 957; +const xml_token_t XML_datastoreItem = 958; +const xml_token_t XML_date = 959; +const xml_token_t XML_date1904 = 960; +const xml_token_t XML_dateAx = 961; +const xml_token_t XML_dateFormat = 962; +const xml_token_t XML_dateGroupItem = 963; +const xml_token_t XML_dateTime = 964; +const xml_token_t XML_dateTimeGrouping = 965; +const xml_token_t XML_day = 966; +const xml_token_t XML_dayLong = 967; +const xml_token_t XML_dayShort = 968; +const xml_token_t XML_dbPr = 969; +const xml_token_t XML_ddList = 970; +const xml_token_t XML_ddeItem = 971; +const xml_token_t XML_ddeItems = 972; +const xml_token_t XML_ddeLink = 973; +const xml_token_t XML_ddeService = 974; +const xml_token_t XML_ddeTopic = 975; +const xml_token_t XML_decel = 976; +const xml_token_t XML_decimal = 977; +const xml_token_t XML_decimalSymbol = 978; +const xml_token_t XML_decorated = 979; +const xml_token_t XML_def = 980; +const xml_token_t XML_defJc = 981; +const xml_token_t XML_defLockedState = 982; +const xml_token_t XML_defPPr = 983; +const xml_token_t XML_defQFormat = 984; +const xml_token_t XML_defRPr = 985; +const xml_token_t XML_defSemiHidden = 986; +const xml_token_t XML_defStyle = 987; +const xml_token_t XML_defTabSz = 988; +const xml_token_t XML_defUIPriority = 989; +const xml_token_t XML_defUnhideWhenUsed = 990; +const xml_token_t XML_default = 991; +const xml_token_t XML_defaultAttributeDrillState = 992; +const xml_token_t XML_defaultColWidth = 993; +const xml_token_t XML_defaultGridColor = 994; +const xml_token_t XML_defaultMemberUniqueName = 995; +const xml_token_t XML_defaultPivotStyle = 996; +const xml_token_t XML_defaultRowHeight = 997; +const xml_token_t XML_defaultSubtotal = 998; +const xml_token_t XML_defaultTabStop = 999; +const xml_token_t XML_defaultTableStyle = 1000; +const xml_token_t XML_defaultTextStyle = 1001; +const xml_token_t XML_defaultThemeVersion = 1002; +const xml_token_t XML_definedName = 1003; +const xml_token_t XML_definedNames = 1004; +const xml_token_t XML_deg = 1005; +const xml_token_t XML_degHide = 1006; +const xml_token_t XML_degree = 1007; +const xml_token_t XML_del = 1008; +const xml_token_t XML_del1 = 1009; +const xml_token_t XML_del2 = 1010; +const xml_token_t XML_delInstrText = 1011; +const xml_token_t XML_delText = 1012; +const xml_token_t XML_delay = 1013; +const xml_token_t XML_delete = 1014; +const xml_token_t XML_deleteColumns = 1015; +const xml_token_t XML_deleteRows = 1016; +const xml_token_t XML_deleted = 1017; +const xml_token_t XML_deletedField = 1018; +const xml_token_t XML_delimited = 1019; +const xml_token_t XML_delimiter = 1020; +const xml_token_t XML_den = 1021; +const xml_token_t XML_denormalized = 1022; +const xml_token_t XML_depthPercent = 1023; +const xml_token_t XML_desc = 1024; +const xml_token_t XML_descending = 1025; +const xml_token_t XML_descr = 1026; +const xml_token_t XML_description = 1027; +const xml_token_t XML_destId = 1028; +const xml_token_t XML_destOrd = 1029; +const xml_token_t XML_destination = 1030; +const xml_token_t XML_destinationFile = 1031; +const xml_token_t XML_detectmouseclick = 1032; +const xml_token_t XML_dgm = 1033; +const xml_token_t XML_dgmbasetextscale = 1034; +const xml_token_t XML_dgmfontsize = 1035; +const xml_token_t XML_dgmlayout = 1036; +const xml_token_t XML_dgmlayoutmru = 1037; +const xml_token_t XML_dgmnodekind = 1038; +const xml_token_t XML_dgmscalex = 1039; +const xml_token_t XML_dgmscaley = 1040; +const xml_token_t XML_dgmstyle = 1041; +const xml_token_t XML_diagonal = 1042; +const xml_token_t XML_diagonalDown = 1043; +const xml_token_t XML_diagonalUp = 1044; +const xml_token_t XML_diagram = 1045; +const xml_token_t XML_dialogsheet = 1046; +const xml_token_t XML_diamond = 1047; +const xml_token_t XML_diff = 1048; +const xml_token_t XML_differentFirst = 1049; +const xml_token_t XML_differentOddEven = 1050; +const xml_token_t XML_diffusity = 1051; +const xml_token_t XML_dimension = 1052; +const xml_token_t XML_dimensionUniqueName = 1053; +const xml_token_t XML_dimensions = 1054; +const xml_token_t XML_dir = 1055; +const xml_token_t XML_dirty = 1056; +const xml_token_t XML_disableEdit = 1057; +const xml_token_t XML_disableFieldList = 1058; +const xml_token_t XML_disablePrompts = 1059; +const xml_token_t XML_disableRefresh = 1060; +const xml_token_t XML_discretePr = 1061; +const xml_token_t XML_diskRevisions = 1062; +const xml_token_t XML_dispBlanksAs = 1063; +const xml_token_t XML_dispDef = 1064; +const xml_token_t XML_dispEq = 1065; +const xml_token_t XML_dispRSqr = 1066; +const xml_token_t XML_dispUnits = 1067; +const xml_token_t XML_dispUnitsLbl = 1068; +const xml_token_t XML_displacedByCustomXml = 1069; +const xml_token_t XML_display = 1070; +const xml_token_t XML_displayBackgroundShape = 1071; +const xml_token_t XML_displayFolder = 1072; +const xml_token_t XML_displayHangulFixedWidth = 1073; +const xml_token_t XML_displayHorizontalDrawingGridEvery = 1074; +const xml_token_t XML_displayName = 1075; +const xml_token_t XML_displayText = 1076; +const xml_token_t XML_displayVerticalDrawingGridEvery = 1077; +const xml_token_t XML_dissolve = 1078; +const xml_token_t XML_dist = 1079; +const xml_token_t XML_distB = 1080; +const xml_token_t XML_distL = 1081; +const xml_token_t XML_distR = 1082; +const xml_token_t XML_distT = 1083; +const xml_token_t XML_distance = 1084; +const xml_token_t XML_div = 1085; +const xml_token_t XML_divBdr = 1086; +const xml_token_t XML_divId = 1087; +const xml_token_t XML_divs = 1088; +const xml_token_t XML_divsChild = 1089; +const xml_token_t XML_dk1 = 1090; +const xml_token_t XML_dk2 = 1091; +const xml_token_t XML_dllVersion = 1092; +const xml_token_t XML_dm = 1093; +const xml_token_t XML_dn = 1094; +const xml_token_t XML_doNotAutoCompressPictures = 1095; +const xml_token_t XML_doNotAutofitConstrainedTables = 1096; +const xml_token_t XML_doNotBreakConstrainedForcedTable = 1097; +const xml_token_t XML_doNotBreakWrappedTables = 1098; +const xml_token_t XML_doNotDemarcateInvalidXml = 1099; +const xml_token_t XML_doNotDisplayPageBoundaries = 1100; +const xml_token_t XML_doNotEmbedSmartTags = 1101; +const xml_token_t XML_doNotExpandShiftReturn = 1102; +const xml_token_t XML_doNotHyphenateCaps = 1103; +const xml_token_t XML_doNotIncludeSubdocsInStats = 1104; +const xml_token_t XML_doNotLeaveBackslashAlone = 1105; +const xml_token_t XML_doNotOrganizeInFolder = 1106; +const xml_token_t XML_doNotRelyOnCSS = 1107; +const xml_token_t XML_doNotSaveAsSingleFile = 1108; +const xml_token_t XML_doNotShadeFormData = 1109; +const xml_token_t XML_doNotSnapToGridInCell = 1110; +const xml_token_t XML_doNotSuppressBlankLines = 1111; +const xml_token_t XML_doNotSuppressIndentation = 1112; +const xml_token_t XML_doNotSuppressParagraphBorders = 1113; +const xml_token_t XML_doNotTrackFormatting = 1114; +const xml_token_t XML_doNotTrackMoves = 1115; +const xml_token_t XML_doNotUseEastAsianBreakRules = 1116; +const xml_token_t XML_doNotUseHTMLParagraphAutoSpacing = 1117; +const xml_token_t XML_doNotUseIndentAsNumberingTabStop = 1118; +const xml_token_t XML_doNotUseLongFileNames = 1119; +const xml_token_t XML_doNotUseMarginsForDrawingGridOrigin = 1120; +const xml_token_t XML_doNotValidateAgainstSchema = 1121; +const xml_token_t XML_doNotVertAlignCellWithSp = 1122; +const xml_token_t XML_doNotVertAlignInTxbx = 1123; +const xml_token_t XML_doNotWrapTextWithPunct = 1124; +const xml_token_t XML_docDefaults = 1125; +const xml_token_t XML_docGrid = 1126; +const xml_token_t XML_docLocation = 1127; +const xml_token_t XML_docPart = 1128; +const xml_token_t XML_docPartBody = 1129; +const xml_token_t XML_docPartCategory = 1130; +const xml_token_t XML_docPartGallery = 1131; +const xml_token_t XML_docPartList = 1132; +const xml_token_t XML_docPartObj = 1133; +const xml_token_t XML_docPartPr = 1134; +const xml_token_t XML_docPartUnique = 1135; +const xml_token_t XML_docParts = 1136; +const xml_token_t XML_docPr = 1137; +const xml_token_t XML_docVar = 1138; +const xml_token_t XML_docVars = 1139; +const xml_token_t XML_document = 1140; +const xml_token_t XML_documentProtection = 1141; +const xml_token_t XML_documentType = 1142; +const xml_token_t XML_double = 1143; +const xml_token_t XML_doubleclicknotify = 1144; +const xml_token_t XML_doughnutChart = 1145; +const xml_token_t XML_downBars = 1146; +const xml_token_t XML_dpi = 1147; +const xml_token_t XML_dr = 1148; +const xml_token_t XML_draft = 1149; +const xml_token_t XML_dragOff = 1150; +const xml_token_t XML_dragToCol = 1151; +const xml_token_t XML_dragToData = 1152; +const xml_token_t XML_dragToPage = 1153; +const xml_token_t XML_dragToRow = 1154; +const xml_token_t XML_drawing = 1155; +const xml_token_t XML_drawingGridHorizontalOrigin = 1156; +const xml_token_t XML_drawingGridHorizontalSpacing = 1157; +const xml_token_t XML_drawingGridVerticalOrigin = 1158; +const xml_token_t XML_drawingGridVerticalSpacing = 1159; +const xml_token_t XML_drop = 1160; +const xml_token_t XML_dropCap = 1161; +const xml_token_t XML_dropDownList = 1162; +const xml_token_t XML_dropLines = 1163; +const xml_token_t XML_dropauto = 1164; +const xml_token_t XML_ds = 1165; +const xml_token_t XML_dstrike = 1166; +const xml_token_t XML_dt = 1167; +const xml_token_t XML_dt2D = 1168; +const xml_token_t XML_dtr = 1169; +const xml_token_t XML_duotone = 1170; +const xml_token_t XML_dur = 1171; +const xml_token_t XML_dvAspect = 1172; +const xml_token_t XML_dx = 1173; +const xml_token_t XML_dxaOrig = 1174; +const xml_token_t XML_dxf = 1175; +const xml_token_t XML_dxfId = 1176; +const xml_token_t XML_dxfs = 1177; +const xml_token_t XML_dy = 1178; +const xml_token_t XML_dyaOrig = 1179; +const xml_token_t XML_dynamicAddress = 1180; +const xml_token_t XML_dynamicFilter = 1181; +const xml_token_t XML_dz = 1182; +const xml_token_t XML_e = 1183; +const xml_token_t XML_ea = 1184; +const xml_token_t XML_eaLnBrk = 1185; +const xml_token_t XML_eastAsia = 1186; +const xml_token_t XML_eastAsiaTheme = 1187; +const xml_token_t XML_eastAsianLayout = 1188; +const xml_token_t XML_eb = 1189; +const xml_token_t XML_ed = 1190; +const xml_token_t XML_edGrp = 1191; +const xml_token_t XML_edge = 1192; +const xml_token_t XML_edit = 1193; +const xml_token_t XML_editAs = 1194; +const xml_token_t XML_editData = 1195; +const xml_token_t XML_editPage = 1196; +const xml_token_t XML_editas = 1197; +const xml_token_t XML_edited = 1198; +const xml_token_t XML_effect = 1199; +const xml_token_t XML_effectClrLst = 1200; +const xml_token_t XML_effectDag = 1201; +const xml_token_t XML_effectExtent = 1202; +const xml_token_t XML_effectLst = 1203; +const xml_token_t XML_effectRef = 1204; +const xml_token_t XML_effectStyle = 1205; +const xml_token_t XML_effectStyleLst = 1206; +const xml_token_t XML_element = 1207; +const xml_token_t XML_else = 1208; +const xml_token_t XML_em = 1209; +const xml_token_t XML_embed = 1210; +const xml_token_t XML_embedBold = 1211; +const xml_token_t XML_embedBoldItalic = 1212; +const xml_token_t XML_embedItalic = 1213; +const xml_token_t XML_embedRegular = 1214; +const xml_token_t XML_embedSystemFonts = 1215; +const xml_token_t XML_embedTrueTypeFonts = 1216; +const xml_token_t XML_embeddedFont = 1217; +const xml_token_t XML_embeddedFontLst = 1218; +const xml_token_t XML_emboss = 1219; +const xml_token_t XML_embosscolor = 1220; +const xml_token_t XML_empty = 1221; +const xml_token_t XML_emptyCellReference = 1222; +const xml_token_t XML_enableDrill = 1223; +const xml_token_t XML_enableFieldProperties = 1224; +const xml_token_t XML_enableFormatConditionsCalculation = 1225; +const xml_token_t XML_enableRefresh = 1226; +const xml_token_t XML_enableWizard = 1227; +const xml_token_t XML_enabled = 1228; +const xml_token_t XML_encoding = 1229; +const xml_token_t XML_end = 1230; +const xml_token_t XML_endA = 1231; +const xml_token_t XML_endAngle = 1232; +const xml_token_t XML_endChr = 1233; +const xml_token_t XML_endCondLst = 1234; +const xml_token_t XML_endCxn = 1235; +const xml_token_t XML_endDate = 1236; +const xml_token_t XML_endNum = 1237; +const xml_token_t XML_endOfListFormulaUpdate = 1238; +const xml_token_t XML_endParaRPr = 1239; +const xml_token_t XML_endPos = 1240; +const xml_token_t XML_endSnd = 1241; +const xml_token_t XML_endSync = 1242; +const xml_token_t XML_endarrow = 1243; +const xml_token_t XML_endarrowlength = 1244; +const xml_token_t XML_endarrowwidth = 1245; +const xml_token_t XML_endcap = 1246; +const xml_token_t XML_endnote = 1247; +const xml_token_t XML_endnotePr = 1248; +const xml_token_t XML_endnoteRef = 1249; +const xml_token_t XML_endnoteReference = 1250; +const xml_token_t XML_endnotes = 1251; +const xml_token_t XML_enforcement = 1252; +const xml_token_t XML_entries = 1253; +const xml_token_t XML_entry = 1254; +const xml_token_t XML_entryMacro = 1255; +const xml_token_t XML_eol = 1256; +const xml_token_t XML_eqArr = 1257; +const xml_token_t XML_eqArrPr = 1258; +const xml_token_t XML_eqn = 1259; +const xml_token_t XML_equalAverage = 1260; +const xml_token_t XML_equalWidth = 1261; +const xml_token_t XML_equation = 1262; +const xml_token_t XML_equationxml = 1263; +const xml_token_t XML_err = 1264; +const xml_token_t XML_errBarType = 1265; +const xml_token_t XML_errBars = 1266; +const xml_token_t XML_errDir = 1267; +const xml_token_t XML_errValType = 1268; +const xml_token_t XML_error = 1269; +const xml_token_t XML_errorCaption = 1270; +const xml_token_t XML_errorStyle = 1271; +const xml_token_t XML_errorTitle = 1272; +const xml_token_t XML_errors = 1273; +const xml_token_t XML_evalError = 1274; +const xml_token_t XML_evalOrder = 1275; +const xml_token_t XML_evenAndOddHeaders = 1276; +const xml_token_t XML_evenFooter = 1277; +const xml_token_t XML_evenHeader = 1278; +const xml_token_t XML_evt = 1279; +const xml_token_t XML_evtFilter = 1280; +const xml_token_t XML_excl = 1281; +const xml_token_t XML_exclusive = 1282; +const xml_token_t XML_exitMacro = 1283; +const xml_token_t XML_exp = 1284; +const xml_token_t XML_explosion = 1285; +const xml_token_t XML_ext = 1286; +const xml_token_t XML_extLst = 1287; +const xml_token_t XML_extend = 1288; +const xml_token_t XML_extendable = 1289; +const xml_token_t XML_extent = 1290; +const xml_token_t XML_externalBook = 1291; +const xml_token_t XML_externalData = 1292; +const xml_token_t XML_externalLink = 1293; +const xml_token_t XML_externalReference = 1294; +const xml_token_t XML_externalReferences = 1295; +const xml_token_t XML_extraClrScheme = 1296; +const xml_token_t XML_extraClrSchemeLst = 1297; +const xml_token_t XML_extrusion = 1298; +const xml_token_t XML_extrusionClr = 1299; +const xml_token_t XML_extrusionH = 1300; +const xml_token_t XML_extrusionOk = 1301; +const xml_token_t XML_extrusioncolor = 1302; +const xml_token_t XML_extrusionok = 1303; +const xml_token_t XML_f = 1304; +const xml_token_t XML_fHdr = 1305; +const xml_token_t XML_fLocksText = 1306; +const xml_token_t XML_fLocksWithSheet = 1307; +const xml_token_t XML_fName = 1308; +const xml_token_t XML_fPr = 1309; +const xml_token_t XML_fPrintsWithSheet = 1310; +const xml_token_t XML_fPublished = 1311; +const xml_token_t XML_facet = 1312; +const xml_token_t XML_fact = 1313; +const xml_token_t XML_fade = 1314; +const xml_token_t XML_fadeDir = 1315; +const xml_token_t XML_family = 1316; +const xml_token_t XML_fc = 1317; +const xml_token_t XML_ffData = 1318; +const xml_token_t XML_fgClr = 1319; +const xml_token_t XML_fgColor = 1320; +const xml_token_t XML_fi = 1321; +const xml_token_t XML_field = 1322; +const xml_token_t XML_fieldGroup = 1323; +const xml_token_t XML_fieldId = 1324; +const xml_token_t XML_fieldIdWrapped = 1325; +const xml_token_t XML_fieldListSortAscending = 1326; +const xml_token_t XML_fieldMapData = 1327; +const xml_token_t XML_fieldPosition = 1328; +const xml_token_t XML_fieldPrintTitles = 1329; +const xml_token_t XML_fieldUsage = 1330; +const xml_token_t XML_fieldsUsage = 1331; +const xml_token_t XML_fileRecoveryPr = 1332; +const xml_token_t XML_fileSharing = 1333; +const xml_token_t XML_fileType = 1334; +const xml_token_t XML_fileVersion = 1335; +const xml_token_t XML_filetime = 1336; +const xml_token_t XML_fill = 1337; +const xml_token_t XML_fillClrLst = 1338; +const xml_token_t XML_fillFormulas = 1339; +const xml_token_t XML_fillId = 1340; +const xml_token_t XML_fillOverlay = 1341; +const xml_token_t XML_fillRect = 1342; +const xml_token_t XML_fillRef = 1343; +const xml_token_t XML_fillStyleLst = 1344; +const xml_token_t XML_fillToRect = 1345; +const xml_token_t XML_fillcolor = 1346; +const xml_token_t XML_filled = 1347; +const xml_token_t XML_fillok = 1348; +const xml_token_t XML_fills = 1349; +const xml_token_t XML_filltype = 1350; +const xml_token_t XML_filter = 1351; +const xml_token_t XML_filterColumn = 1352; +const xml_token_t XML_filterMode = 1353; +const xml_token_t XML_filterPrivacy = 1354; +const xml_token_t XML_filterUnique = 1355; +const xml_token_t XML_filterVal = 1356; +const xml_token_t XML_filters = 1357; +const xml_token_t XML_first = 1358; +const xml_token_t XML_firstBackgroundRefresh = 1359; +const xml_token_t XML_firstCol = 1360; +const xml_token_t XML_firstDataCol = 1361; +const xml_token_t XML_firstDataRow = 1362; +const xml_token_t XML_firstFooter = 1363; +const xml_token_t XML_firstHeader = 1364; +const xml_token_t XML_firstHeaderRow = 1365; +const xml_token_t XML_firstLine = 1366; +const xml_token_t XML_firstLineChars = 1367; +const xml_token_t XML_firstPageNumber = 1368; +const xml_token_t XML_firstRow = 1369; +const xml_token_t XML_firstSheet = 1370; +const xml_token_t XML_firstSliceAng = 1371; +const xml_token_t XML_firstSlideNum = 1372; +const xml_token_t XML_fitText = 1373; +const xml_token_t XML_fitToHeight = 1374; +const xml_token_t XML_fitToPage = 1375; +const xml_token_t XML_fitToWidth = 1376; +const xml_token_t XML_fitpath = 1377; +const xml_token_t XML_fitshape = 1378; +const xml_token_t XML_flatBorders = 1379; +const xml_token_t XML_flatTx = 1380; +const xml_token_t XML_fld = 1381; +const xml_token_t XML_fldChar = 1382; +const xml_token_t XML_fldCharType = 1383; +const xml_token_t XML_fldData = 1384; +const xml_token_t XML_fldLock = 1385; +const xml_token_t XML_fldSimple = 1386; +const xml_token_t XML_flip = 1387; +const xml_token_t XML_flipH = 1388; +const xml_token_t XML_flipV = 1389; +const xml_token_t XML_floor = 1390; +const xml_token_t XML_fltVal = 1391; +const xml_token_t XML_fmla = 1392; +const xml_token_t XML_fmt = 1393; +const xml_token_t XML_fmtId = 1394; +const xml_token_t XML_fmtScheme = 1395; +const xml_token_t XML_fmtid = 1396; +const xml_token_t XML_focus = 1397; +const xml_token_t XML_focusposition = 1398; +const xml_token_t XML_focussize = 1399; +const xml_token_t XML_folHlink = 1400; +const xml_token_t XML_followColorScheme = 1401; +const xml_token_t XML_followedHyperlink = 1402; +const xml_token_t XML_font = 1403; +const xml_token_t XML_fontAlgn = 1404; +const xml_token_t XML_fontId = 1405; +const xml_token_t XML_fontKey = 1406; +const xml_token_t XML_fontRef = 1407; +const xml_token_t XML_fontScale = 1408; +const xml_token_t XML_fontScheme = 1409; +const xml_token_t XML_fontSz = 1410; +const xml_token_t XML_fonts = 1411; +const xml_token_t XML_footer = 1412; +const xml_token_t XML_footerReference = 1413; +const xml_token_t XML_footnote = 1414; +const xml_token_t XML_footnoteLayoutLikeWW8 = 1415; +const xml_token_t XML_footnotePr = 1416; +const xml_token_t XML_footnoteRef = 1417; +const xml_token_t XML_footnoteReference = 1418; +const xml_token_t XML_footnotes = 1419; +const xml_token_t XML_for = 1420; +const xml_token_t XML_forEach = 1421; +const xml_token_t XML_forName = 1422; +const xml_token_t XML_forceAA = 1423; +const xml_token_t XML_forceFullCalc = 1424; +const xml_token_t XML_forceUpgrade = 1425; +const xml_token_t XML_forcedash = 1426; +const xml_token_t XML_foredepth = 1427; +const xml_token_t XML_forgetLastTabAlignment = 1428; +const xml_token_t XML_formProt = 1429; +const xml_token_t XML_format = 1430; +const xml_token_t XML_formatCells = 1431; +const xml_token_t XML_formatCode = 1432; +const xml_token_t XML_formatColumns = 1433; +const xml_token_t XML_formatRows = 1434; +const xml_token_t XML_formats = 1435; +const xml_token_t XML_formatting = 1436; +const xml_token_t XML_formsDesign = 1437; +const xml_token_t XML_formula = 1438; +const xml_token_t XML_formula1 = 1439; +const xml_token_t XML_formula2 = 1440; +const xml_token_t XML_formulaRange = 1441; +const xml_token_t XML_formulas = 1442; +const xml_token_t XML_forward = 1443; +const xml_token_t XML_fov = 1444; +const xml_token_t XML_frame = 1445; +const xml_token_t XML_frameLayout = 1446; +const xml_token_t XML_framePr = 1447; +const xml_token_t XML_frameSlides = 1448; +const xml_token_t XML_frameset = 1449; +const xml_token_t XML_framesetSplitbar = 1450; +const xml_token_t XML_from = 1451; +const xml_token_t XML_fromWordArt = 1452; +const xml_token_t XML_ftr = 1453; +const xml_token_t XML_fullCalcOnLoad = 1454; +const xml_token_t XML_fullDate = 1455; +const xml_token_t XML_fullPrecision = 1456; +const xml_token_t XML_fullScrn = 1457; +const xml_token_t XML_func = 1458; +const xml_token_t XML_funcPr = 1459; +const xml_token_t XML_function = 1460; +const xml_token_t XML_functionGroup = 1461; +const xml_token_t XML_functionGroupId = 1462; +const xml_token_t XML_functionGroups = 1463; +const xml_token_t XML_futureMetadata = 1464; +const xml_token_t XML_g = 1465; +const xml_token_t XML_gain = 1466; +const xml_token_t XML_gallery = 1467; +const xml_token_t XML_gamma = 1468; +const xml_token_t XML_gap = 1469; +const xml_token_t XML_gapDepth = 1470; +const xml_token_t XML_gapWidth = 1471; +const xml_token_t XML_gd = 1472; +const xml_token_t XML_gdLst = 1473; +const xml_token_t XML_gdRefAng = 1474; +const xml_token_t XML_gdRefR = 1475; +const xml_token_t XML_gdRefX = 1476; +const xml_token_t XML_gdRefY = 1477; +const xml_token_t XML_gfxdata = 1478; +const xml_token_t XML_ghostCol = 1479; +const xml_token_t XML_ghostRow = 1480; +const xml_token_t XML_glossaryDocument = 1481; +const xml_token_t XML_glow = 1482; +const xml_token_t XML_goal = 1483; +const xml_token_t XML_gradFill = 1484; +const xml_token_t XML_gradientFill = 1485; +const xml_token_t XML_gradientshapeok = 1486; +const xml_token_t XML_grammar = 1487; +const xml_token_t XML_grandCol = 1488; +const xml_token_t XML_grandRow = 1489; +const xml_token_t XML_grandTotalCaption = 1490; +const xml_token_t XML_graphic = 1491; +const xml_token_t XML_graphicData = 1492; +const xml_token_t XML_graphicEl = 1493; +const xml_token_t XML_graphicFrame = 1494; +const xml_token_t XML_graphicFrameLocks = 1495; +const xml_token_t XML_gray = 1496; +const xml_token_t XML_grayscale = 1497; +const xml_token_t XML_grayscl = 1498; +const xml_token_t XML_green = 1499; +const xml_token_t XML_greenMod = 1500; +const xml_token_t XML_greenOff = 1501; +const xml_token_t XML_gridAfter = 1502; +const xml_token_t XML_gridBefore = 1503; +const xml_token_t XML_gridCol = 1504; +const xml_token_t XML_gridDropZones = 1505; +const xml_token_t XML_gridLines = 1506; +const xml_token_t XML_gridLinesSet = 1507; +const xml_token_t XML_gridSpacing = 1508; +const xml_token_t XML_gridSpan = 1509; +const xml_token_t XML_group = 1510; +const xml_token_t XML_groupBy = 1511; +const xml_token_t XML_groupChr = 1512; +const xml_token_t XML_groupChrPr = 1513; +const xml_token_t XML_groupInterval = 1514; +const xml_token_t XML_groupItems = 1515; +const xml_token_t XML_groupLevel = 1516; +const xml_token_t XML_groupLevels = 1517; +const xml_token_t XML_groupMember = 1518; +const xml_token_t XML_groupMembers = 1519; +const xml_token_t XML_grouping = 1520; +const xml_token_t XML_groups = 1521; +const xml_token_t XML_grow = 1522; +const xml_token_t XML_growAutofit = 1523; +const xml_token_t XML_growShrinkType = 1524; +const xml_token_t XML_grpFill = 1525; +const xml_token_t XML_grpId = 1526; +const xml_token_t XML_grpSp = 1527; +const xml_token_t XML_grpSpLocks = 1528; +const xml_token_t XML_grpSpPr = 1529; +const xml_token_t XML_gs = 1530; +const xml_token_t XML_gsLst = 1531; +const xml_token_t XML_gte = 1532; +const xml_token_t XML_guid = 1533; +const xml_token_t XML_guide = 1534; +const xml_token_t XML_guideLst = 1535; +const xml_token_t XML_gutter = 1536; +const xml_token_t XML_gutterAtTop = 1537; +const xml_token_t XML_h = 1538; +const xml_token_t XML_hAnchor = 1539; +const xml_token_t XML_hAnsi = 1540; +const xml_token_t XML_hAnsiTheme = 1541; +const xml_token_t XML_hMerge = 1542; +const xml_token_t XML_hMode = 1543; +const xml_token_t XML_hPercent = 1544; +const xml_token_t XML_hR = 1545; +const xml_token_t XML_hRule = 1546; +const xml_token_t XML_hSpace = 1547; +const xml_token_t XML_handles = 1548; +const xml_token_t XML_handoutMaster = 1549; +const xml_token_t XML_handoutMasterId = 1550; +const xml_token_t XML_handoutMasterIdLst = 1551; +const xml_token_t XML_hanging = 1552; +const xml_token_t XML_hangingChars = 1553; +const xml_token_t XML_hangingPunct = 1554; +const xml_token_t XML_hasCustomPrompt = 1555; +const xml_token_t XML_hash = 1556; +const xml_token_t XML_hashData = 1557; +const xml_token_t XML_hdr = 1558; +const xml_token_t XML_hdrShapeDefaults = 1559; +const xml_token_t XML_headEnd = 1560; +const xml_token_t XML_header = 1561; +const xml_token_t XML_headerFooter = 1562; +const xml_token_t XML_headerReference = 1563; +const xml_token_t XML_headerRowBorderDxfId = 1564; +const xml_token_t XML_headerRowCellStyle = 1565; +const xml_token_t XML_headerRowCount = 1566; +const xml_token_t XML_headerRowDxfId = 1567; +const xml_token_t XML_headerSource = 1568; +const xml_token_t XML_headers = 1569; +const xml_token_t XML_headersInLastRefresh = 1570; +const xml_token_t XML_heading = 1571; +const xml_token_t XML_headings = 1572; +const xml_token_t XML_help = 1573; +const xml_token_t XML_helpText = 1574; +const xml_token_t XML_hf = 1575; +const xml_token_t XML_hiLowLines = 1576; +const xml_token_t XML_hidden = 1577; +const xml_token_t XML_hiddenButton = 1578; +const xml_token_t XML_hiddenColumn = 1579; +const xml_token_t XML_hiddenColumns = 1580; +const xml_token_t XML_hiddenLevel = 1581; +const xml_token_t XML_hiddenRow = 1582; +const xml_token_t XML_hiddenRows = 1583; +const xml_token_t XML_hiddenSlides = 1584; +const xml_token_t XML_hideBot = 1585; +const xml_token_t XML_hideGeom = 1586; +const xml_token_t XML_hideGrammaticalErrors = 1587; +const xml_token_t XML_hideLastTrans = 1588; +const xml_token_t XML_hideLeft = 1589; +const xml_token_t XML_hideMark = 1590; +const xml_token_t XML_hideNewItems = 1591; +const xml_token_t XML_hidePivotFieldList = 1592; +const xml_token_t XML_hideRight = 1593; +const xml_token_t XML_hideSpellingErrors = 1594; +const xml_token_t XML_hideTop = 1595; +const xml_token_t XML_hier = 1596; +const xml_token_t XML_hierBranch = 1597; +const xml_token_t XML_hierarchy = 1598; +const xml_token_t XML_hierarchyUsage = 1599; +const xml_token_t XML_highlight = 1600; +const xml_token_t XML_highlightClick = 1601; +const xml_token_t XML_hint = 1602; +const xml_token_t XML_history = 1603; +const xml_token_t XML_hlink = 1604; +const xml_token_t XML_hlinkClick = 1605; +const xml_token_t XML_hlinkHover = 1606; +const xml_token_t XML_hlinkMouseOver = 1607; +const xml_token_t XML_holeSize = 1608; +const xml_token_t XML_horizontal = 1609; +const xml_token_t XML_horizontalCentered = 1610; +const xml_token_t XML_horizontalDpi = 1611; +const xml_token_t XML_horzAnchor = 1612; +const xml_token_t XML_horzBarState = 1613; +const xml_token_t XML_horzOverflow = 1614; +const xml_token_t XML_hour = 1615; +const xml_token_t XML_how = 1616; +const xml_token_t XML_hps = 1617; +const xml_token_t XML_hpsBaseText = 1618; +const xml_token_t XML_hpsRaise = 1619; +const xml_token_t XML_hr = 1620; +const xml_token_t XML_hralign = 1621; +const xml_token_t XML_href = 1622; +const xml_token_t XML_hrnoshade = 1623; +const xml_token_t XML_hrpct = 1624; +const xml_token_t XML_hrstd = 1625; +const xml_token_t XML_hsl = 1626; +const xml_token_t XML_hslClr = 1627; +const xml_token_t XML_ht = 1628; +const xml_token_t XML_htmlFormat = 1629; +const xml_token_t XML_htmlPubPr = 1630; +const xml_token_t XML_htmlTables = 1631; +const xml_token_t XML_hue = 1632; +const xml_token_t XML_hueDir = 1633; +const xml_token_t XML_hueMod = 1634; +const xml_token_t XML_hueOff = 1635; +const xml_token_t XML_hyperlink = 1636; +const xml_token_t XML_hyperlinks = 1637; +const xml_token_t XML_hyphenationZone = 1638; +const xml_token_t XML_i = 1639; +const xml_token_t XML_i1 = 1640; +const xml_token_t XML_i2 = 1641; +const xml_token_t XML_i3 = 1642; +const xml_token_t XML_i4 = 1643; +const xml_token_t XML_i8 = 1644; +const xml_token_t XML_iCs = 1645; +const xml_token_t XML_iLevel = 1646; +const xml_token_t XML_iMeasureFld = 1647; +const xml_token_t XML_iMeasureHier = 1648; +const xml_token_t XML_icon = 1649; +const xml_token_t XML_iconFilter = 1650; +const xml_token_t XML_iconId = 1651; +const xml_token_t XML_iconSet = 1652; +const xml_token_t XML_id = 1653; +const xml_token_t XML_idcntr = 1654; +const xml_token_t XML_iddest = 1655; +const xml_token_t XML_idmap = 1656; +const xml_token_t XML_idref = 1657; +const xml_token_t XML_idsrc = 1658; +const xml_token_t XML_idx = 1659; +const xml_token_t XML_if = 1660; +const xml_token_t XML_ignoreMixedContent = 1661; +const xml_token_t XML_ignoredError = 1662; +const xml_token_t XML_ignoredErrors = 1663; +const xml_token_t XML_ilvl = 1664; +const xml_token_t XML_image = 1665; +const xml_token_t XML_imagealignshape = 1666; +const xml_token_t XML_imageaspect = 1667; +const xml_token_t XML_imagedata = 1668; +const xml_token_t XML_imagesize = 1669; +const xml_token_t XML_imeMode = 1670; +const xml_token_t XML_imgH = 1671; +const xml_token_t XML_imgSz = 1672; +const xml_token_t XML_imgW = 1673; +const xml_token_t XML_immersive = 1674; +const xml_token_t XML_imprint = 1675; +const xml_token_t XML_in = 1676; +const xml_token_t XML_includeHiddenRowCol = 1677; +const xml_token_t XML_includeNewItemsInFilter = 1678; +const xml_token_t XML_includePrintSettings = 1679; +const xml_token_t XML_ind = 1680; +const xml_token_t XML_indent = 1681; +const xml_token_t XML_index = 1682; +const xml_token_t XML_indexed = 1683; +const xml_token_t XML_indexedColors = 1684; +const xml_token_t XML_initials = 1685; +const xml_token_t XML_ink = 1686; +const xml_token_t XML_inkAnnotations = 1687; +const xml_token_t XML_inkTgt = 1688; +const xml_token_t XML_inline = 1689; +const xml_token_t XML_innerShdw = 1690; +const xml_token_t XML_inputCells = 1691; +const xml_token_t XML_ins = 1692; +const xml_token_t XML_insDel = 1693; +const xml_token_t XML_insertBlankRow = 1694; +const xml_token_t XML_insertColumns = 1695; +const xml_token_t XML_insertHyperlinks = 1696; +const xml_token_t XML_insertPageBreak = 1697; +const xml_token_t XML_insertRow = 1698; +const xml_token_t XML_insertRowShift = 1699; +const xml_token_t XML_insertRows = 1700; +const xml_token_t XML_inset = 1701; +const xml_token_t XML_insetmode = 1702; +const xml_token_t XML_insetpen = 1703; +const xml_token_t XML_insetpenok = 1704; +const xml_token_t XML_insideH = 1705; +const xml_token_t XML_insideV = 1706; +const xml_token_t XML_instr = 1707; +const xml_token_t XML_instrText = 1708; +const xml_token_t XML_int = 1709; +const xml_token_t XML_intLim = 1710; +const xml_token_t XML_intVal = 1711; +const xml_token_t XML_integer = 1712; +const xml_token_t XML_interSp = 1713; +const xml_token_t XML_intercept = 1714; +const xml_token_t XML_intermediate = 1715; +const xml_token_t XML_interval = 1716; +const xml_token_t XML_intraSp = 1717; +const xml_token_t XML_inv = 1718; +const xml_token_t XML_invGamma = 1719; +const xml_token_t XML_invalEndChars = 1720; +const xml_token_t XML_invalStChars = 1721; +const xml_token_t XML_invalid = 1722; +const xml_token_t XML_invalidUrl = 1723; +const xml_token_t XML_invertIfNegative = 1724; +const xml_token_t XML_invx = 1725; +const xml_token_t XML_invy = 1726; +const xml_token_t XML_is = 1727; +const xml_token_t XML_isLgl = 1728; +const xml_token_t XML_isNarration = 1729; +const xml_token_t XML_isPhoto = 1730; +const xml_token_t XML_iscomment = 1731; +const xml_token_t XML_issignatureline = 1732; +const xml_token_t XML_italic = 1733; +const xml_token_t XML_item = 1734; +const xml_token_t XML_itemID = 1735; +const xml_token_t XML_itemPageCount = 1736; +const xml_token_t XML_itemPrintTitles = 1737; +const xml_token_t XML_items = 1738; +const xml_token_t XML_iterate = 1739; +const xml_token_t XML_iterateCount = 1740; +const xml_token_t XML_iterateDelta = 1741; +const xml_token_t XML_jc = 1742; +const xml_token_t XML_joinstyle = 1743; +const xml_token_t XML_justifyLastLine = 1744; +const xml_token_t XML_k = 1745; +const xml_token_t XML_keepAlive = 1746; +const xml_token_t XML_keepChangeHistory = 1747; +const xml_token_t XML_keepLines = 1748; +const xml_token_t XML_keepNext = 1749; +const xml_token_t XML_kern = 1750; +const xml_token_t XML_key = 1751; +const xml_token_t XML_keyAttribute = 1752; +const xml_token_t XML_kinsoku = 1753; +const xml_token_t XML_kiosk = 1754; +const xml_token_t XML_kpi = 1755; +const xml_token_t XML_kpis = 1756; +const xml_token_t XML_kumimoji = 1757; +const xml_token_t XML_kx = 1758; +const xml_token_t XML_ky = 1759; +const xml_token_t XML_l = 1760; +const xml_token_t XML_lBounds = 1761; +const xml_token_t XML_lIns = 1762; +const xml_token_t XML_lMargin = 1763; +const xml_token_t XML_label = 1764; +const xml_token_t XML_labelOnly = 1765; +const xml_token_t XML_lang = 1766; +const xml_token_t XML_lastClr = 1767; +const xml_token_t XML_lastCol = 1768; +const xml_token_t XML_lastEdited = 1769; +const xml_token_t XML_lastGuid = 1770; +const xml_token_t XML_lastIdx = 1771; +const xml_token_t XML_lastRenderedPageBreak = 1772; +const xml_token_t XML_lastRow = 1773; +const xml_token_t XML_lastValue = 1774; +const xml_token_t XML_lastView = 1775; +const xml_token_t XML_lat = 1776; +const xml_token_t XML_latentStyles = 1777; +const xml_token_t XML_latin = 1778; +const xml_token_t XML_latinLnBrk = 1779; +const xml_token_t XML_layout = 1780; +const xml_token_t XML_layoutDef = 1781; +const xml_token_t XML_layoutDefHdr = 1782; +const xml_token_t XML_layoutDefHdrLst = 1783; +const xml_token_t XML_layoutInCell = 1784; +const xml_token_t XML_layoutNode = 1785; +const xml_token_t XML_layoutRawTableWidth = 1786; +const xml_token_t XML_layoutTableRowsApart = 1787; +const xml_token_t XML_layoutTarget = 1788; +const xml_token_t XML_lblAlgn = 1789; +const xml_token_t XML_lblOffset = 1790; +const xml_token_t XML_leader = 1791; +const xml_token_t XML_leaderLines = 1792; +const xml_token_t XML_left = 1793; +const xml_token_t XML_leftChars = 1794; +const xml_token_t XML_leftFromText = 1795; +const xml_token_t XML_leftLabels = 1796; +const xml_token_t XML_legacy = 1797; +const xml_token_t XML_legacyDrawing = 1798; +const xml_token_t XML_legacyDrawingHF = 1799; +const xml_token_t XML_legacyIndent = 1800; +const xml_token_t XML_legacySpace = 1801; +const xml_token_t XML_legend = 1802; +const xml_token_t XML_legendEntry = 1803; +const xml_token_t XML_legendPos = 1804; +const xml_token_t XML_len = 1805; +const xml_token_t XML_length = 1806; +const xml_token_t XML_lengthspecified = 1807; +const xml_token_t XML_level = 1808; +const xml_token_t XML_lid = 1809; +const xml_token_t XML_lightRig = 1810; +const xml_token_t XML_lightface = 1811; +const xml_token_t XML_lightharsh = 1812; +const xml_token_t XML_lightharsh2 = 1813; +const xml_token_t XML_lightlevel = 1814; +const xml_token_t XML_lightlevel2 = 1815; +const xml_token_t XML_lightposition = 1816; +const xml_token_t XML_lightposition2 = 1817; +const xml_token_t XML_lim = 1818; +const xml_token_t XML_limLoc = 1819; +const xml_token_t XML_limLow = 1820; +const xml_token_t XML_limLowPr = 1821; +const xml_token_t XML_limUpp = 1822; +const xml_token_t XML_limUppPr = 1823; +const xml_token_t XML_limo = 1824; +const xml_token_t XML_lin = 1825; +const xml_token_t XML_linClrLst = 1826; +const xml_token_t XML_line = 1827; +const xml_token_t XML_line3DChart = 1828; +const xml_token_t XML_lineChart = 1829; +const xml_token_t XML_linePitch = 1830; +const xml_token_t XML_lineRule = 1831; +const xml_token_t XML_lineTo = 1832; +const xml_token_t XML_lineWrapLikeWord6 = 1833; +const xml_token_t XML_lines = 1834; +const xml_token_t XML_linestyle = 1835; +const xml_token_t XML_link = 1836; +const xml_token_t XML_linkStyles = 1837; +const xml_token_t XML_linkTarget = 1838; +const xml_token_t XML_linkToQuery = 1839; +const xml_token_t XML_linkedToFile = 1840; +const xml_token_t XML_listDataValidation = 1841; +const xml_token_t XML_listEntry = 1842; +const xml_token_t XML_listItem = 1843; +const xml_token_t XML_listSeparator = 1844; +const xml_token_t XML_lit = 1845; +const xml_token_t XML_lkTxEntry = 1846; +const xml_token_t XML_ln = 1847; +const xml_token_t XML_lnB = 1848; +const xml_token_t XML_lnBlToTr = 1849; +const xml_token_t XML_lnDef = 1850; +const xml_token_t XML_lnL = 1851; +const xml_token_t XML_lnNumType = 1852; +const xml_token_t XML_lnR = 1853; +const xml_token_t XML_lnRef = 1854; +const xml_token_t XML_lnSpc = 1855; +const xml_token_t XML_lnSpcReduction = 1856; +const xml_token_t XML_lnStyleLst = 1857; +const xml_token_t XML_lnT = 1858; +const xml_token_t XML_lnTlToBr = 1859; +const xml_token_t XML_lnTo = 1860; +const xml_token_t XML_lo = 1861; +const xml_token_t XML_loCatId = 1862; +const xml_token_t XML_loTypeId = 1863; +const xml_token_t XML_local = 1864; +const xml_token_t XML_localConnection = 1865; +const xml_token_t XML_localRefresh = 1866; +const xml_token_t XML_localSheetId = 1867; +const xml_token_t XML_location = 1868; +const xml_token_t XML_lock = 1869; +const xml_token_t XML_lockRevision = 1870; +const xml_token_t XML_lockStructure = 1871; +const xml_token_t XML_lockWindows = 1872; +const xml_token_t XML_locked = 1873; +const xml_token_t XML_lockedCanvas = 1874; +const xml_token_t XML_lockrotationcenter = 1875; +const xml_token_t XML_logBase = 1876; +const xml_token_t XML_lon = 1877; +const xml_token_t XML_longFileNames = 1878; +const xml_token_t XML_longText = 1879; +const xml_token_t XML_loop = 1880; +const xml_token_t XML_lowestEdited = 1881; +const xml_token_t XML_lpstr = 1882; +const xml_token_t XML_lpwstr = 1883; +const xml_token_t XML_lsdException = 1884; +const xml_token_t XML_lstStyle = 1885; +const xml_token_t XML_lt1 = 1886; +const xml_token_t XML_lt2 = 1887; +const xml_token_t XML_lum = 1888; +const xml_token_t XML_lumMod = 1889; +const xml_token_t XML_lumOff = 1890; +const xml_token_t XML_lvl = 1891; +const xml_token_t XML_lvl1pPr = 1892; +const xml_token_t XML_lvl2pPr = 1893; +const xml_token_t XML_lvl3pPr = 1894; +const xml_token_t XML_lvl4pPr = 1895; +const xml_token_t XML_lvl5pPr = 1896; +const xml_token_t XML_lvl6pPr = 1897; +const xml_token_t XML_lvl7pPr = 1898; +const xml_token_t XML_lvl8pPr = 1899; +const xml_token_t XML_lvl9pPr = 1900; +const xml_token_t XML_lvlJc = 1901; +const xml_token_t XML_lvlOverride = 1902; +const xml_token_t XML_lvlPicBulletId = 1903; +const xml_token_t XML_lvlRestart = 1904; +const xml_token_t XML_lvlText = 1905; +const xml_token_t XML_m = 1906; +const xml_token_t XML_mPr = 1907; +const xml_token_t XML_macro = 1908; +const xml_token_t XML_mailAsAttachment = 1909; +const xml_token_t XML_mailMerge = 1910; +const xml_token_t XML_mailSubject = 1911; +const xml_token_t XML_main = 1912; +const xml_token_t XML_mainDocumentType = 1913; +const xml_token_t XML_majorFont = 1914; +const xml_token_t XML_majorGridlines = 1915; +const xml_token_t XML_majorTickMark = 1916; +const xml_token_t XML_majorTimeUnit = 1917; +const xml_token_t XML_majorUnit = 1918; +const xml_token_t XML_man = 1919; +const xml_token_t XML_manifestLocation = 1920; +const xml_token_t XML_manualBreakCount = 1921; +const xml_token_t XML_manualLayout = 1922; +const xml_token_t XML_map = 1923; +const xml_token_t XML_mapId = 1924; +const xml_token_t XML_mappedName = 1925; +const xml_token_t XML_mappingCount = 1926; +const xml_token_t XML_maps = 1927; +const xml_token_t XML_marB = 1928; +const xml_token_t XML_marBottom = 1929; +const xml_token_t XML_marH = 1930; +const xml_token_t XML_marL = 1931; +const xml_token_t XML_marLeft = 1932; +const xml_token_t XML_marR = 1933; +const xml_token_t XML_marRight = 1934; +const xml_token_t XML_marT = 1935; +const xml_token_t XML_marTop = 1936; +const xml_token_t XML_marW = 1937; +const xml_token_t XML_marker = 1938; +const xml_token_t XML_markup = 1939; +const xml_token_t XML_master = 1940; +const xml_token_t XML_masterClrMapping = 1941; +const xml_token_t XML_masterRel = 1942; +const xml_token_t XML_matchSrc = 1943; +const xml_token_t XML_matchingName = 1944; +const xml_token_t XML_mathFont = 1945; +const xml_token_t XML_mathPr = 1946; +const xml_token_t XML_matrix = 1947; +const xml_token_t XML_max = 1948; +const xml_token_t XML_maxAng = 1949; +const xml_token_t XML_maxDate = 1950; +const xml_token_t XML_maxDist = 1951; +const xml_token_t XML_maxLength = 1952; +const xml_token_t XML_maxR = 1953; +const xml_token_t XML_maxRId = 1954; +const xml_token_t XML_maxRank = 1955; +const xml_token_t XML_maxSheetId = 1956; +const xml_token_t XML_maxSubtotal = 1957; +const xml_token_t XML_maxVal = 1958; +const xml_token_t XML_maxValue = 1959; +const xml_token_t XML_maxX = 1960; +const xml_token_t XML_maxY = 1961; +const xml_token_t XML_maximized = 1962; +const xml_token_t XML_mc = 1963; +const xml_token_t XML_mcJc = 1964; +const xml_token_t XML_mcPr = 1965; +const xml_token_t XML_mcs = 1966; +const xml_token_t XML_mdx = 1967; +const xml_token_t XML_mdxMetadata = 1968; +const xml_token_t XML_mdxSubqueries = 1969; +const xml_token_t XML_measure = 1970; +const xml_token_t XML_measureFilter = 1971; +const xml_token_t XML_measureGroup = 1972; +const xml_token_t XML_measureGroups = 1973; +const xml_token_t XML_measures = 1974; +const xml_token_t XML_member = 1975; +const xml_token_t XML_memberName = 1976; +const xml_token_t XML_memberPropertyField = 1977; +const xml_token_t XML_memberValueDatatype = 1978; +const xml_token_t XML_members = 1979; +const xml_token_t XML_merge = 1980; +const xml_token_t XML_mergeCell = 1981; +const xml_token_t XML_mergeCells = 1982; +const xml_token_t XML_mergeInterval = 1983; +const xml_token_t XML_mergeItem = 1984; +const xml_token_t XML_metadata = 1985; +const xml_token_t XML_metadataStrings = 1986; +const xml_token_t XML_metadataType = 1987; +const xml_token_t XML_metadataTypes = 1988; +const xml_token_t XML_metal = 1989; +const xml_token_t XML_meth = 1990; +const xml_token_t XML_method = 1991; +const xml_token_t XML_min = 1992; +const xml_token_t XML_minAng = 1993; +const xml_token_t XML_minDate = 1994; +const xml_token_t XML_minLength = 1995; +const xml_token_t XML_minR = 1996; +const xml_token_t XML_minRId = 1997; +const xml_token_t XML_minRefreshableVersion = 1998; +const xml_token_t XML_minSubtotal = 1999; +const xml_token_t XML_minSupportedVersion = 2000; +const xml_token_t XML_minValue = 2001; +const xml_token_t XML_minVer = 2002; +const xml_token_t XML_minX = 2003; +const xml_token_t XML_minY = 2004; +const xml_token_t XML_minimized = 2005; +const xml_token_t XML_minimumVersion = 2006; +const xml_token_t XML_minorFont = 2007; +const xml_token_t XML_minorGridlines = 2008; +const xml_token_t XML_minorTickMark = 2009; +const xml_token_t XML_minorTimeUnit = 2010; +const xml_token_t XML_minorUnit = 2011; +const xml_token_t XML_minus = 2012; +const xml_token_t XML_minusx = 2013; +const xml_token_t XML_minusy = 2014; +const xml_token_t XML_minute = 2015; +const xml_token_t XML_mirrorIndents = 2016; +const xml_token_t XML_mirrorMargins = 2017; +const xml_token_t XML_missingCaption = 2018; +const xml_token_t XML_missingItemsLimit = 2019; +const xml_token_t XML_miter = 2020; +const xml_token_t XML_miterlimit = 2021; +const xml_token_t XML_mod = 2022; +const xml_token_t XML_modelId = 2023; +const xml_token_t XML_modifyVerifier = 2024; +const xml_token_t XML_month = 2025; +const xml_token_t XML_monthLong = 2026; +const xml_token_t XML_monthShort = 2027; +const xml_token_t XML_moveFrom = 2028; +const xml_token_t XML_moveFromRangeEnd = 2029; +const xml_token_t XML_moveFromRangeStart = 2030; +const xml_token_t XML_moveTo = 2031; +const xml_token_t XML_moveToRangeEnd = 2032; +const xml_token_t XML_moveToRangeStart = 2033; +const xml_token_t XML_moveWith = 2034; +const xml_token_t XML_movie = 2035; +const xml_token_t XML_mp = 2036; +const xml_token_t XML_mpFld = 2037; +const xml_token_t XML_mpMap = 2038; +const xml_token_t XML_mps = 2039; +const xml_token_t XML_mr = 2040; +const xml_token_t XML_mruColors = 2041; +const xml_token_t XML_ms = 2042; +const xml_token_t XML_multiLevelType = 2043; +const xml_token_t XML_multiLine = 2044; +const xml_token_t XML_multiLvlStrCache = 2045; +const xml_token_t XML_multiLvlStrRef = 2046; +const xml_token_t XML_multipleFieldFilters = 2047; +const xml_token_t XML_multipleItemSelectionAllowed = 2048; +const xml_token_t XML_mute = 2049; +const xml_token_t XML_mwSmallCaps = 2050; +const xml_token_t XML_n = 2051; +const xml_token_t XML_name = 2052; +const xml_token_t XML_nameLen = 2053; +const xml_token_t XML_namespaceUri = 2054; +const xml_token_t XML_namespaceuri = 2055; +const xml_token_t XML_nary = 2056; +const xml_token_t XML_naryLim = 2057; +const xml_token_t XML_naryPr = 2058; +const xml_token_t XML_nc = 2059; +const xml_token_t XML_ndxf = 2060; +const xml_token_t XML_neCell = 2061; +const xml_token_t XML_new = 2062; +const xml_token_t XML_newLength = 2063; +const xml_token_t XML_newName = 2064; +const xml_token_t XML_newsflash = 2065; +const xml_token_t XML_next = 2066; +const xml_token_t XML_nextAc = 2067; +const xml_token_t XML_nextCondLst = 2068; +const xml_token_t XML_nextId = 2069; +const xml_token_t XML_nf = 2070; +const xml_token_t XML_nlCheck = 2071; +const xml_token_t XML_noAdjustHandles = 2072; +const xml_token_t XML_noAutofit = 2073; +const xml_token_t XML_noBorder = 2074; +const xml_token_t XML_noBreak = 2075; +const xml_token_t XML_noBreakHyphen = 2076; +const xml_token_t XML_noChangeArrowheads = 2077; +const xml_token_t XML_noChangeAspect = 2078; +const xml_token_t XML_noChangeShapeType = 2079; +const xml_token_t XML_noColumnBalance = 2080; +const xml_token_t XML_noCrop = 2081; +const xml_token_t XML_noDrilldown = 2082; +const xml_token_t XML_noEditPoints = 2083; +const xml_token_t XML_noEndCap = 2084; +const xml_token_t XML_noEndnote = 2085; +const xml_token_t XML_noExtraLineSpacing = 2086; +const xml_token_t XML_noFill = 2087; +const xml_token_t XML_noGrp = 2088; +const xml_token_t XML_noLabel = 2089; +const xml_token_t XML_noLeading = 2090; +const xml_token_t XML_noLineBreaksAfter = 2091; +const xml_token_t XML_noLineBreaksBefore = 2092; +const xml_token_t XML_noMove = 2093; +const xml_token_t XML_noMultiLvlLbl = 2094; +const xml_token_t XML_noProof = 2095; +const xml_token_t XML_noPunctuationKerning = 2096; +const xml_token_t XML_noResize = 2097; +const xml_token_t XML_noResizeAllowed = 2098; +const xml_token_t XML_noRot = 2099; +const xml_token_t XML_noSelect = 2100; +const xml_token_t XML_noSpaceRaiseLower = 2101; +const xml_token_t XML_noTabHangInd = 2102; +const xml_token_t XML_noTextEdit = 2103; +const xml_token_t XML_noUngrp = 2104; +const xml_token_t XML_noWrap = 2105; +const xml_token_t XML_nodePh = 2106; +const xml_token_t XML_nodeType = 2107; +const xml_token_t XML_nonAutoSortDefault = 2108; +const xml_token_t XML_nor = 2109; +const xml_token_t XML_norm = 2110; +const xml_token_t XML_normAutofit = 2111; +const xml_token_t XML_normalViewPr = 2112; +const xml_token_t XML_normalizeH = 2113; +const xml_token_t XML_notTrueType = 2114; +const xml_token_t XML_notes = 2115; +const xml_token_t XML_notesMaster = 2116; +const xml_token_t XML_notesMasterId = 2117; +const xml_token_t XML_notesMasterIdLst = 2118; +const xml_token_t XML_notesStyle = 2119; +const xml_token_t XML_notesSz = 2120; +const xml_token_t XML_notesTextViewPr = 2121; +const xml_token_t XML_notesViewPr = 2122; +const xml_token_t XML_np = 2123; +const xml_token_t XML_ns = 2124; +const xml_token_t XML_nsid = 2125; +const xml_token_t XML_null = 2126; +const xml_token_t XML_num = 2127; +const xml_token_t XML_numCache = 2128; +const xml_token_t XML_numCol = 2129; +const xml_token_t XML_numFmt = 2130; +const xml_token_t XML_numFmtId = 2131; +const xml_token_t XML_numFmts = 2132; +const xml_token_t XML_numId = 2133; +const xml_token_t XML_numIdMacAtCleanup = 2134; +const xml_token_t XML_numLit = 2135; +const xml_token_t XML_numPicBullet = 2136; +const xml_token_t XML_numPicBulletId = 2137; +const xml_token_t XML_numPr = 2138; +const xml_token_t XML_numRef = 2139; +const xml_token_t XML_numRestart = 2140; +const xml_token_t XML_numSld = 2141; +const xml_token_t XML_numStart = 2142; +const xml_token_t XML_numStyleLink = 2143; +const xml_token_t XML_numberStoredAsText = 2144; +const xml_token_t XML_numbering = 2145; +const xml_token_t XML_numberingChange = 2146; +const xml_token_t XML_nvCxnSpPr = 2147; +const xml_token_t XML_nvGraphicFramePr = 2148; +const xml_token_t XML_nvGrpSpPr = 2149; +const xml_token_t XML_nvPicPr = 2150; +const xml_token_t XML_nvPr = 2151; +const xml_token_t XML_nvSpPr = 2152; +const xml_token_t XML_nwCell = 2153; +const xml_token_t XML_o = 2154; +const xml_token_t XML_oMath = 2155; +const xml_token_t XML_oMathPara = 2156; +const xml_token_t XML_oMathParaPr = 2157; +const xml_token_t XML_objDist = 2158; +const xml_token_t XML_object = 2159; +const xml_token_t XML_objectDefaults = 2160; +const xml_token_t XML_objects = 2161; +const xml_token_t XML_oblob = 2162; +const xml_token_t XML_obscured = 2163; +const xml_token_t XML_oc = 2164; +const xml_token_t XML_odcFile = 2165; +const xml_token_t XML_oddFooter = 2166; +const xml_token_t XML_oddHeader = 2167; +const xml_token_t XML_odso = 2168; +const xml_token_t XML_odxf = 2169; +const xml_token_t XML_ofPieChart = 2170; +const xml_token_t XML_ofPieType = 2171; +const xml_token_t XML_off = 2172; +const xml_token_t XML_offset = 2173; +const xml_token_t XML_offset2 = 2174; +const xml_token_t XML_offsetFrom = 2175; +const xml_token_t XML_olapPr = 2176; +const xml_token_t XML_old = 2177; +const xml_token_t XML_oldComment = 2178; +const xml_token_t XML_oldCustomMenu = 2179; +const xml_token_t XML_oldDescription = 2180; +const xml_token_t XML_oldFormula = 2181; +const xml_token_t XML_oldFunction = 2182; +const xml_token_t XML_oldFunctionGroupId = 2183; +const xml_token_t XML_oldHelp = 2184; +const xml_token_t XML_oldHidden = 2185; +const xml_token_t XML_oldLength = 2186; +const xml_token_t XML_oldName = 2187; +const xml_token_t XML_oldPh = 2188; +const xml_token_t XML_oldQuotePrefix = 2189; +const xml_token_t XML_oldShortcutKey = 2190; +const xml_token_t XML_oldStatusBar = 2191; +const xml_token_t XML_ole = 2192; +const xml_token_t XML_oleChartEl = 2193; +const xml_token_t XML_oleItem = 2194; +const xml_token_t XML_oleItems = 2195; +const xml_token_t XML_oleLink = 2196; +const xml_token_t XML_oleObj = 2197; +const xml_token_t XML_oleObject = 2198; +const xml_token_t XML_oleObjects = 2199; +const xml_token_t XML_oleSize = 2200; +const xml_token_t XML_oleUpdate = 2201; +const xml_token_t XML_oleicon = 2202; +const xml_token_t XML_oleid = 2203; +const xml_token_t XML_on = 2204; +const xml_token_t XML_oneCellAnchor = 2205; +const xml_token_t XML_oneField = 2206; +const xml_token_t XML_oned = 2207; +const xml_token_t XML_onlySync = 2208; +const xml_token_t XML_onlyUseConnectionFile = 2209; +const xml_token_t XML_op = 2210; +const xml_token_t XML_opEmu = 2211; +const xml_token_t XML_opacity = 2212; +const xml_token_t XML_opacity2 = 2213; +const xml_token_t XML_operator = 2214; +const xml_token_t XML_optimizeForBrowser = 2215; +const xml_token_t XML_optimizeMemory = 2216; +const xml_token_t XML_order = 2217; +const xml_token_t XML_orgChart = 2218; +const xml_token_t XML_organizeInFolders = 2219; +const xml_token_t XML_orient = 2220; +const xml_token_t XML_orientation = 2221; +const xml_token_t XML_orientationangle = 2222; +const xml_token_t XML_origin = 2223; +const xml_token_t XML_original = 2224; +const xml_token_t XML_ostorage = 2225; +const xml_token_t XML_ostream = 2226; +const xml_token_t XML_other = 2227; +const xml_token_t XML_otherStyle = 2228; +const xml_token_t XML_outerShdw = 2229; +const xml_token_t XML_outline = 2230; +const xml_token_t XML_outlineData = 2231; +const xml_token_t XML_outlineLevel = 2232; +const xml_token_t XML_outlineLevelCol = 2233; +const xml_token_t XML_outlineLevelRow = 2234; +const xml_token_t XML_outlineLvl = 2235; +const xml_token_t XML_outlinePr = 2236; +const xml_token_t XML_outlineSymbols = 2237; +const xml_token_t XML_outlineViewPr = 2238; +const xml_token_t XML_oval = 2239; +const xml_token_t XML_overflowPunct = 2240; +const xml_token_t XML_overlap = 2241; +const xml_token_t XML_overlay = 2242; +const xml_token_t XML_override = 2243; +const xml_token_t XML_overrideClrMapping = 2244; +const xml_token_t XML_p = 2245; +const xml_token_t XML_pBdr = 2246; +const xml_token_t XML_pLen = 2247; +const xml_token_t XML_pPos = 2248; +const xml_token_t XML_pPr = 2249; +const xml_token_t XML_pPrChange = 2250; +const xml_token_t XML_pPrDefault = 2251; +const xml_token_t XML_pRg = 2252; +const xml_token_t XML_pStyle = 2253; +const xml_token_t XML_page = 2254; +const xml_token_t XML_pageBreakBefore = 2255; +const xml_token_t XML_pageField = 2256; +const xml_token_t XML_pageFields = 2257; +const xml_token_t XML_pageItem = 2258; +const xml_token_t XML_pageMargins = 2259; +const xml_token_t XML_pageOrder = 2260; +const xml_token_t XML_pageOverThenDown = 2261; +const xml_token_t XML_pageSetUpPr = 2262; +const xml_token_t XML_pageSetup = 2263; +const xml_token_t XML_pageStyle = 2264; +const xml_token_t XML_pageWrap = 2265; +const xml_token_t XML_pages = 2266; +const xml_token_t XML_pane = 2267; +const xml_token_t XML_panose = 2268; +const xml_token_t XML_panose1 = 2269; +const xml_token_t XML_paperSize = 2270; +const xml_token_t XML_paperSrc = 2271; +const xml_token_t XML_par = 2272; +const xml_token_t XML_parTransId = 2273; +const xml_token_t XML_param = 2274; +const xml_token_t XML_parameter = 2275; +const xml_token_t XML_parameterType = 2276; +const xml_token_t XML_parameters = 2277; +const xml_token_t XML_parent = 2278; +const xml_token_t XML_parentSet = 2279; +const xml_token_t XML_parsePre = 2280; +const xml_token_t XML_password = 2281; +const xml_token_t XML_pasteAll = 2282; +const xml_token_t XML_pasteBorders = 2283; +const xml_token_t XML_pasteColWidths = 2284; +const xml_token_t XML_pasteComments = 2285; +const xml_token_t XML_pasteDataValidation = 2286; +const xml_token_t XML_pasteFormats = 2287; +const xml_token_t XML_pasteFormulas = 2288; +const xml_token_t XML_pasteNumberFormats = 2289; +const xml_token_t XML_pasteValues = 2290; +const xml_token_t XML_path = 2291; +const xml_token_t XML_pathEditMode = 2292; +const xml_token_t XML_pathLst = 2293; +const xml_token_t XML_pattFill = 2294; +const xml_token_t XML_patternFill = 2295; +const xml_token_t XML_patternType = 2296; +const xml_token_t XML_penClr = 2297; +const xml_token_t XML_percent = 2298; +const xml_token_t XML_period = 2299; +const xml_token_t XML_permEnd = 2300; +const xml_token_t XML_permStart = 2301; +const xml_token_t XML_personal = 2302; +const xml_token_t XML_personalCompose = 2303; +const xml_token_t XML_personalReply = 2304; +const xml_token_t XML_personalView = 2305; +const xml_token_t XML_perspective = 2306; +const xml_token_t XML_pgBorders = 2307; +const xml_token_t XML_pgMar = 2308; +const xml_token_t XML_pgNum = 2309; +const xml_token_t XML_pgNumType = 2310; +const xml_token_t XML_pgSz = 2311; +const xml_token_t XML_ph = 2312; +const xml_token_t XML_phant = 2313; +const xml_token_t XML_phantPr = 2314; +const xml_token_t XML_phldr = 2315; +const xml_token_t XML_phldrT = 2316; +const xml_token_t XML_phonetic = 2317; +const xml_token_t XML_phoneticPr = 2318; +const xml_token_t XML_photoAlbum = 2319; +const xml_token_t XML_pic = 2320; +const xml_token_t XML_picLocks = 2321; +const xml_token_t XML_pict = 2322; +const xml_token_t XML_picture = 2323; +const xml_token_t XML_pictureFormat = 2324; +const xml_token_t XML_pictureOptions = 2325; +const xml_token_t XML_pictureStackUnit = 2326; +const xml_token_t XML_pid = 2327; +const xml_token_t XML_pie3DChart = 2328; +const xml_token_t XML_pieChart = 2329; +const xml_token_t XML_pitch = 2330; +const xml_token_t XML_pitchFamily = 2331; +const xml_token_t XML_pivot = 2332; +const xml_token_t XML_pivotArea = 2333; +const xml_token_t XML_pivotAreas = 2334; +const xml_token_t XML_pivotButton = 2335; +const xml_token_t XML_pivotCache = 2336; +const xml_token_t XML_pivotCacheDefinition = 2337; +const xml_token_t XML_pivotCacheRecords = 2338; +const xml_token_t XML_pivotCaches = 2339; +const xml_token_t XML_pivotField = 2340; +const xml_token_t XML_pivotFields = 2341; +const xml_token_t XML_pivotFmt = 2342; +const xml_token_t XML_pivotFmts = 2343; +const xml_token_t XML_pivotHierarchies = 2344; +const xml_token_t XML_pivotHierarchy = 2345; +const xml_token_t XML_pivotSelection = 2346; +const xml_token_t XML_pivotSource = 2347; +const xml_token_t XML_pivotTableDefinition = 2348; +const xml_token_t XML_pivotTableStyle = 2349; +const xml_token_t XML_pivotTableStyleInfo = 2350; +const xml_token_t XML_pivotTables = 2351; +const xml_token_t XML_pixelsPerInch = 2352; +const xml_token_t XML_placeholder = 2353; +const xml_token_t XML_plane = 2354; +const xml_token_t XML_plcHide = 2355; +const xml_token_t XML_plotArea = 2356; +const xml_token_t XML_plotVisOnly = 2357; +const xml_token_t XML_plus = 2358; +const xml_token_t XML_points = 2359; +const xml_token_t XML_polar = 2360; +const xml_token_t XML_polyline = 2361; +const xml_token_t XML_pos = 2362; +const xml_token_t XML_posOffset = 2363; +const xml_token_t XML_position = 2364; +const xml_token_t XML_positionH = 2365; +const xml_token_t XML_positionV = 2366; +const xml_token_t XML_post = 2367; +const xml_token_t XML_postSp = 2368; +const xml_token_t XML_prLst = 2369; +const xml_token_t XML_prSet = 2370; +const xml_token_t XML_preSp = 2371; +const xml_token_t XML_preferPic = 2372; +const xml_token_t XML_preferRelativeResize = 2373; +const xml_token_t XML_preferSingleView = 2374; +const xml_token_t XML_preferrelative = 2375; +const xml_token_t XML_prefixMappings = 2376; +const xml_token_t XML_presAssocID = 2377; +const xml_token_t XML_presId = 2378; +const xml_token_t XML_presLayoutVars = 2379; +const xml_token_t XML_presName = 2380; +const xml_token_t XML_presOf = 2381; +const xml_token_t XML_presStyleCnt = 2382; +const xml_token_t XML_presStyleIdx = 2383; +const xml_token_t XML_presStyleLbl = 2384; +const xml_token_t XML_present = 2385; +const xml_token_t XML_presentation = 2386; +const xml_token_t XML_presentationPr = 2387; +const xml_token_t XML_preserve = 2388; +const xml_token_t XML_preserveFormatting = 2389; +const xml_token_t XML_preserveHistory = 2390; +const xml_token_t XML_preserveSortFilterLayout = 2391; +const xml_token_t XML_presetClass = 2392; +const xml_token_t XML_presetID = 2393; +const xml_token_t XML_presetSubtype = 2394; +const xml_token_t XML_prevAc = 2395; +const xml_token_t XML_prevCondLst = 2396; +const xml_token_t XML_previousCol = 2397; +const xml_token_t XML_previousRow = 2398; +const xml_token_t XML_pri = 2399; +const xml_token_t XML_print = 2400; +const xml_token_t XML_printArea = 2401; +const xml_token_t XML_printBodyTextBeforeHeader = 2402; +const xml_token_t XML_printColBlack = 2403; +const xml_token_t XML_printDrill = 2404; +const xml_token_t XML_printFormsData = 2405; +const xml_token_t XML_printFractionalCharacterWidth = 2406; +const xml_token_t XML_printOptions = 2407; +const xml_token_t XML_printPostScriptOverText = 2408; +const xml_token_t XML_printSettings = 2409; +const xml_token_t XML_printTwoOnOne = 2410; +const xml_token_t XML_printerSettings = 2411; +const xml_token_t XML_priority = 2412; +const xml_token_t XML_prnPr = 2413; +const xml_token_t XML_prnWhat = 2414; +const xml_token_t XML_productSubtotal = 2415; +const xml_token_t XML_progId = 2416; +const xml_token_t XML_progress = 2417; +const xml_token_t XML_prompt = 2418; +const xml_token_t XML_promptTitle = 2419; +const xml_token_t XML_promptedSolutions = 2420; +const xml_token_t XML_proofErr = 2421; +const xml_token_t XML_proofState = 2422; +const xml_token_t XML_property = 2423; +const xml_token_t XML_propertyName = 2424; +const xml_token_t XML_protected = 2425; +const xml_token_t XML_protectedRange = 2426; +const xml_token_t XML_protectedRanges = 2427; +const xml_token_t XML_protection = 2428; +const xml_token_t XML_provid = 2429; +const xml_token_t XML_proxy = 2430; +const xml_token_t XML_prst = 2431; +const xml_token_t XML_prstClr = 2432; +const xml_token_t XML_prstDash = 2433; +const xml_token_t XML_prstGeom = 2434; +const xml_token_t XML_prstMaterial = 2435; +const xml_token_t XML_prstShdw = 2436; +const xml_token_t XML_prstTxWarp = 2437; +const xml_token_t XML_pt = 2438; +const xml_token_t XML_ptCount = 2439; +const xml_token_t XML_ptLst = 2440; +const xml_token_t XML_ptType = 2441; +const xml_token_t XML_ptab = 2442; +const xml_token_t XML_ptsTypes = 2443; +const xml_token_t XML_pubBrowser = 2444; +const xml_token_t XML_publishItems = 2445; +const xml_token_t XML_publishToServer = 2446; +const xml_token_t XML_published = 2447; +const xml_token_t XML_pull = 2448; +const xml_token_t XML_push = 2449; +const xml_token_t XML_qFormat = 2450; +const xml_token_t XML_qs = 2451; +const xml_token_t XML_qsCatId = 2452; +const xml_token_t XML_qsTypeId = 2453; +const xml_token_t XML_quadBezTo = 2454; +const xml_token_t XML_qualifier = 2455; +const xml_token_t XML_query = 2456; +const xml_token_t XML_queryCache = 2457; +const xml_token_t XML_queryFailed = 2458; +const xml_token_t XML_queryTable = 2459; +const xml_token_t XML_queryTableDeletedFields = 2460; +const xml_token_t XML_queryTableField = 2461; +const xml_token_t XML_queryTableFieldId = 2462; +const xml_token_t XML_queryTableFields = 2463; +const xml_token_t XML_queryTableRefresh = 2464; +const xml_token_t XML_quickTimeFile = 2465; +const xml_token_t XML_quotePrefix = 2466; +const xml_token_t XML_r = 2467; +const xml_token_t XML_r1 = 2468; +const xml_token_t XML_r2 = 2469; +const xml_token_t XML_r4 = 2470; +const xml_token_t XML_r8 = 2471; +const xml_token_t XML_rAng = 2472; +const xml_token_t XML_rAngAx = 2473; +const xml_token_t XML_rCtr = 2474; +const xml_token_t XML_rFont = 2475; +const xml_token_t XML_rFonts = 2476; +const xml_token_t XML_rId = 2477; +const xml_token_t XML_rIns = 2478; +const xml_token_t XML_rMargin = 2479; +const xml_token_t XML_rPh = 2480; +const xml_token_t XML_rPr = 2481; +const xml_token_t XML_rPrChange = 2482; +const xml_token_t XML_rPrDefault = 2483; +const xml_token_t XML_rSp = 2484; +const xml_token_t XML_rSpRule = 2485; +const xml_token_t XML_rStyle = 2486; +const xml_token_t XML_ra = 2487; +const xml_token_t XML_rad = 2488; +const xml_token_t XML_radPr = 2489; +const xml_token_t XML_radarChart = 2490; +const xml_token_t XML_radarStyle = 2491; +const xml_token_t XML_radiusrange = 2492; +const xml_token_t XML_raf = 2493; +const xml_token_t XML_random = 2494; +const xml_token_t XML_randomBar = 2495; +const xml_token_t XML_rangePr = 2496; +const xml_token_t XML_rangeSet = 2497; +const xml_token_t XML_rangeSets = 2498; +const xml_token_t XML_rank = 2499; +const xml_token_t XML_rankBy = 2500; +const xml_token_t XML_rc = 2501; +const xml_token_t XML_rcc = 2502; +const xml_token_t XML_rcft = 2503; +const xml_token_t XML_rcmt = 2504; +const xml_token_t XML_rctx = 2505; +const xml_token_t XML_rcv = 2506; +const xml_token_t XML_rdn = 2507; +const xml_token_t XML_readModeInkLockDown = 2508; +const xml_token_t XML_readOnlyRecommended = 2509; +const xml_token_t XML_readingOrder = 2510; +const xml_token_t XML_recipientData = 2511; +const xml_token_t XML_recipients = 2512; +const xml_token_t XML_recolor = 2513; +const xml_token_t XML_recolortarget = 2514; +const xml_token_t XML_recommended = 2515; +const xml_token_t XML_reconnectionMethod = 2516; +const xml_token_t XML_recordCount = 2517; +const xml_token_t XML_rect = 2518; +const xml_token_t XML_red = 2519; +const xml_token_t XML_redMod = 2520; +const xml_token_t XML_redOff = 2521; +const xml_token_t XML_ref = 2522; +const xml_token_t XML_ref3D = 2523; +const xml_token_t XML_refFor = 2524; +const xml_token_t XML_refForName = 2525; +const xml_token_t XML_refMode = 2526; +const xml_token_t XML_refPtType = 2527; +const xml_token_t XML_refType = 2528; +const xml_token_t XML_reference = 2529; +const xml_token_t XML_references = 2530; +const xml_token_t XML_refersTo = 2531; +const xml_token_t XML_reflection = 2532; +const xml_token_t XML_refreshAllConnections = 2533; +const xml_token_t XML_refreshError = 2534; +const xml_token_t XML_refreshOnChange = 2535; +const xml_token_t XML_refreshOnLoad = 2536; +const xml_token_t XML_refreshedBy = 2537; +const xml_token_t XML_refreshedDate = 2538; +const xml_token_t XML_refreshedVersion = 2539; +const xml_token_t XML_regroupid = 2540; +const xml_token_t XML_regrouptable = 2541; +const xml_token_t XML_regular = 2542; +const xml_token_t XML_rel = 2543; +const xml_token_t XML_relIds = 2544; +const xml_token_t XML_relOff = 2545; +const xml_token_t XML_relSizeAnchor = 2546; +const xml_token_t XML_relation = 2547; +const xml_token_t XML_relationtable = 2548; +const xml_token_t XML_relative = 2549; +const xml_token_t XML_relativeFrom = 2550; +const xml_token_t XML_relativeHeight = 2551; +const xml_token_t XML_relativeIndent = 2552; +const xml_token_t XML_relativeTo = 2553; +const xml_token_t XML_relid = 2554; +const xml_token_t XML_relyOnVML = 2555; +const xml_token_t XML_relyOnVml = 2556; +const xml_token_t XML_removeDataOnSave = 2557; +const xml_token_t XML_removeDateAndTime = 2558; +const xml_token_t XML_removePersonalInfoOnSave = 2559; +const xml_token_t XML_removePersonalInformation = 2560; +const xml_token_t XML_render = 2561; +const xml_token_t XML_repairLoad = 2562; +const xml_token_t XML_repeatCount = 2563; +const xml_token_t XML_repeatDur = 2564; +const xml_token_t XML_resId = 2565; +const xml_token_t XML_reservationPassword = 2566; +const xml_token_t XML_resizeGraphics = 2567; +const xml_token_t XML_resizeHandles = 2568; +const xml_token_t XML_restart = 2569; +const xml_token_t XML_restoredLeft = 2570; +const xml_token_t XML_restoredTop = 2571; +const xml_token_t XML_result = 2572; +const xml_token_t XML_rev = 2573; +const xml_token_t XML_reverse = 2574; +const xml_token_t XML_reviewed = 2575; +const xml_token_t XML_reviewedList = 2576; +const xml_token_t XML_revisionId = 2577; +const xml_token_t XML_revisionView = 2578; +const xml_token_t XML_revisions = 2579; +const xml_token_t XML_revisionsPassword = 2580; +const xml_token_t XML_rfmt = 2581; +const xml_token_t XML_rgb = 2582; +const xml_token_t XML_rgbColor = 2583; +const xml_token_t XML_rich = 2584; +const xml_token_t XML_richText = 2585; +const xml_token_t XML_rig = 2586; +const xml_token_t XML_right = 2587; +const xml_token_t XML_rightChars = 2588; +const xml_token_t XML_rightFromText = 2589; +const xml_token_t XML_rightToLeft = 2590; +const xml_token_t XML_ris = 2591; +const xml_token_t XML_rm = 2592; +const xml_token_t XML_rot = 2593; +const xml_token_t XML_rotWithShape = 2594; +const xml_token_t XML_rotX = 2595; +const xml_token_t XML_rotY = 2596; +const xml_token_t XML_rotate = 2597; +const xml_token_t XML_rotation = 2598; +const xml_token_t XML_rotationangle = 2599; +const xml_token_t XML_rotationcenter = 2600; +const xml_token_t XML_round = 2601; +const xml_token_t XML_roundedCorners = 2602; +const xml_token_t XML_roundrect = 2603; +const xml_token_t XML_row = 2604; +const xml_token_t XML_rowBreaks = 2605; +const xml_token_t XML_rowColShift = 2606; +const xml_token_t XML_rowDrillCount = 2607; +const xml_token_t XML_rowFields = 2608; +const xml_token_t XML_rowGrandTotals = 2609; +const xml_token_t XML_rowHeaderCaption = 2610; +const xml_token_t XML_rowHierarchiesUsage = 2611; +const xml_token_t XML_rowHierarchyUsage = 2612; +const xml_token_t XML_rowItems = 2613; +const xml_token_t XML_rowNumbers = 2614; +const xml_token_t XML_rowOff = 2615; +const xml_token_t XML_rowPageCount = 2616; +const xml_token_t XML_rowSpan = 2617; +const xml_token_t XML_rows = 2618; +const xml_token_t XML_rqt = 2619; +const xml_token_t XML_rrc = 2620; +const xml_token_t XML_rsid = 2621; +const xml_token_t XML_rsidDel = 2622; +const xml_token_t XML_rsidP = 2623; +const xml_token_t XML_rsidR = 2624; +const xml_token_t XML_rsidRDefault = 2625; +const xml_token_t XML_rsidRPr = 2626; +const xml_token_t XML_rsidRoot = 2627; +const xml_token_t XML_rsidSect = 2628; +const xml_token_t XML_rsidTr = 2629; +const xml_token_t XML_rsids = 2630; +const xml_token_t XML_rsnm = 2631; +const xml_token_t XML_rt = 2632; +const xml_token_t XML_rtl = 2633; +const xml_token_t XML_rtlCol = 2634; +const xml_token_t XML_rtlGutter = 2635; +const xml_token_t XML_rtn = 2636; +const xml_token_t XML_ruby = 2637; +const xml_token_t XML_rubyAlign = 2638; +const xml_token_t XML_rubyBase = 2639; +const xml_token_t XML_rubyPr = 2640; +const xml_token_t XML_rule = 2641; +const xml_token_t XML_ruleLst = 2642; +const xml_token_t XML_rules = 2643; +const xml_token_t XML_rupBuild = 2644; +const xml_token_t XML_s = 2645; +const xml_token_t XML_sId = 2646; +const xml_token_t XML_sPre = 2647; +const xml_token_t XML_sPrePr = 2648; +const xml_token_t XML_sSub = 2649; +const xml_token_t XML_sSubPr = 2650; +const xml_token_t XML_sSubSup = 2651; +const xml_token_t XML_sSubSupPr = 2652; +const xml_token_t XML_sSup = 2653; +const xml_token_t XML_sSupPr = 2654; +const xml_token_t XML_salt = 2655; +const xml_token_t XML_saltData = 2656; +const xml_token_t XML_sampData = 2657; +const xml_token_t XML_sat = 2658; +const xml_token_t XML_satMod = 2659; +const xml_token_t XML_satOff = 2660; +const xml_token_t XML_saveData = 2661; +const xml_token_t XML_saveExternalLinkValues = 2662; +const xml_token_t XML_saveFormsData = 2663; +const xml_token_t XML_saveInvalidXml = 2664; +const xml_token_t XML_savePassword = 2665; +const xml_token_t XML_savePreviewPicture = 2666; +const xml_token_t XML_saveSmartTagsAsXml = 2667; +const xml_token_t XML_saveSubsetFonts = 2668; +const xml_token_t XML_saveThroughXslt = 2669; +const xml_token_t XML_saveXmlDataOnly = 2670; +const xml_token_t XML_sb = 2671; +const xml_token_t XML_scale = 2672; +const xml_token_t XML_scaleToFitPaper = 2673; +const xml_token_t XML_scaleWithDoc = 2674; +const xml_token_t XML_scaled = 2675; +const xml_token_t XML_scaling = 2676; +const xml_token_t XML_scatterChart = 2677; +const xml_token_t XML_scatterStyle = 2678; +const xml_token_t XML_scenario = 2679; +const xml_token_t XML_scenarios = 2680; +const xml_token_t XML_scene3d = 2681; +const xml_token_t XML_schema = 2682; +const xml_token_t XML_schemaLibrary = 2683; +const xml_token_t XML_schemaLocation = 2684; +const xml_token_t XML_schemaRef = 2685; +const xml_token_t XML_schemaRefs = 2686; +const xml_token_t XML_scheme = 2687; +const xml_token_t XML_schemeClr = 2688; +const xml_token_t XML_scope = 2689; +const xml_token_t XML_scr = 2690; +const xml_token_t XML_scrgbClr = 2691; +const xml_token_t XML_script = 2692; +const xml_token_t XML_scrollbar = 2693; +const xml_token_t XML_sd = 2694; +const xml_token_t XML_sdt = 2695; +const xml_token_t XML_sdtContent = 2696; +const xml_token_t XML_sdtEndPr = 2697; +const xml_token_t XML_sdtPr = 2698; +const xml_token_t XML_seCell = 2699; +const xml_token_t XML_second = 2700; +const xml_token_t XML_secondPiePt = 2701; +const xml_token_t XML_secondPieSize = 2702; +const xml_token_t XML_sectPr = 2703; +const xml_token_t XML_sectPrChange = 2704; +const xml_token_t XML_securityDescriptor = 2705; +const xml_token_t XML_selectFldWithFirstOrLastChar = 2706; +const xml_token_t XML_selectLockedCells = 2707; +const xml_token_t XML_selectUnlockedCells = 2708; +const xml_token_t XML_selected = 2709; +const xml_token_t XML_selection = 2710; +const xml_token_t XML_semiHidden = 2711; +const xml_token_t XML_semicolon = 2712; +const xml_token_t XML_sendLocale = 2713; +const xml_token_t XML_sep = 2714; +const xml_token_t XML_sepChr = 2715; +const xml_token_t XML_separator = 2716; +const xml_token_t XML_seq = 2717; +const xml_token_t XML_ser = 2718; +const xml_token_t XML_serAx = 2719; +const xml_token_t XML_serLines = 2720; +const xml_token_t XML_series = 2721; +const xml_token_t XML_seriesIdx = 2722; +const xml_token_t XML_serverCommand = 2723; +const xml_token_t XML_serverField = 2724; +const xml_token_t XML_serverFill = 2725; +const xml_token_t XML_serverFont = 2726; +const xml_token_t XML_serverFontColor = 2727; +const xml_token_t XML_serverFormat = 2728; +const xml_token_t XML_serverFormats = 2729; +const xml_token_t XML_serverNumberFormat = 2730; +const xml_token_t XML_serverSldId = 2731; +const xml_token_t XML_serverSldModifiedTime = 2732; +const xml_token_t XML_serverZoom = 2733; +const xml_token_t XML_set = 2734; +const xml_token_t XML_setDefinition = 2735; +const xml_token_t XML_sets = 2736; +const xml_token_t XML_settings = 2737; +const xml_token_t XML_shade = 2738; +const xml_token_t XML_shadeToTitle = 2739; +const xml_token_t XML_shadow = 2740; +const xml_token_t XML_shadowcolor = 2741; +const xml_token_t XML_shadowok = 2742; +const xml_token_t XML_shape = 2743; +const xml_token_t XML_shapeDefaults = 2744; +const xml_token_t XML_shapeId = 2745; +const xml_token_t XML_shapeLayoutLikeWW8 = 2746; +const xml_token_t XML_shapedefaults = 2747; +const xml_token_t XML_shapeid = 2748; +const xml_token_t XML_shapelayout = 2749; +const xml_token_t XML_shapetype = 2750; +const xml_token_t XML_shared = 2751; +const xml_token_t XML_sharedItems = 2752; +const xml_token_t XML_shd = 2753; +const xml_token_t XML_sheet = 2754; +const xml_token_t XML_sheetCalcPr = 2755; +const xml_token_t XML_sheetData = 2756; +const xml_token_t XML_sheetDataSet = 2757; +const xml_token_t XML_sheetFormatPr = 2758; +const xml_token_t XML_sheetId = 2759; +const xml_token_t XML_sheetIdMap = 2760; +const xml_token_t XML_sheetName = 2761; +const xml_token_t XML_sheetNames = 2762; +const xml_token_t XML_sheetPosition = 2763; +const xml_token_t XML_sheetPr = 2764; +const xml_token_t XML_sheetProtection = 2765; +const xml_token_t XML_sheetView = 2766; +const xml_token_t XML_sheetViews = 2767; +const xml_token_t XML_sheets = 2768; +const xml_token_t XML_shininess = 2769; +const xml_token_t XML_shortcutKey = 2770; +const xml_token_t XML_show = 2771; +const xml_token_t XML_showAll = 2772; +const xml_token_t XML_showAnimation = 2773; +const xml_token_t XML_showAsCaption = 2774; +const xml_token_t XML_showAsIcon = 2775; +const xml_token_t XML_showAutoFilter = 2776; +const xml_token_t XML_showBorderUnselectedTables = 2777; +const xml_token_t XML_showBreaksInFrames = 2778; +const xml_token_t XML_showBubbleSize = 2779; +const xml_token_t XML_showButton = 2780; +const xml_token_t XML_showCalcMbrs = 2781; +const xml_token_t XML_showCaptions = 2782; +const xml_token_t XML_showCatName = 2783; +const xml_token_t XML_showCell = 2784; +const xml_token_t XML_showColHeaders = 2785; +const xml_token_t XML_showColStripes = 2786; +const xml_token_t XML_showColumnStripes = 2787; +const xml_token_t XML_showComments = 2788; +const xml_token_t XML_showDLblsOverMax = 2789; +const xml_token_t XML_showDataAs = 2790; +const xml_token_t XML_showDataDropDown = 2791; +const xml_token_t XML_showDataTips = 2792; +const xml_token_t XML_showDrill = 2793; +const xml_token_t XML_showDropDown = 2794; +const xml_token_t XML_showDropDowns = 2795; +const xml_token_t XML_showDropZones = 2796; +const xml_token_t XML_showEmptyCol = 2797; +const xml_token_t XML_showEmptyRow = 2798; +const xml_token_t XML_showEnvelope = 2799; +const xml_token_t XML_showError = 2800; +const xml_token_t XML_showErrorMessage = 2801; +const xml_token_t XML_showFirstColumn = 2802; +const xml_token_t XML_showFormatting = 2803; +const xml_token_t XML_showFormulaBar = 2804; +const xml_token_t XML_showFormulas = 2805; +const xml_token_t XML_showGridLines = 2806; +const xml_token_t XML_showGuides = 2807; +const xml_token_t XML_showHeader = 2808; +const xml_token_t XML_showHeaders = 2809; +const xml_token_t XML_showHorizontalScroll = 2810; +const xml_token_t XML_showHorzBorder = 2811; +const xml_token_t XML_showInFieldList = 2812; +const xml_token_t XML_showInkAnnotation = 2813; +const xml_token_t XML_showInputMessage = 2814; +const xml_token_t XML_showItems = 2815; +const xml_token_t XML_showKeys = 2816; +const xml_token_t XML_showLastColumn = 2817; +const xml_token_t XML_showLeaderLines = 2818; +const xml_token_t XML_showLegendKey = 2819; +const xml_token_t XML_showMasterPhAnim = 2820; +const xml_token_t XML_showMasterSp = 2821; +const xml_token_t XML_showMemberPropertyTips = 2822; +const xml_token_t XML_showMissing = 2823; +const xml_token_t XML_showMultipleLabel = 2824; +const xml_token_t XML_showNarration = 2825; +const xml_token_t XML_showNegBubbles = 2826; +const xml_token_t XML_showObjects = 2827; +const xml_token_t XML_showOutline = 2828; +const xml_token_t XML_showOutlineIcons = 2829; +const xml_token_t XML_showOutlineSymbols = 2830; +const xml_token_t XML_showPageBreaks = 2831; +const xml_token_t XML_showPercent = 2832; +const xml_token_t XML_showPivotChartFilter = 2833; +const xml_token_t XML_showPr = 2834; +const xml_token_t XML_showPropAsCaption = 2835; +const xml_token_t XML_showPropCell = 2836; +const xml_token_t XML_showPropTip = 2837; +const xml_token_t XML_showRowCol = 2838; +const xml_token_t XML_showRowColHeaders = 2839; +const xml_token_t XML_showRowHeaders = 2840; +const xml_token_t XML_showRowStripes = 2841; +const xml_token_t XML_showRuler = 2842; +const xml_token_t XML_showScrollbar = 2843; +const xml_token_t XML_showSerName = 2844; +const xml_token_t XML_showSheetTabs = 2845; +const xml_token_t XML_showSpeakerNotes = 2846; +const xml_token_t XML_showSpecialPlsOnTitleSld = 2847; +const xml_token_t XML_showStatusbar = 2848; +const xml_token_t XML_showTip = 2849; +const xml_token_t XML_showVal = 2850; +const xml_token_t XML_showValue = 2851; +const xml_token_t XML_showVertBorder = 2852; +const xml_token_t XML_showVerticalScroll = 2853; +const xml_token_t XML_showWhenStopped = 2854; +const xml_token_t XML_showWhiteSpace = 2855; +const xml_token_t XML_showXMLTags = 2856; +const xml_token_t XML_showZeros = 2857; +const xml_token_t XML_showingPlcHdr = 2858; +const xml_token_t XML_showsigndate = 2859; +const xml_token_t XML_shp = 2860; +const xml_token_t XML_shrinkToFit = 2861; +const xml_token_t XML_si = 2862; +const xml_token_t XML_sibTransId = 2863; +const xml_token_t XML_side = 2864; +const xml_token_t XML_sideWall = 2865; +const xml_token_t XML_sig = 2866; +const xml_token_t XML_signatureline = 2867; +const xml_token_t XML_signinginstructions = 2868; +const xml_token_t XML_signinginstructionsset = 2869; +const xml_token_t XML_sigprovurl = 2870; +const xml_token_t XML_simplePos = 2871; +const xml_token_t XML_singleSignOnId = 2872; +const xml_token_t XML_singleXmlCell = 2873; +const xml_token_t XML_singleXmlCells = 2874; +const xml_token_t XML_singleclick = 2875; +const xml_token_t XML_size = 2876; +const xml_token_t XML_sizeAuto = 2877; +const xml_token_t XML_sizeRepresents = 2878; +const xml_token_t XML_skew = 2879; +const xml_token_t XML_skewamt = 2880; +const xml_token_t XML_skewangle = 2881; +const xml_token_t XML_sld = 2882; +const xml_token_t XML_sldAll = 2883; +const xml_token_t XML_sldId = 2884; +const xml_token_t XML_sldIdLst = 2885; +const xml_token_t XML_sldLayout = 2886; +const xml_token_t XML_sldLayoutId = 2887; +const xml_token_t XML_sldLayoutIdLst = 2888; +const xml_token_t XML_sldLst = 2889; +const xml_token_t XML_sldMaster = 2890; +const xml_token_t XML_sldMasterId = 2891; +const xml_token_t XML_sldMasterIdLst = 2892; +const xml_token_t XML_sldNum = 2893; +const xml_token_t XML_sldRg = 2894; +const xml_token_t XML_sldSyncPr = 2895; +const xml_token_t XML_sldSz = 2896; +const xml_token_t XML_sldTgt = 2897; +const xml_token_t XML_slideViewPr = 2898; +const xml_token_t XML_smallCaps = 2899; +const xml_token_t XML_smallFrac = 2900; +const xml_token_t XML_smartTag = 2901; +const xml_token_t XML_smartTagPr = 2902; +const xml_token_t XML_smartTagType = 2903; +const xml_token_t XML_smartTagTypes = 2904; +const xml_token_t XML_smartTags = 2905; +const xml_token_t XML_smooth = 2906; +const xml_token_t XML_smtClean = 2907; +const xml_token_t XML_smtId = 2908; +const xml_token_t XML_snapToGrid = 2909; +const xml_token_t XML_snapToObjects = 2910; +const xml_token_t XML_snapVertSplitter = 2911; +const xml_token_t XML_snd = 2912; +const xml_token_t XML_sndAc = 2913; +const xml_token_t XML_sndTgt = 2914; +const xml_token_t XML_softEdge = 2915; +const xml_token_t XML_softHyphen = 2916; +const xml_token_t XML_solidFill = 2917; +const xml_token_t XML_solutionID = 2918; +const xml_token_t XML_solveOrder = 2919; +const xml_token_t XML_sort = 2920; +const xml_token_t XML_sortBy = 2921; +const xml_token_t XML_sortByTuple = 2922; +const xml_token_t XML_sortCondition = 2923; +const xml_token_t XML_sortMethod = 2924; +const xml_token_t XML_sortState = 2925; +const xml_token_t XML_sortType = 2926; +const xml_token_t XML_sorterViewPr = 2927; +const xml_token_t XML_source = 2928; +const xml_token_t XML_sourceData = 2929; +const xml_token_t XML_sourceFile = 2930; +const xml_token_t XML_sourceFileName = 2931; +const xml_token_t XML_sourceLinked = 2932; +const xml_token_t XML_sourceObject = 2933; +const xml_token_t XML_sourceRef = 2934; +const xml_token_t XML_sourceSheetId = 2935; +const xml_token_t XML_sourceType = 2936; +const xml_token_t XML_sp = 2937; +const xml_token_t XML_sp3d = 2938; +const xml_token_t XML_spAutoFit = 2939; +const xml_token_t XML_spDef = 2940; +const xml_token_t XML_spLocks = 2941; +const xml_token_t XML_spPr = 2942; +const xml_token_t XML_spTgt = 2943; +const xml_token_t XML_spTree = 2944; +const xml_token_t XML_space = 2945; +const xml_token_t XML_spaceForUL = 2946; +const xml_token_t XML_spacing = 2947; +const xml_token_t XML_spacingInWholePoints = 2948; +const xml_token_t XML_spans = 2949; +const xml_token_t XML_spc = 2950; +const xml_token_t XML_spcAft = 2951; +const xml_token_t XML_spcBef = 2952; +const xml_token_t XML_spcCol = 2953; +const xml_token_t XML_spcFirstLastPara = 2954; +const xml_token_t XML_spcPct = 2955; +const xml_token_t XML_spcPts = 2956; +const xml_token_t XML_spd = 2957; +const xml_token_t XML_specVanish = 2958; +const xml_token_t XML_specularity = 2959; +const xml_token_t XML_spelling = 2960; +const xml_token_t XML_spid = 2961; +const xml_token_t XML_spidmax = 2962; +const xml_token_t XML_spinCount = 2963; +const xml_token_t XML_split = 2964; +const xml_token_t XML_splitAll = 2965; +const xml_token_t XML_splitFirst = 2966; +const xml_token_t XML_splitPgBreakAndParaMark = 2967; +const xml_token_t XML_splitPos = 2968; +const xml_token_t XML_splitType = 2969; +const xml_token_t XML_spokes = 2970; +const xml_token_t XML_spt = 2971; +const xml_token_t XML_sqlType = 2972; +const xml_token_t XML_sqref = 2973; +const xml_token_t XML_src = 2974; +const xml_token_t XML_srcId = 2975; +const xml_token_t XML_srcOrd = 2976; +const xml_token_t XML_srcRect = 2977; +const xml_token_t XML_srgbClr = 2978; +const xml_token_t XML_sst = 2979; +const xml_token_t XML_st = 2980; +const xml_token_t XML_stA = 2981; +const xml_token_t XML_stAng = 2982; +const xml_token_t XML_stCondLst = 2983; +const xml_token_t XML_stCxn = 2984; +const xml_token_t XML_stPos = 2985; +const xml_token_t XML_stSnd = 2986; +const xml_token_t XML_start = 2987; +const xml_token_t XML_startAngle = 2988; +const xml_token_t XML_startAt = 2989; +const xml_token_t XML_startDate = 2990; +const xml_token_t XML_startNum = 2991; +const xml_token_t XML_startOverride = 2992; +const xml_token_t XML_startarrow = 2993; +const xml_token_t XML_startarrowlength = 2994; +const xml_token_t XML_startarrowwidth = 2995; +const xml_token_t XML_state = 2996; +const xml_token_t XML_status = 2997; +const xml_token_t XML_statusBar = 2998; +const xml_token_t XML_statusText = 2999; +const xml_token_t XML_stdDev = 3000; +const xml_token_t XML_stdDevPSubtotal = 3001; +const xml_token_t XML_stdDevSubtotal = 3002; +const xml_token_t XML_step = 3003; +const xml_token_t XML_stockChart = 3004; +const xml_token_t XML_stop = 3005; +const xml_token_t XML_stopIfTrue = 3006; +const xml_token_t XML_storage = 3007; +const xml_token_t XML_storeItemID = 3008; +const xml_token_t XML_storeMappedDataAs = 3009; +const xml_token_t XML_stp = 3010; +const xml_token_t XML_strCache = 3011; +const xml_token_t XML_strLit = 3012; +const xml_token_t XML_strRef = 3013; +const xml_token_t XML_strVal = 3014; +const xml_token_t XML_stream = 3015; +const xml_token_t XML_stretch = 3016; +const xml_token_t XML_strictFirstAndLastChars = 3017; +const xml_token_t XML_strike = 3018; +const xml_token_t XML_strikeBLTR = 3019; +const xml_token_t XML_strikeH = 3020; +const xml_token_t XML_strikeTLBR = 3021; +const xml_token_t XML_strikeV = 3022; +const xml_token_t XML_string = 3023; +const xml_token_t XML_stringValue1 = 3024; +const xml_token_t XML_stringValue2 = 3025; +const xml_token_t XML_strips = 3026; +const xml_token_t XML_stroke = 3027; +const xml_token_t XML_strokecolor = 3028; +const xml_token_t XML_stroked = 3029; +const xml_token_t XML_strokeok = 3030; +const xml_token_t XML_strokeweight = 3031; +const xml_token_t XML_sty = 3032; +const xml_token_t XML_style = 3033; +const xml_token_t XML_styleData = 3034; +const xml_token_t XML_styleDef = 3035; +const xml_token_t XML_styleDefHdr = 3036; +const xml_token_t XML_styleDefHdrLst = 3037; +const xml_token_t XML_styleId = 3038; +const xml_token_t XML_styleLbl = 3039; +const xml_token_t XML_styleLink = 3040; +const xml_token_t XML_styleLockQFSet = 3041; +const xml_token_t XML_styleLockTheme = 3042; +const xml_token_t XML_styleName = 3043; +const xml_token_t XML_stylePaneFormatFilter = 3044; +const xml_token_t XML_stylePaneSortMethod = 3045; +const xml_token_t XML_styleSheet = 3046; +const xml_token_t XML_styles = 3047; +const xml_token_t XML_sub = 3048; +const xml_token_t XML_subDoc = 3049; +const xml_token_t XML_subFontBySize = 3050; +const xml_token_t XML_subHide = 3051; +const xml_token_t XML_subSp = 3052; +const xml_token_t XML_subTnLst = 3053; +const xml_token_t XML_subsetted = 3054; +const xml_token_t XML_subtotal = 3055; +const xml_token_t XML_subtotalCaption = 3056; +const xml_token_t XML_subtotalHiddenItems = 3057; +const xml_token_t XML_subtotalTop = 3058; +const xml_token_t XML_suff = 3059; +const xml_token_t XML_suggestedsigner = 3060; +const xml_token_t XML_suggestedsigner2 = 3061; +const xml_token_t XML_suggestedsigneremail = 3062; +const xml_token_t XML_sumSubtotal = 3063; +const xml_token_t XML_summaryBelow = 3064; +const xml_token_t XML_summaryLength = 3065; +const xml_token_t XML_summaryRight = 3066; +const xml_token_t XML_sup = 3067; +const xml_token_t XML_supHide = 3068; +const xml_token_t XML_supportAdvancedDrill = 3069; +const xml_token_t XML_supportSubquery = 3070; +const xml_token_t XML_suppressAutoHyphens = 3071; +const xml_token_t XML_suppressBottomSpacing = 3072; +const xml_token_t XML_suppressLineNumbers = 3073; +const xml_token_t XML_suppressOverlap = 3074; +const xml_token_t XML_suppressSpBfAfterPgBrk = 3075; +const xml_token_t XML_suppressSpacingAtTopOfPage = 3076; +const xml_token_t XML_suppressTopSpacing = 3077; +const xml_token_t XML_suppressTopSpacingWP = 3078; +const xml_token_t XML_surface3DChart = 3079; +const xml_token_t XML_surfaceChart = 3080; +const xml_token_t XML_swAng = 3081; +const xml_token_t XML_swCell = 3082; +const xml_token_t XML_swapBordersFacingPages = 3083; +const xml_token_t XML_switch = 3084; +const xml_token_t XML_sx = 3085; +const xml_token_t XML_sy = 3086; +const xml_token_t XML_sym = 3087; +const xml_token_t XML_symbol = 3088; +const xml_token_t XML_syncBehavior = 3089; +const xml_token_t XML_syncHorizontal = 3090; +const xml_token_t XML_syncRef = 3091; +const xml_token_t XML_syncVertical = 3092; +const xml_token_t XML_sysClr = 3093; +const xml_token_t XML_sz = 3094; +const xml_token_t XML_szCs = 3095; +const xml_token_t XML_t = 3096; +const xml_token_t XML_t1 = 3097; +const xml_token_t XML_t2 = 3098; +const xml_token_t XML_tIns = 3099; +const xml_token_t XML_tab = 3100; +const xml_token_t XML_tabColor = 3101; +const xml_token_t XML_tabLst = 3102; +const xml_token_t XML_tabRatio = 3103; +const xml_token_t XML_tabSelected = 3104; +const xml_token_t XML_table = 3105; +const xml_token_t XML_tableBorderDxfId = 3106; +const xml_token_t XML_tableColumn = 3107; +const xml_token_t XML_tableColumnId = 3108; +const xml_token_t XML_tableColumns = 3109; +const xml_token_t XML_tablePart = 3110; +const xml_token_t XML_tableParts = 3111; +const xml_token_t XML_tableStyle = 3112; +const xml_token_t XML_tableStyleElement = 3113; +const xml_token_t XML_tableStyleId = 3114; +const xml_token_t XML_tableStyleInfo = 3115; +const xml_token_t XML_tableStyles = 3116; +const xml_token_t XML_tableType = 3117; +const xml_token_t XML_tablelimits = 3118; +const xml_token_t XML_tableproperties = 3119; +const xml_token_t XML_tables = 3120; +const xml_token_t XML_tabs = 3121; +const xml_token_t XML_tag = 3122; +const xml_token_t XML_tagLst = 3123; +const xml_token_t XML_tags = 3124; +const xml_token_t XML_tailEnd = 3125; +const xml_token_t XML_target = 3126; +const xml_token_t XML_targetScreenSize = 3127; +const xml_token_t XML_targetScreenSz = 3128; +const xml_token_t XML_targetscreensize = 3129; +const xml_token_t XML_tav = 3130; +const xml_token_t XML_tavLst = 3131; +const xml_token_t XML_tbl = 3132; +const xml_token_t XML_tblBg = 3133; +const xml_token_t XML_tblBorders = 3134; +const xml_token_t XML_tblCellMar = 3135; +const xml_token_t XML_tblCellSpacing = 3136; +const xml_token_t XML_tblGrid = 3137; +const xml_token_t XML_tblGridChange = 3138; +const xml_token_t XML_tblHeader = 3139; +const xml_token_t XML_tblInd = 3140; +const xml_token_t XML_tblLayout = 3141; +const xml_token_t XML_tblLook = 3142; +const xml_token_t XML_tblOverlap = 3143; +const xml_token_t XML_tblPr = 3144; +const xml_token_t XML_tblPrChange = 3145; +const xml_token_t XML_tblPrEx = 3146; +const xml_token_t XML_tblPrExChange = 3147; +const xml_token_t XML_tblStyle = 3148; +const xml_token_t XML_tblStyleColBandSize = 3149; +const xml_token_t XML_tblStyleLst = 3150; +const xml_token_t XML_tblStylePr = 3151; +const xml_token_t XML_tblStyleRowBandSize = 3152; +const xml_token_t XML_tblW = 3153; +const xml_token_t XML_tblpPr = 3154; +const xml_token_t XML_tblpX = 3155; +const xml_token_t XML_tblpXSpec = 3156; +const xml_token_t XML_tblpY = 3157; +const xml_token_t XML_tblpYSpec = 3158; +const xml_token_t XML_tc = 3159; +const xml_token_t XML_tcBdr = 3160; +const xml_token_t XML_tcBorders = 3161; +const xml_token_t XML_tcFitText = 3162; +const xml_token_t XML_tcMar = 3163; +const xml_token_t XML_tcPr = 3164; +const xml_token_t XML_tcPrChange = 3165; +const xml_token_t XML_tcStyle = 3166; +const xml_token_t XML_tcTxStyle = 3167; +const xml_token_t XML_tcW = 3168; +const xml_token_t XML_temporary = 3169; +const xml_token_t XML_tentative = 3170; +const xml_token_t XML_text = 3171; +const xml_token_t XML_textAlignment = 3172; +const xml_token_t XML_textDates = 3173; +const xml_token_t XML_textDirection = 3174; +const xml_token_t XML_textField = 3175; +const xml_token_t XML_textFields = 3176; +const xml_token_t XML_textInput = 3177; +const xml_token_t XML_textPr = 3178; +const xml_token_t XML_textRotation = 3179; +const xml_token_t XML_textborder = 3180; +const xml_token_t XML_textbox = 3181; +const xml_token_t XML_textboxTightWrap = 3182; +const xml_token_t XML_textboxrect = 3183; +const xml_token_t XML_textdata = 3184; +const xml_token_t XML_textlink = 3185; +const xml_token_t XML_textpath = 3186; +const xml_token_t XML_textpathok = 3187; +const xml_token_t XML_tgtEl = 3188; +const xml_token_t XML_tgtFrame = 3189; +const xml_token_t XML_theme = 3190; +const xml_token_t XML_themeColor = 3191; +const xml_token_t XML_themeElements = 3192; +const xml_token_t XML_themeFill = 3193; +const xml_token_t XML_themeFillShade = 3194; +const xml_token_t XML_themeFillTint = 3195; +const xml_token_t XML_themeFontLang = 3196; +const xml_token_t XML_themeManager = 3197; +const xml_token_t XML_themeOverride = 3198; +const xml_token_t XML_themeShade = 3199; +const xml_token_t XML_themeTint = 3200; +const xml_token_t XML_thickBot = 3201; +const xml_token_t XML_thickBottom = 3202; +const xml_token_t XML_thickTop = 3203; +const xml_token_t XML_thicket = 3204; +const xml_token_t XML_thickness = 3205; +const xml_token_t XML_thousands = 3206; +const xml_token_t XML_thresh = 3207; +const xml_token_t XML_thruBlk = 3208; +const xml_token_t XML_tickLblPos = 3209; +const xml_token_t XML_tickLblSkip = 3210; +const xml_token_t XML_tickMarkSkip = 3211; +const xml_token_t XML_tile = 3212; +const xml_token_t XML_tileRect = 3213; +const xml_token_t XML_time = 3214; +const xml_token_t XML_timePeriod = 3215; +const xml_token_t XML_timing = 3216; +const xml_token_t XML_tint = 3217; +const xml_token_t XML_title = 3218; +const xml_token_t XML_titlePg = 3219; +const xml_token_t XML_titleStyle = 3220; +const xml_token_t XML_tl2br = 3221; +const xml_token_t XML_tm = 3222; +const xml_token_t XML_tmAbs = 3223; +const xml_token_t XML_tmFilter = 3224; +const xml_token_t XML_tmPct = 3225; +const xml_token_t XML_tmpl = 3226; +const xml_token_t XML_tmplLst = 3227; +const xml_token_t XML_tn = 3228; +const xml_token_t XML_tnLst = 3229; +const xml_token_t XML_to = 3230; +const xml_token_t XML_tooltip = 3231; +const xml_token_t XML_top = 3232; +const xml_token_t XML_top10 = 3233; +const xml_token_t XML_topAutoShow = 3234; +const xml_token_t XML_topFromText = 3235; +const xml_token_t XML_topLabels = 3236; +const xml_token_t XML_topLeftCell = 3237; +const xml_token_t XML_topLinePunct = 3238; +const xml_token_t XML_totalsRowBorderDxfId = 3239; +const xml_token_t XML_totalsRowCellStyle = 3240; +const xml_token_t XML_totalsRowCount = 3241; +const xml_token_t XML_totalsRowDxfId = 3242; +const xml_token_t XML_totalsRowFormula = 3243; +const xml_token_t XML_totalsRowFunction = 3244; +const xml_token_t XML_totalsRowLabel = 3245; +const xml_token_t XML_totalsRowShown = 3246; +const xml_token_t XML_tp = 3247; +const xml_token_t XML_tpl = 3248; +const xml_token_t XML_tplc = 3249; +const xml_token_t XML_tpls = 3250; +const xml_token_t XML_tr = 3251; +const xml_token_t XML_tr2bl = 3252; +const xml_token_t XML_trHeight = 3253; +const xml_token_t XML_trPr = 3254; +const xml_token_t XML_trPrChange = 3255; +const xml_token_t XML_track = 3256; +const xml_token_t XML_trackRevisions = 3257; +const xml_token_t XML_transition = 3258; +const xml_token_t XML_transitionEntry = 3259; +const xml_token_t XML_transitionEvaluation = 3260; +const xml_token_t XML_transp = 3261; +const xml_token_t XML_trend = 3262; +const xml_token_t XML_trendline = 3263; +const xml_token_t XML_trendlineLbl = 3264; +const xml_token_t XML_trendlineType = 3265; +const xml_token_t XML_trim = 3266; +const xml_token_t XML_truncateFontHeightsLikeWP6 = 3267; +const xml_token_t XML_tupleCache = 3268; +const xml_token_t XML_twoCellAnchor = 3269; +const xml_token_t XML_twoDigitTextYear = 3270; +const xml_token_t XML_tx = 3271; +const xml_token_t XML_tx1 = 3272; +const xml_token_t XML_tx2 = 3273; +const xml_token_t XML_txBody = 3274; +const xml_token_t XML_txBox = 3275; +const xml_token_t XML_txDef = 3276; +const xml_token_t XML_txEffectClrLst = 3277; +const xml_token_t XML_txEl = 3278; +const xml_token_t XML_txFillClrLst = 3279; +const xml_token_t XML_txLinClrLst = 3280; +const xml_token_t XML_txPr = 3281; +const xml_token_t XML_txSp = 3282; +const xml_token_t XML_txStyles = 3283; +const xml_token_t XML_txbxContent = 3284; +const xml_token_t XML_ty = 3285; +const xml_token_t XML_type = 3286; +const xml_token_t XML_typeface = 3287; +const xml_token_t XML_types = 3288; +const xml_token_t XML_u = 3289; +const xml_token_t XML_uBounds = 3290; +const xml_token_t XML_uFill = 3291; +const xml_token_t XML_uFillTx = 3292; +const xml_token_t XML_uLn = 3293; +const xml_token_t XML_uLnTx = 3294; +const xml_token_t XML_ua = 3295; +const xml_token_t XML_udl = 3296; +const xml_token_t XML_ui1 = 3297; +const xml_token_t XML_ui2 = 3298; +const xml_token_t XML_ui4 = 3299; +const xml_token_t XML_ui8 = 3300; +const xml_token_t XML_uiCompat97To2003 = 3301; +const xml_token_t XML_uiExpand = 3302; +const xml_token_t XML_uiPriority = 3303; +const xml_token_t XML_uint = 3304; +const xml_token_t XML_ulTrailSpace = 3305; +const xml_token_t XML_un = 3306; +const xml_token_t XML_unbalanced = 3307; +const xml_token_t XML_unbalancedGroup = 3308; +const xml_token_t XML_unboundColumnsLeft = 3309; +const xml_token_t XML_unboundColumnsRight = 3310; +const xml_token_t XML_underlineTabInNumList = 3311; +const xml_token_t XML_undo = 3312; +const xml_token_t XML_undone = 3313; +const xml_token_t XML_ungrouping = 3314; +const xml_token_t XML_unhideWhenUsed = 3315; +const xml_token_t XML_uniqueCount = 3316; +const xml_token_t XML_uniqueId = 3317; +const xml_token_t XML_uniqueList = 3318; +const xml_token_t XML_uniqueMemberProperty = 3319; +const xml_token_t XML_uniqueName = 3320; +const xml_token_t XML_uniqueParent = 3321; +const xml_token_t XML_uniqueTag = 3322; +const xml_token_t XML_unlockedFormula = 3323; +const xml_token_t XML_up = 3324; +const xml_token_t XML_upBars = 3325; +const xml_token_t XML_upDownBars = 3326; +const xml_token_t XML_updateAutomatic = 3327; +const xml_token_t XML_updateFields = 3328; +const xml_token_t XML_updateLinks = 3329; +const xml_token_t XML_updatedVersion = 3330; +const xml_token_t XML_upgradeOnRefresh = 3331; +const xml_token_t XML_upright = 3332; +const xml_token_t XML_uri = 3333; +const xml_token_t XML_url = 3334; +const xml_token_t XML_usb0 = 3335; +const xml_token_t XML_usb1 = 3336; +const xml_token_t XML_usb2 = 3337; +const xml_token_t XML_usb3 = 3338; +const xml_token_t XML_useA = 3339; +const xml_token_t XML_useAltKinsokuLineBreakRules = 3340; +const xml_token_t XML_useAnsiKerningPairs = 3341; +const xml_token_t XML_useAutoFormatting = 3342; +const xml_token_t XML_useBgFill = 3343; +const xml_token_t XML_useDef = 3344; +const xml_token_t XML_useFELayout = 3345; +const xml_token_t XML_useFirstPageNumber = 3346; +const xml_token_t XML_useLongFilenames = 3347; +const xml_token_t XML_useNormalStyleForList = 3348; +const xml_token_t XML_usePrinterDefaults = 3349; +const xml_token_t XML_usePrinterMetrics = 3350; +const xml_token_t XML_useSingleBorderforContiguousCells = 3351; +const xml_token_t XML_useSpRect = 3352; +const xml_token_t XML_useTimings = 3353; +const xml_token_t XML_useWord2002TableStyleRules = 3354; +const xml_token_t XML_useWord97LineBreakRules = 3355; +const xml_token_t XML_useXSLTWhenSaving = 3356; +const xml_token_t XML_user = 3357; +const xml_token_t XML_userDrawn = 3358; +const xml_token_t XML_userInfo = 3359; +const xml_token_t XML_userInterface = 3360; +const xml_token_t XML_userName = 3361; +const xml_token_t XML_userShapes = 3362; +const xml_token_t XML_userdrawn = 3363; +const xml_token_t XML_userhidden = 3364; +const xml_token_t XML_users = 3365; +const xml_token_t XML_v = 3366; +const xml_token_t XML_vAlign = 3367; +const xml_token_t XML_vAnchor = 3368; +const xml_token_t XML_vMerge = 3369; +const xml_token_t XML_vMergeOrig = 3370; +const xml_token_t XML_vSpace = 3371; +const xml_token_t XML_vacatedStyle = 3372; +const xml_token_t XML_val = 3373; +const xml_token_t XML_valAx = 3374; +const xml_token_t XML_value = 3375; +const xml_token_t XML_valueMetadata = 3376; +const xml_token_t XML_valueType = 3377; +const xml_token_t XML_values = 3378; +const xml_token_t XML_vanish = 3379; +const xml_token_t XML_varLst = 3380; +const xml_token_t XML_varPSubtotal = 3381; +const xml_token_t XML_varScale = 3382; +const xml_token_t XML_varSubtotal = 3383; +const xml_token_t XML_variant = 3384; +const xml_token_t XML_varyColors = 3385; +const xml_token_t XML_vbProcedure = 3386; +const xml_token_t XML_vector = 3387; +const xml_token_t XML_vendorID = 3388; +const xml_token_t XML_version = 3389; +const xml_token_t XML_vert = 3390; +const xml_token_t XML_vertAlign = 3391; +const xml_token_t XML_vertAnchor = 3392; +const xml_token_t XML_vertBarState = 3393; +const xml_token_t XML_vertCompress = 3394; +const xml_token_t XML_vertJc = 3395; +const xml_token_t XML_vertOverflow = 3396; +const xml_token_t XML_vertical = 3397; +const xml_token_t XML_verticalCentered = 3398; +const xml_token_t XML_verticalDpi = 3399; +const xml_token_t XML_verticies = 3400; +const xml_token_t XML_video = 3401; +const xml_token_t XML_videoFile = 3402; +const xml_token_t XML_view = 3403; +const xml_token_t XML_view3D = 3404; +const xml_token_t XML_viewMergedData = 3405; +const xml_token_t XML_viewPr = 3406; +const xml_token_t XML_viewpoint = 3407; +const xml_token_t XML_viewpointorigin = 3408; +const xml_token_t XML_visibility = 3409; +const xml_token_t XML_visualTotals = 3410; +const xml_token_t XML_vm = 3411; +const xml_token_t XML_vml = 3412; +const xml_token_t XML_vocabulary = 3413; +const xml_token_t XML_vol = 3414; +const xml_token_t XML_volType = 3415; +const xml_token_t XML_volTypes = 3416; +const xml_token_t XML_vstream = 3417; +const xml_token_t XML_w = 3418; +const xml_token_t XML_wAfter = 3419; +const xml_token_t XML_wBefore = 3420; +const xml_token_t XML_wMode = 3421; +const xml_token_t XML_wR = 3422; +const xml_token_t XML_wavAudioFile = 3423; +const xml_token_t XML_webHidden = 3424; +const xml_token_t XML_webPr = 3425; +const xml_token_t XML_webPublishItem = 3426; +const xml_token_t XML_webPublishItems = 3427; +const xml_token_t XML_webPublishObject = 3428; +const xml_token_t XML_webPublishObjects = 3429; +const xml_token_t XML_webPublishing = 3430; +const xml_token_t XML_webSettings = 3431; +const xml_token_t XML_wedge = 3432; +const xml_token_t XML_weight = 3433; +const xml_token_t XML_wheel = 3434; +const xml_token_t XML_whole = 3435; +const xml_token_t XML_wholeTbl = 3436; +const xml_token_t XML_widowControl = 3437; +const xml_token_t XML_width = 3438; +const xml_token_t XML_windowHeight = 3439; +const xml_token_t XML_windowProtection = 3440; +const xml_token_t XML_windowWidth = 3441; +const xml_token_t XML_wipe = 3442; +const xml_token_t XML_wireframe = 3443; +const xml_token_t XML_wordWrap = 3444; +const xml_token_t XML_workbook = 3445; +const xml_token_t XML_workbookParameter = 3446; +const xml_token_t XML_workbookPassword = 3447; +const xml_token_t XML_workbookPr = 3448; +const xml_token_t XML_workbookProtection = 3449; +const xml_token_t XML_workbookView = 3450; +const xml_token_t XML_workbookViewId = 3451; +const xml_token_t XML_worksheet = 3452; +const xml_token_t XML_worksheetSource = 3453; +const xml_token_t XML_wpJustification = 3454; +const xml_token_t XML_wpSpaceWidth = 3455; +const xml_token_t XML_wrap = 3456; +const xml_token_t XML_wrapIndent = 3457; +const xml_token_t XML_wrapNone = 3458; +const xml_token_t XML_wrapPolygon = 3459; +const xml_token_t XML_wrapRight = 3460; +const xml_token_t XML_wrapSquare = 3461; +const xml_token_t XML_wrapText = 3462; +const xml_token_t XML_wrapThrough = 3463; +const xml_token_t XML_wrapTight = 3464; +const xml_token_t XML_wrapTopAndBottom = 3465; +const xml_token_t XML_wrapTrailSpaces = 3466; +const xml_token_t XML_wrapcoords = 3467; +const xml_token_t XML_writeProtection = 3468; +const xml_token_t XML_wsDr = 3469; +const xml_token_t XML_x = 3470; +const xml_token_t XML_xAlign = 3471; +const xml_token_t XML_xMode = 3472; +const xml_token_t XML_xSplit = 3473; +const xml_token_t XML_xVal = 3474; +const xml_token_t XML_xWindow = 3475; +const xml_token_t XML_xf = 3476; +const xml_token_t XML_xfDxf = 3477; +const xml_token_t XML_xfId = 3478; +const xml_token_t XML_xfrm = 3479; +const xml_token_t XML_xfrmType = 3480; +const xml_token_t XML_xl2000 = 3481; +const xml_token_t XML_xl97 = 3482; +const xml_token_t XML_xlm = 3483; +const xml_token_t XML_xml = 3484; +const xml_token_t XML_xmlBased = 3485; +const xml_token_t XML_xmlCellPr = 3486; +const xml_token_t XML_xmlColumnPr = 3487; +const xml_token_t XML_xmlDataType = 3488; +const xml_token_t XML_xmlPr = 3489; +const xml_token_t XML_xpath = 3490; +const xml_token_t XML_xrange = 3491; +const xml_token_t XML_xscale = 3492; +const xml_token_t XML_y = 3493; +const xml_token_t XML_yAlign = 3494; +const xml_token_t XML_yMode = 3495; +const xml_token_t XML_ySplit = 3496; +const xml_token_t XML_yVal = 3497; +const xml_token_t XML_yWindow = 3498; +const xml_token_t XML_year = 3499; +const xml_token_t XML_yearLong = 3500; +const xml_token_t XML_yearShort = 3501; +const xml_token_t XML_yrange = 3502; +const xml_token_t XML_z = 3503; +const xml_token_t XML_zOrder = 3504; +const xml_token_t XML_zOrderOff = 3505; +const xml_token_t XML_zeroAsc = 3506; +const xml_token_t XML_zeroDesc = 3507; +const xml_token_t XML_zeroHeight = 3508; +const xml_token_t XML_zeroValues = 3509; +const xml_token_t XML_zeroWid = 3510; +const xml_token_t XML_zoom = 3511; +const xml_token_t XML_zoomContents = 3512; +const xml_token_t XML_zoomScale = 3513; +const xml_token_t XML_zoomScaleNormal = 3514; +const xml_token_t XML_zoomScalePageLayoutView = 3515; +const xml_token_t XML_zoomScaleSheetLayoutView = 3516; +const xml_token_t XML_zoomToFit = 3517; diff --git a/src/liborcus/ooxml_tokens.cpp b/src/liborcus/ooxml_tokens.cpp new file mode 100644 index 0000000..f73a06c --- /dev/null +++ b/src/liborcus/ooxml_tokens.cpp @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ooxml_tokens.hpp" + +namespace orcus { + +namespace ooxml { + +#include "ooxml_tokens.inl" + +} + +namespace opc { + +#include "opc_tokens.inl" + +} + +tokens ooxml_tokens = tokens(ooxml::token_names, ooxml::token_name_count); + +tokens opc_tokens = tokens(opc::token_names, opc::token_name_count); + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ooxml_tokens.hpp b/src/liborcus/ooxml_tokens.hpp new file mode 100644 index 0000000..3e8380b --- /dev/null +++ b/src/liborcus/ooxml_tokens.hpp @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef __ORCUS_OOXML_TOKENS_HPP__ +#define __ORCUS_OOXML_TOKENS_HPP__ + +#include "orcus/tokens.hpp" + +namespace orcus { + +extern tokens ooxml_tokens; +extern tokens opc_tokens; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ooxml_tokens.inl b/src/liborcus/ooxml_tokens.inl new file mode 100644 index 0000000..5fa2ad0 --- /dev/null +++ b/src/liborcus/ooxml_tokens.inl @@ -0,0 +1,3524 @@ +// This file has been auto-generated. Do not hand-edit this. + +const char* token_names[] = { + "??", // 0 + "AbbreviatedCaseNumber", // 1 + "Accel", // 2 + "Accel2", // 3 + "AlbumTitle", // 4 + "AlternateContent", // 5 + "Anchor", // 6 + "AppVersion", // 7 + "Append", // 8 + "Application", // 9 + "Artist", // 10 + "Author", // 11 + "AutoFill", // 12 + "AutoFit", // 13 + "AutoLine", // 14 + "AutoPict", // 15 + "AutoScale", // 16 + "BookAuthor", // 17 + "BookTitle", // 18 + "BroadcastTitle", // 19 + "Broadcaster", // 20 + "CF", // 21 + "Camera", // 22 + "Cancel", // 23 + "CaseNumber", // 24 + "ChapterNumber", // 25 + "Characters", // 26 + "CharactersWithSpaces", // 27 + "Checked", // 28 + "Choice", // 29 + "City", // 30 + "ClientData", // 31 + "ColHidden", // 32 + "Colored", // 33 + "Column", // 34 + "Comments", // 35 + "Company", // 36 + "Compiler", // 37 + "Composer", // 38 + "Conductor", // 39 + "ConferenceName", // 40 + "ConnectionID", // 41 + "Corporate", // 42 + "Counsel", // 43 + "CountryRegion", // 44 + "Court", // 45 + "DDE", // 46 + "DataBinding", // 47 + "DataBindingLoadMode", // 48 + "DataBindingName", // 49 + "Day", // 50 + "DayAccessed", // 51 + "Default", // 52 + "DefaultSize", // 53 + "Department", // 54 + "DigSig", // 55 + "Director", // 56 + "Disabled", // 57 + "Dismiss", // 58 + "Distributor", // 59 + "DocSecurity", // 60 + "DrawAspect", // 61 + "DropLines", // 62 + "DropStyle", // 63 + "Dx", // 64 + "Edition", // 65 + "Editor", // 66 + "Fallback", // 67 + "FieldCodes", // 68 + "FileBinding", // 69 + "FileBindingName", // 70 + "First", // 71 + "FirstButton", // 72 + "FmlaGroup", // 73 + "FmlaLink", // 74 + "FmlaMacro", // 75 + "FmlaPict", // 76 + "FmlaRange", // 77 + "FmlaTxbx", // 78 + "Guid", // 79 + "HLinks", // 80 + "HeadingPairs", // 81 + "Help", // 82 + "HiddenSlides", // 83 + "Horiz", // 84 + "HyperlinkBase", // 85 + "HyperlinksChanged", // 86 + "ID", // 87 + "Inc", // 88 + "Institution", // 89 + "InternetSiteTitle", // 90 + "Interviewee", // 91 + "Interviewer", // 92 + "Inventor", // 93 + "Issue", // 94 + "JournalName", // 95 + "JustLastX", // 96 + "LCID", // 97 + "LCT", // 98 + "Last", // 99 + "Lines", // 100 + "LinkType", // 101 + "LinksUpToDate", // 102 + "ListItem", // 103 + "LockText", // 104 + "Locked", // 105 + "LockedField", // 106 + "MMClips", // 107 + "Manager", // 108 + "Map", // 109 + "MapInfo", // 110 + "MapOCX", // 111 + "Max", // 112 + "Medium", // 113 + "Middle", // 114 + "Min", // 115 + "Month", // 116 + "MonthAccessed", // 117 + "MoveWithCells", // 118 + "MultiLine", // 119 + "MultiSel", // 120 + "Name", // 121 + "NameList", // 122 + "Namespace", // 123 + "NoThreeD", // 124 + "NoThreeD2", // 125 + "Notes", // 126 + "NumberVolumes", // 127 + "OLEObject", // 128 + "ObjectID", // 129 + "ObjectType", // 130 + "Page", // 131 + "Pages", // 132 + "Paragraphs", // 133 + "PatentNumber", // 134 + "Performer", // 135 + "PeriodicalTitle", // 136 + "Person", // 137 + "PresentationFormat", // 138 + "PreserveFormat", // 139 + "PreserveSortAFLayout", // 140 + "PrintObject", // 141 + "ProducerName", // 142 + "ProductionCompany", // 143 + "ProgID", // 144 + "Properties", // 145 + "PublicationTitle", // 146 + "Publisher", // 147 + "RecalcAlways", // 148 + "RecordingNumber", // 149 + "RefOrder", // 150 + "Reporter", // 151 + "RootElement", // 152 + "Row", // 153 + "RowHidden", // 154 + "ScaleCrop", // 155 + "Schema", // 156 + "SchemaID", // 157 + "SchemaRef", // 158 + "ScriptExtended", // 159 + "ScriptLanguage", // 160 + "ScriptLocation", // 161 + "ScriptText", // 162 + "SecretEdit", // 163 + "Sel", // 164 + "SelType", // 165 + "SelectedStyle", // 166 + "SelectionNamespaces", // 167 + "ShapeID", // 168 + "SharedDoc", // 169 + "ShortTitle", // 170 + "ShowImportExportValidationErrors", // 171 + "SizeWithCells", // 172 + "Slides", // 173 + "Source", // 174 + "SourceType", // 175 + "Sources", // 176 + "StandardNumber", // 177 + "StateProvince", // 178 + "Station", // 179 + "StyleName", // 180 + "Tag", // 181 + "Template", // 182 + "TextHAlign", // 183 + "TextVAlign", // 184 + "Theater", // 185 + "ThesisType", // 186 + "Title", // 187 + "TitlesOfParts", // 188 + "TotalTime", // 189 + "Translator", // 190 + "Type", // 191 + "UIObj", // 192 + "URI", // 193 + "URL", // 194 + "UpdateMode", // 195 + "VScroll", // 196 + "VTEdit", // 197 + "Val", // 198 + "ValidIds", // 199 + "Version", // 200 + "Visible", // 201 + "Volume", // 202 + "WidthMin", // 203 + "Words", // 204 + "Writer", // 205 + "Year", // 206 + "YearAccessed", // 207 + "a", // 208 + "aboveAverage", // 209 + "absSizeAnchor", // 210 + "absoluteAnchor", // 211 + "abstractNum", // 212 + "abstractNumId", // 213 + "aca", // 214 + "acc", // 215 + "accPr", // 216 + "accel", // 217 + "accent1", // 218 + "accent2", // 219 + "accent3", // 220 + "accent4", // 221 + "accent5", // 222 + "accent6", // 223 + "accentbar", // 224 + "accumulate", // 225 + "action", // 226 + "active", // 227 + "activeCell", // 228 + "activeCellId", // 229 + "activeCol", // 230 + "activePane", // 231 + "activeRecord", // 232 + "activeRow", // 233 + "activeSheetId", // 234 + "activeTab", // 235 + "activeWritingStyle", // 236 + "actualPg", // 237 + "additionalCharacteristics", // 238 + "additive", // 239 + "addlxml", // 240 + "addressFieldName", // 241 + "adj", // 242 + "adjLst", // 243 + "adjust", // 244 + "adjustColumnWidth", // 245 + "adjustLineHeightInTable", // 246 + "adjustRightInd", // 247 + "adjusthandles", // 248 + "advAuto", // 249 + "advClick", // 250 + "advTm", // 251 + "advise", // 252 + "after", // 253 + "afterAutospacing", // 254 + "afterEffect", // 255 + "afterLines", // 256 + "ahLst", // 257 + "ahPolar", // 258 + "ahXY", // 259 + "alg", // 260 + "algIdExt", // 261 + "algIdExtSource", // 262 + "algn", // 263 + "alias", // 264 + "aliases", // 265 + "align", // 266 + "alignBordersAndEdges", // 267 + "alignTablesRowByRow", // 268 + "alignWithMargins", // 269 + "alignment", // 270 + "alignshape", // 271 + "all", // 272 + "allCaption", // 273 + "allDrilled", // 274 + "allUniqueName", // 275 + "allowBlank", // 276 + "allowOverlap", // 277 + "allowPNG", // 278 + "allowPng", // 279 + "allowRefreshQuery", // 280 + "allowSpaceOfSameStyleInTable", // 281 + "allowcomments", // 282 + "allowincell", // 283 + "allowoverlap", // 284 + "aln", // 285 + "alnAt", // 286 + "alnScr", // 287 + "alpha", // 288 + "alphaBiLevel", // 289 + "alphaCeiling", // 290 + "alphaFloor", // 291 + "alphaInv", // 292 + "alphaMod", // 293 + "alphaModFix", // 294 + "alphaOff", // 295 + "alphaOutset", // 296 + "alphaRepl", // 297 + "alt", // 298 + "altChunk", // 299 + "altChunkPr", // 300 + "altLang", // 301 + "altName", // 302 + "althref", // 303 + "alwaysMergeEmptyNamespace", // 304 + "alwaysShow", // 305 + "alwaysShowPlaceholderText", // 306 + "amt", // 307 + "anchor", // 308 + "anchorCtr", // 309 + "anchorLock", // 310 + "anchorlock", // 311 + "anchorx", // 312 + "anchory", // 313 + "and", // 314 + "ang", // 315 + "angle", // 316 + "anim", // 317 + "animBg", // 318 + "animClr", // 319 + "animEffect", // 320 + "animLvl", // 321 + "animMotion", // 322 + "animOne", // 323 + "animRot", // 324 + "animScale", // 325 + "annotation", // 326 + "annotationRef", // 327 + "appName", // 328 + "applyAlignment", // 329 + "applyAlignmentFormats", // 330 + "applyBorder", // 331 + "applyBorderFormats", // 332 + "applyBreakingRules", // 333 + "applyFill", // 334 + "applyFont", // 335 + "applyFontFormats", // 336 + "applyNumberFormat", // 337 + "applyNumberFormats", // 338 + "applyPatternFormats", // 339 + "applyProtection", // 340 + "applyStyles", // 341 + "applyToEnd", // 342 + "applyToFront", // 343 + "applyToSides", // 344 + "applyWidthHeightFormats", // 345 + "arc", // 346 + "arcTo", // 347 + "arcsize", // 348 + "area3DChart", // 349 + "areaChart", // 350 + "arg", // 351 + "argPr", // 352 + "argSz", // 353 + "array", // 354 + "arrowok", // 355 + "ascii", // 356 + "asciiTheme", // 357 + "aspect", // 358 + "aspectratio", // 359 + "assign", // 360 + "asteriskTotals", // 361 + "attachedSchema", // 362 + "attachedTemplate", // 363 + "attr", // 364 + "attrName", // 365 + "attrNameLst", // 366 + "attribute", // 367 + "audio", // 368 + "audioCd", // 369 + "audioFile", // 370 + "author", // 371 + "authorId", // 372 + "authors", // 373 + "auto", // 374 + "autoAdjust", // 375 + "autoCaption", // 376 + "autoCaptions", // 377 + "autoCompressPictures", // 378 + "autoEnd", // 379 + "autoFilter", // 380 + "autoFilterDateGrouping", // 381 + "autoFormatId", // 382 + "autoFormatOverride", // 383 + "autoHyphenation", // 384 + "autoLoad", // 385 + "autoPage", // 386 + "autoPageBreaks", // 387 + "autoRecover", // 388 + "autoRedefine", // 389 + "autoRepublish", // 390 + "autoRev", // 391 + "autoShow", // 392 + "autoSortScope", // 393 + "autoSpaceDE", // 394 + "autoSpaceDN", // 395 + "autoSpaceLikeWord95", // 396 + "autoStart", // 397 + "autoTitleDeleted", // 398 + "autoUpdate", // 399 + "autoUpdateAnimBg", // 400 + "autofitToFirstFixedWidthCell", // 401 + "autoformat", // 402 + "autolayout", // 403 + "autorotationcenter", // 404 + "avLst", // 405 + "avgSubtotal", // 406 + "axId", // 407 + "axPos", // 408 + "axis", // 409 + "b", // 410 + "bCs", // 411 + "bIns", // 412 + "backWall", // 413 + "backdepth", // 414 + "backdrop", // 415 + "background", // 416 + "backgroundQuery", // 417 + "backgroundRefresh", // 418 + "backupFile", // 419 + "backward", // 420 + "backwards", // 421 + "balanceSingleByteDoubleByteWidth", // 422 + "band1H", // 423 + "band1V", // 424 + "band2H", // 425 + "band2V", // 426 + "bandCol", // 427 + "bandFmt", // 428 + "bandFmts", // 429 + "bandRow", // 430 + "bar", // 431 + "bar3DChart", // 432 + "barChart", // 433 + "barDir", // 434 + "barPr", // 435 + "base", // 436 + "baseColWidth", // 437 + "baseField", // 438 + "baseItem", // 439 + "baseJc", // 440 + "baseTimeUnit", // 441 + "baseType", // 442 + "basedOn", // 443 + "baseline", // 444 + "bc", // 445 + "bdr", // 446 + "before", // 447 + "beforeAutospacing", // 448 + "beforeLines", // 449 + "begChr", // 450 + "behavior", // 451 + "behaviors", // 452 + "behindDoc", // 453 + "bestFit", // 454 + "between", // 455 + "bevel", // 456 + "bevelB", // 457 + "bevelT", // 458 + "bg", // 459 + "bg1", // 460 + "bg2", // 461 + "bgClr", // 462 + "bgColor", // 463 + "bgFillStyleLst", // 464 + "bgPr", // 465 + "bgRef", // 466 + "biLevel", // 467 + "bibliography", // 468 + "bidi", // 469 + "bidiVisual", // 470 + "bilevel", // 471 + "bk", // 472 + "blackAndWhite", // 473 + "blacklevel", // 474 + "blank", // 475 + "bld", // 476 + "bldAsOne", // 477 + "bldChart", // 478 + "bldDgm", // 479 + "bldGraphic", // 480 + "bldLst", // 481 + "bldLvl", // 482 + "bldOleChart", // 483 + "bldP", // 484 + "bldStep", // 485 + "bldSub", // 486 + "blend", // 487 + "blinds", // 488 + "blip", // 489 + "blipFill", // 490 + "blipPhldr", // 491 + "blob", // 492 + "blockQuote", // 493 + "blue", // 494 + "blueMod", // 495 + "blueOff", // 496 + "blur", // 497 + "blurRad", // 498 + "bmk", // 499 + "body", // 500 + "bodyDiv", // 501 + "bodyPr", // 502 + "bodyStyle", // 503 + "bold", // 504 + "boldItalic", // 505 + "bookFoldPrinting", // 506 + "bookFoldPrintingSheets", // 507 + "bookFoldRevPrinting", // 508 + "bookViews", // 509 + "bookmarkEnd", // 510 + "bookmarkIdSeed", // 511 + "bookmarkStart", // 512 + "bool", // 513 + "boolVal", // 514 + "boolean", // 515 + "border", // 516 + "borderBox", // 517 + "borderBoxPr", // 518 + "borderId", // 519 + "borderbottom", // 520 + "borderbottomcolor", // 521 + "borderleft", // 522 + "borderleftcolor", // 523 + "borderright", // 524 + "borderrightcolor", // 525 + "borders", // 526 + "bordersDoNotSurroundFooter", // 527 + "bordersDoNotSurroundHeader", // 528 + "bordertop", // 529 + "bordertopcolor", // 530 + "bottom", // 531 + "bottomFromText", // 532 + "box", // 533 + "boxPr", // 534 + "br", // 535 + "bright", // 536 + "brightness", // 537 + "brk", // 538 + "brkBin", // 539 + "brkBinSub", // 540 + "browse", // 541 + "bstr", // 542 + "buAutoNum", // 543 + "buBlip", // 544 + "buChar", // 545 + "buClr", // 546 + "buClrTx", // 547 + "buFont", // 548 + "buFontTx", // 549 + "buNone", // 550 + "buSzPct", // 551 + "buSzPts", // 552 + "buSzTx", // 553 + "bubble3D", // 554 + "bubbleChart", // 555 + "bubbleScale", // 556 + "bubbleSize", // 557 + "build", // 558 + "builtIn", // 559 + "builtInGroupCount", // 560 + "builtInUnit", // 561 + "builtinId", // 562 + "bullet", // 563 + "bulletEnabled", // 564 + "button", // 565 + "bw", // 566 + "bwMode", // 567 + "bwmode", // 568 + "bwnormal", // 569 + "bwpure", // 570 + "bx", // 571 + "by", // 572 + "byPosition", // 573 + "c", // 574 + "cBhvr", // 575 + "cGp", // 576 + "cGpRule", // 577 + "cMediaNode", // 578 + "cNvCxnSpPr", // 579 + "cNvGraphicFramePr", // 580 + "cNvGrpSpPr", // 581 + "cNvPicPr", // 582 + "cNvPr", // 583 + "cNvSpPr", // 584 + "cSld", // 585 + "cSldViewPr", // 586 + "cSp", // 587 + "cTn", // 588 + "cViewPr", // 589 + "ca", // 590 + "cacheField", // 591 + "cacheFields", // 592 + "cacheHierarchies", // 593 + "cacheHierarchy", // 594 + "cacheId", // 595 + "cacheIndex", // 596 + "cacheSource", // 597 + "cachedColBalance", // 598 + "calcChain", // 599 + "calcCompleted", // 600 + "calcId", // 601 + "calcMode", // 602 + "calcOnExit", // 603 + "calcOnSave", // 604 + "calcPr", // 605 + "calcmode", // 606 + "calculatedColumn", // 607 + "calculatedColumnFormula", // 608 + "calculatedItem", // 609 + "calculatedItems", // 610 + "calculatedMember", // 611 + "calculatedMembers", // 612 + "calendar", // 613 + "calendarType", // 614 + "callout", // 615 + "camera", // 616 + "cantSplit", // 617 + "cap", // 618 + "caps", // 619 + "caption", // 620 + "captions", // 621 + "caseSensitive", // 622 + "cat", // 623 + "catAx", // 624 + "catLst", // 625 + "category", // 626 + "categoryIdx", // 627 + "cell", // 628 + "cell3D", // 629 + "cellColor", // 630 + "cellComments", // 631 + "cellDel", // 632 + "cellIns", // 633 + "cellMerge", // 634 + "cellMeta", // 635 + "cellMetadata", // 636 + "cellSmartTag", // 637 + "cellSmartTagPr", // 638 + "cellSmartTags", // 639 + "cellStyle", // 640 + "cellStyleXfs", // 641 + "cellStyles", // 642 + "cellWatch", // 643 + "cellWatches", // 644 + "cellXfs", // 645 + "cf", // 646 + "cfRule", // 647 + "cfvo", // 648 + "chExt", // 649 + "chMax", // 650 + "chOff", // 651 + "chOrder", // 652 + "chPref", // 653 + "changesSavedWin", // 654 + "chapNum", // 655 + "chapSep", // 656 + "chapStyle", // 657 + "char", // 658 + "charRg", // 659 + "charSpace", // 660 + "characterSpacingControl", // 661 + "characteristic", // 662 + "charset", // 663 + "chart", // 664 + "chartFormat", // 665 + "chartFormats", // 666 + "chartObject", // 667 + "chartSpace", // 668 + "chartsheet", // 669 + "checkBox", // 670 + "checkCompatibility", // 671 + "checkErrors", // 672 + "checkStyle", // 673 + "checked", // 674 + "checker", // 675 + "childTnLst", // 676 + "choose", // 677 + "chr", // 678 + "chromakey", // 679 + "circle", // 680 + "citation", // 681 + "class", // 682 + "clear", // 683 + "clearAll", // 684 + "clearComments", // 685 + "clearContents", // 686 + "clearFormats", // 687 + "click", // 688 + "clickAndTypeStyle", // 689 + "clientData", // 690 + "clientInsertedTime", // 691 + "clip", // 692 + "clippath", // 693 + "clipped", // 694 + "cliptowrap", // 695 + "close", // 696 + "clr", // 697 + "clrChange", // 698 + "clrData", // 699 + "clrFrom", // 700 + "clrIdx", // 701 + "clrMap", // 702 + "clrMapOvr", // 703 + "clrMode", // 704 + "clrMru", // 705 + "clrRepl", // 706 + "clrScheme", // 707 + "clrSchemeMapping", // 708 + "clrSpc", // 709 + "clrTo", // 710 + "clrVal", // 711 + "clsid", // 712 + "cm", // 713 + "cmAuthor", // 714 + "cmAuthorLst", // 715 + "cmLst", // 716 + "cmd", // 717 + "cmpd", // 718 + "cnfStyle", // 719 + "cnt", // 720 + "code", // 721 + "codeName", // 722 + "codePage", // 723 + "coerce", // 724 + "coherent3DOff", // 725 + "col", // 726 + "colBreaks", // 727 + "colDelim", // 728 + "colFields", // 729 + "colFirst", // 730 + "colGrandTotals", // 731 + "colHeaderCaption", // 732 + "colHierarchiesUsage", // 733 + "colHierarchyUsage", // 734 + "colId", // 735 + "colItems", // 736 + "colLast", // 737 + "colOff", // 738 + "colPageCount", // 739 + "collapse", // 740 + "collapsed", // 741 + "collapsedLevelsAreSubtotals", // 742 + "color", // 743 + "color2", // 744 + "colorFilter", // 745 + "colorId", // 746 + "colorScale", // 747 + "colormenu", // 748 + "colormode", // 749 + "colormru", // 750 + "colors", // 751 + "colorsDef", // 752 + "colorsDefHdr", // 753 + "colorsDefHdrLst", // 754 + "cols", // 755 + "column", // 756 + "columnSort", // 757 + "comb", // 758 + "combine", // 759 + "combineBrackets", // 760 + "comboBox", // 761 + "comma", // 762 + "command", // 763 + "commandType", // 764 + "comment", // 765 + "commentList", // 766 + "commentRangeEnd", // 767 + "commentRangeStart", // 768 + "commentReference", // 769 + "comments", // 770 + "comp", // 771 + "compact", // 772 + "compactData", // 773 + "compat", // 774 + "compatLnSpc", // 775 + "compatMode", // 776 + "complex", // 777 + "concurrent", // 778 + "concurrentCalc", // 779 + "concurrentManualCount", // 780 + "cond", // 781 + "condense", // 782 + "conditionalFormat", // 783 + "conditionalFormats", // 784 + "conditionalFormatting", // 785 + "connectString", // 786 + "connectangles", // 787 + "connection", // 788 + "connectionId", // 789 + "connections", // 790 + "connectloc", // 791 + "connectlocs", // 792 + "connectortype", // 793 + "connecttype", // 794 + "consecutive", // 795 + "consecutiveHyphenLimit", // 796 + "consolidation", // 797 + "constr", // 798 + "constrLst", // 799 + "constrainbounds", // 800 + "cont", // 801 + "containsBlank", // 802 + "containsDate", // 803 + "containsInteger", // 804 + "containsMixedTypes", // 805 + "containsNonDate", // 806 + "containsNumber", // 807 + "containsSemiMixedTypes", // 808 + "containsString", // 809 + "content", // 810 + "contextualSpacing", // 811 + "continuationSeparator", // 812 + "contourClr", // 813 + "contourW", // 814 + "contrast", // 815 + "control", // 816 + "control1", // 817 + "control2", // 818 + "controls", // 819 + "convMailMergeEsc", // 820 + "coordorigin", // 821 + "coordsize", // 822 + "copies", // 823 + "copy", // 824 + "count", // 825 + "countASubtotal", // 826 + "countBy", // 827 + "countSubtotal", // 828 + "cover", // 829 + "cp", // 830 + "cr", // 831 + "crashSave", // 832 + "createdVersion", // 833 + "credentials", // 834 + "cropbottom", // 835 + "cropleft", // 836 + "cropping", // 837 + "cropright", // 838 + "croptop", // 839 + "crossAx", // 840 + "crossBetween", // 841 + "crosses", // 842 + "crossesAt", // 843 + "cryptAlgorithmClass", // 844 + "cryptAlgorithmSid", // 845 + "cryptAlgorithmType", // 846 + "cryptProvider", // 847 + "cryptProviderType", // 848 + "cryptProviderTypeExt", // 849 + "cryptProviderTypeExtSource", // 850 + "cryptSpinCount", // 851 + "cs", // 852 + "csCatId", // 853 + "csTypeId", // 854 + "csb0", // 855 + "csb1", // 856 + "css", // 857 + "cstate", // 858 + "cstheme", // 859 + "ct", // 860 + "ctrlPr", // 861 + "cubicBezTo", // 862 + "culture", // 863 + "current", // 864 + "curve", // 865 + "custAng", // 866 + "custClr", // 867 + "custClrLst", // 868 + "custDash", // 869 + "custData", // 870 + "custDataLst", // 871 + "custFlipHor", // 872 + "custFlipVert", // 873 + "custGeom", // 874 + "custLinFactNeighborX", // 875 + "custLinFactNeighborY", // 876 + "custLinFactX", // 877 + "custLinFactY", // 878 + "custRadScaleInc", // 879 + "custRadScaleRad", // 880 + "custScaleX", // 881 + "custScaleY", // 882 + "custShow", // 883 + "custShowLst", // 884 + "custSplit", // 885 + "custSzX", // 886 + "custSzY", // 887 + "custT", // 888 + "custUnit", // 889 + "customBuiltin", // 890 + "customFilter", // 891 + "customFilters", // 892 + "customFormat", // 893 + "customHeight", // 894 + "customList", // 895 + "customListSort", // 896 + "customMarkFollows", // 897 + "customMenu", // 898 + "customPr", // 899 + "customProperties", // 900 + "customRollUp", // 901 + "customSheetView", // 902 + "customSheetViews", // 903 + "customStyle", // 904 + "customView", // 905 + "customWidth", // 906 + "customWorkbookView", // 907 + "customWorkbookViews", // 908 + "customXml", // 909 + "customXmlDelRangeEnd", // 910 + "customXmlDelRangeStart", // 911 + "customXmlInsRangeEnd", // 912 + "customXmlInsRangeStart", // 913 + "customXmlMoveFromRangeEnd", // 914 + "customXmlMoveFromRangeStart", // 915 + "customXmlMoveToRangeEnd", // 916 + "customXmlMoveToRangeStart", // 917 + "customXmlPr", // 918 + "cut", // 919 + "cx", // 920 + "cxn", // 921 + "cxnId", // 922 + "cxnLst", // 923 + "cxnSp", // 924 + "cxnSpLocks", // 925 + "cy", // 926 + "d", // 927 + "dLbl", // 928 + "dLblPos", // 929 + "dLbls", // 930 + "dPr", // 931 + "dPt", // 932 + "dTable", // 933 + "dashstyle", // 934 + "data", // 935 + "dataBar", // 936 + "dataBinding", // 937 + "dataBound", // 938 + "dataCaption", // 939 + "dataCellStyle", // 940 + "dataConsolidate", // 941 + "dataDxfId", // 942 + "dataExtractLoad", // 943 + "dataField", // 944 + "dataFields", // 945 + "dataModel", // 946 + "dataOnRows", // 947 + "dataOnly", // 948 + "dataPosition", // 949 + "dataRef", // 950 + "dataRefs", // 951 + "dataSource", // 952 + "dataSourceSort", // 953 + "dataType", // 954 + "dataValidation", // 955 + "dataValidations", // 956 + "databaseField", // 957 + "datastoreItem", // 958 + "date", // 959 + "date1904", // 960 + "dateAx", // 961 + "dateFormat", // 962 + "dateGroupItem", // 963 + "dateTime", // 964 + "dateTimeGrouping", // 965 + "day", // 966 + "dayLong", // 967 + "dayShort", // 968 + "dbPr", // 969 + "ddList", // 970 + "ddeItem", // 971 + "ddeItems", // 972 + "ddeLink", // 973 + "ddeService", // 974 + "ddeTopic", // 975 + "decel", // 976 + "decimal", // 977 + "decimalSymbol", // 978 + "decorated", // 979 + "def", // 980 + "defJc", // 981 + "defLockedState", // 982 + "defPPr", // 983 + "defQFormat", // 984 + "defRPr", // 985 + "defSemiHidden", // 986 + "defStyle", // 987 + "defTabSz", // 988 + "defUIPriority", // 989 + "defUnhideWhenUsed", // 990 + "default", // 991 + "defaultAttributeDrillState", // 992 + "defaultColWidth", // 993 + "defaultGridColor", // 994 + "defaultMemberUniqueName", // 995 + "defaultPivotStyle", // 996 + "defaultRowHeight", // 997 + "defaultSubtotal", // 998 + "defaultTabStop", // 999 + "defaultTableStyle", // 1000 + "defaultTextStyle", // 1001 + "defaultThemeVersion", // 1002 + "definedName", // 1003 + "definedNames", // 1004 + "deg", // 1005 + "degHide", // 1006 + "degree", // 1007 + "del", // 1008 + "del1", // 1009 + "del2", // 1010 + "delInstrText", // 1011 + "delText", // 1012 + "delay", // 1013 + "delete", // 1014 + "deleteColumns", // 1015 + "deleteRows", // 1016 + "deleted", // 1017 + "deletedField", // 1018 + "delimited", // 1019 + "delimiter", // 1020 + "den", // 1021 + "denormalized", // 1022 + "depthPercent", // 1023 + "desc", // 1024 + "descending", // 1025 + "descr", // 1026 + "description", // 1027 + "destId", // 1028 + "destOrd", // 1029 + "destination", // 1030 + "destinationFile", // 1031 + "detectmouseclick", // 1032 + "dgm", // 1033 + "dgmbasetextscale", // 1034 + "dgmfontsize", // 1035 + "dgmlayout", // 1036 + "dgmlayoutmru", // 1037 + "dgmnodekind", // 1038 + "dgmscalex", // 1039 + "dgmscaley", // 1040 + "dgmstyle", // 1041 + "diagonal", // 1042 + "diagonalDown", // 1043 + "diagonalUp", // 1044 + "diagram", // 1045 + "dialogsheet", // 1046 + "diamond", // 1047 + "diff", // 1048 + "differentFirst", // 1049 + "differentOddEven", // 1050 + "diffusity", // 1051 + "dimension", // 1052 + "dimensionUniqueName", // 1053 + "dimensions", // 1054 + "dir", // 1055 + "dirty", // 1056 + "disableEdit", // 1057 + "disableFieldList", // 1058 + "disablePrompts", // 1059 + "disableRefresh", // 1060 + "discretePr", // 1061 + "diskRevisions", // 1062 + "dispBlanksAs", // 1063 + "dispDef", // 1064 + "dispEq", // 1065 + "dispRSqr", // 1066 + "dispUnits", // 1067 + "dispUnitsLbl", // 1068 + "displacedByCustomXml", // 1069 + "display", // 1070 + "displayBackgroundShape", // 1071 + "displayFolder", // 1072 + "displayHangulFixedWidth", // 1073 + "displayHorizontalDrawingGridEvery", // 1074 + "displayName", // 1075 + "displayText", // 1076 + "displayVerticalDrawingGridEvery", // 1077 + "dissolve", // 1078 + "dist", // 1079 + "distB", // 1080 + "distL", // 1081 + "distR", // 1082 + "distT", // 1083 + "distance", // 1084 + "div", // 1085 + "divBdr", // 1086 + "divId", // 1087 + "divs", // 1088 + "divsChild", // 1089 + "dk1", // 1090 + "dk2", // 1091 + "dllVersion", // 1092 + "dm", // 1093 + "dn", // 1094 + "doNotAutoCompressPictures", // 1095 + "doNotAutofitConstrainedTables", // 1096 + "doNotBreakConstrainedForcedTable", // 1097 + "doNotBreakWrappedTables", // 1098 + "doNotDemarcateInvalidXml", // 1099 + "doNotDisplayPageBoundaries", // 1100 + "doNotEmbedSmartTags", // 1101 + "doNotExpandShiftReturn", // 1102 + "doNotHyphenateCaps", // 1103 + "doNotIncludeSubdocsInStats", // 1104 + "doNotLeaveBackslashAlone", // 1105 + "doNotOrganizeInFolder", // 1106 + "doNotRelyOnCSS", // 1107 + "doNotSaveAsSingleFile", // 1108 + "doNotShadeFormData", // 1109 + "doNotSnapToGridInCell", // 1110 + "doNotSuppressBlankLines", // 1111 + "doNotSuppressIndentation", // 1112 + "doNotSuppressParagraphBorders", // 1113 + "doNotTrackFormatting", // 1114 + "doNotTrackMoves", // 1115 + "doNotUseEastAsianBreakRules", // 1116 + "doNotUseHTMLParagraphAutoSpacing", // 1117 + "doNotUseIndentAsNumberingTabStop", // 1118 + "doNotUseLongFileNames", // 1119 + "doNotUseMarginsForDrawingGridOrigin", // 1120 + "doNotValidateAgainstSchema", // 1121 + "doNotVertAlignCellWithSp", // 1122 + "doNotVertAlignInTxbx", // 1123 + "doNotWrapTextWithPunct", // 1124 + "docDefaults", // 1125 + "docGrid", // 1126 + "docLocation", // 1127 + "docPart", // 1128 + "docPartBody", // 1129 + "docPartCategory", // 1130 + "docPartGallery", // 1131 + "docPartList", // 1132 + "docPartObj", // 1133 + "docPartPr", // 1134 + "docPartUnique", // 1135 + "docParts", // 1136 + "docPr", // 1137 + "docVar", // 1138 + "docVars", // 1139 + "document", // 1140 + "documentProtection", // 1141 + "documentType", // 1142 + "double", // 1143 + "doubleclicknotify", // 1144 + "doughnutChart", // 1145 + "downBars", // 1146 + "dpi", // 1147 + "dr", // 1148 + "draft", // 1149 + "dragOff", // 1150 + "dragToCol", // 1151 + "dragToData", // 1152 + "dragToPage", // 1153 + "dragToRow", // 1154 + "drawing", // 1155 + "drawingGridHorizontalOrigin", // 1156 + "drawingGridHorizontalSpacing", // 1157 + "drawingGridVerticalOrigin", // 1158 + "drawingGridVerticalSpacing", // 1159 + "drop", // 1160 + "dropCap", // 1161 + "dropDownList", // 1162 + "dropLines", // 1163 + "dropauto", // 1164 + "ds", // 1165 + "dstrike", // 1166 + "dt", // 1167 + "dt2D", // 1168 + "dtr", // 1169 + "duotone", // 1170 + "dur", // 1171 + "dvAspect", // 1172 + "dx", // 1173 + "dxaOrig", // 1174 + "dxf", // 1175 + "dxfId", // 1176 + "dxfs", // 1177 + "dy", // 1178 + "dyaOrig", // 1179 + "dynamicAddress", // 1180 + "dynamicFilter", // 1181 + "dz", // 1182 + "e", // 1183 + "ea", // 1184 + "eaLnBrk", // 1185 + "eastAsia", // 1186 + "eastAsiaTheme", // 1187 + "eastAsianLayout", // 1188 + "eb", // 1189 + "ed", // 1190 + "edGrp", // 1191 + "edge", // 1192 + "edit", // 1193 + "editAs", // 1194 + "editData", // 1195 + "editPage", // 1196 + "editas", // 1197 + "edited", // 1198 + "effect", // 1199 + "effectClrLst", // 1200 + "effectDag", // 1201 + "effectExtent", // 1202 + "effectLst", // 1203 + "effectRef", // 1204 + "effectStyle", // 1205 + "effectStyleLst", // 1206 + "element", // 1207 + "else", // 1208 + "em", // 1209 + "embed", // 1210 + "embedBold", // 1211 + "embedBoldItalic", // 1212 + "embedItalic", // 1213 + "embedRegular", // 1214 + "embedSystemFonts", // 1215 + "embedTrueTypeFonts", // 1216 + "embeddedFont", // 1217 + "embeddedFontLst", // 1218 + "emboss", // 1219 + "embosscolor", // 1220 + "empty", // 1221 + "emptyCellReference", // 1222 + "enableDrill", // 1223 + "enableFieldProperties", // 1224 + "enableFormatConditionsCalculation", // 1225 + "enableRefresh", // 1226 + "enableWizard", // 1227 + "enabled", // 1228 + "encoding", // 1229 + "end", // 1230 + "endA", // 1231 + "endAngle", // 1232 + "endChr", // 1233 + "endCondLst", // 1234 + "endCxn", // 1235 + "endDate", // 1236 + "endNum", // 1237 + "endOfListFormulaUpdate", // 1238 + "endParaRPr", // 1239 + "endPos", // 1240 + "endSnd", // 1241 + "endSync", // 1242 + "endarrow", // 1243 + "endarrowlength", // 1244 + "endarrowwidth", // 1245 + "endcap", // 1246 + "endnote", // 1247 + "endnotePr", // 1248 + "endnoteRef", // 1249 + "endnoteReference", // 1250 + "endnotes", // 1251 + "enforcement", // 1252 + "entries", // 1253 + "entry", // 1254 + "entryMacro", // 1255 + "eol", // 1256 + "eqArr", // 1257 + "eqArrPr", // 1258 + "eqn", // 1259 + "equalAverage", // 1260 + "equalWidth", // 1261 + "equation", // 1262 + "equationxml", // 1263 + "err", // 1264 + "errBarType", // 1265 + "errBars", // 1266 + "errDir", // 1267 + "errValType", // 1268 + "error", // 1269 + "errorCaption", // 1270 + "errorStyle", // 1271 + "errorTitle", // 1272 + "errors", // 1273 + "evalError", // 1274 + "evalOrder", // 1275 + "evenAndOddHeaders", // 1276 + "evenFooter", // 1277 + "evenHeader", // 1278 + "evt", // 1279 + "evtFilter", // 1280 + "excl", // 1281 + "exclusive", // 1282 + "exitMacro", // 1283 + "exp", // 1284 + "explosion", // 1285 + "ext", // 1286 + "extLst", // 1287 + "extend", // 1288 + "extendable", // 1289 + "extent", // 1290 + "externalBook", // 1291 + "externalData", // 1292 + "externalLink", // 1293 + "externalReference", // 1294 + "externalReferences", // 1295 + "extraClrScheme", // 1296 + "extraClrSchemeLst", // 1297 + "extrusion", // 1298 + "extrusionClr", // 1299 + "extrusionH", // 1300 + "extrusionOk", // 1301 + "extrusioncolor", // 1302 + "extrusionok", // 1303 + "f", // 1304 + "fHdr", // 1305 + "fLocksText", // 1306 + "fLocksWithSheet", // 1307 + "fName", // 1308 + "fPr", // 1309 + "fPrintsWithSheet", // 1310 + "fPublished", // 1311 + "facet", // 1312 + "fact", // 1313 + "fade", // 1314 + "fadeDir", // 1315 + "family", // 1316 + "fc", // 1317 + "ffData", // 1318 + "fgClr", // 1319 + "fgColor", // 1320 + "fi", // 1321 + "field", // 1322 + "fieldGroup", // 1323 + "fieldId", // 1324 + "fieldIdWrapped", // 1325 + "fieldListSortAscending", // 1326 + "fieldMapData", // 1327 + "fieldPosition", // 1328 + "fieldPrintTitles", // 1329 + "fieldUsage", // 1330 + "fieldsUsage", // 1331 + "fileRecoveryPr", // 1332 + "fileSharing", // 1333 + "fileType", // 1334 + "fileVersion", // 1335 + "filetime", // 1336 + "fill", // 1337 + "fillClrLst", // 1338 + "fillFormulas", // 1339 + "fillId", // 1340 + "fillOverlay", // 1341 + "fillRect", // 1342 + "fillRef", // 1343 + "fillStyleLst", // 1344 + "fillToRect", // 1345 + "fillcolor", // 1346 + "filled", // 1347 + "fillok", // 1348 + "fills", // 1349 + "filltype", // 1350 + "filter", // 1351 + "filterColumn", // 1352 + "filterMode", // 1353 + "filterPrivacy", // 1354 + "filterUnique", // 1355 + "filterVal", // 1356 + "filters", // 1357 + "first", // 1358 + "firstBackgroundRefresh", // 1359 + "firstCol", // 1360 + "firstDataCol", // 1361 + "firstDataRow", // 1362 + "firstFooter", // 1363 + "firstHeader", // 1364 + "firstHeaderRow", // 1365 + "firstLine", // 1366 + "firstLineChars", // 1367 + "firstPageNumber", // 1368 + "firstRow", // 1369 + "firstSheet", // 1370 + "firstSliceAng", // 1371 + "firstSlideNum", // 1372 + "fitText", // 1373 + "fitToHeight", // 1374 + "fitToPage", // 1375 + "fitToWidth", // 1376 + "fitpath", // 1377 + "fitshape", // 1378 + "flatBorders", // 1379 + "flatTx", // 1380 + "fld", // 1381 + "fldChar", // 1382 + "fldCharType", // 1383 + "fldData", // 1384 + "fldLock", // 1385 + "fldSimple", // 1386 + "flip", // 1387 + "flipH", // 1388 + "flipV", // 1389 + "floor", // 1390 + "fltVal", // 1391 + "fmla", // 1392 + "fmt", // 1393 + "fmtId", // 1394 + "fmtScheme", // 1395 + "fmtid", // 1396 + "focus", // 1397 + "focusposition", // 1398 + "focussize", // 1399 + "folHlink", // 1400 + "followColorScheme", // 1401 + "followedHyperlink", // 1402 + "font", // 1403 + "fontAlgn", // 1404 + "fontId", // 1405 + "fontKey", // 1406 + "fontRef", // 1407 + "fontScale", // 1408 + "fontScheme", // 1409 + "fontSz", // 1410 + "fonts", // 1411 + "footer", // 1412 + "footerReference", // 1413 + "footnote", // 1414 + "footnoteLayoutLikeWW8", // 1415 + "footnotePr", // 1416 + "footnoteRef", // 1417 + "footnoteReference", // 1418 + "footnotes", // 1419 + "for", // 1420 + "forEach", // 1421 + "forName", // 1422 + "forceAA", // 1423 + "forceFullCalc", // 1424 + "forceUpgrade", // 1425 + "forcedash", // 1426 + "foredepth", // 1427 + "forgetLastTabAlignment", // 1428 + "formProt", // 1429 + "format", // 1430 + "formatCells", // 1431 + "formatCode", // 1432 + "formatColumns", // 1433 + "formatRows", // 1434 + "formats", // 1435 + "formatting", // 1436 + "formsDesign", // 1437 + "formula", // 1438 + "formula1", // 1439 + "formula2", // 1440 + "formulaRange", // 1441 + "formulas", // 1442 + "forward", // 1443 + "fov", // 1444 + "frame", // 1445 + "frameLayout", // 1446 + "framePr", // 1447 + "frameSlides", // 1448 + "frameset", // 1449 + "framesetSplitbar", // 1450 + "from", // 1451 + "fromWordArt", // 1452 + "ftr", // 1453 + "fullCalcOnLoad", // 1454 + "fullDate", // 1455 + "fullPrecision", // 1456 + "fullScrn", // 1457 + "func", // 1458 + "funcPr", // 1459 + "function", // 1460 + "functionGroup", // 1461 + "functionGroupId", // 1462 + "functionGroups", // 1463 + "futureMetadata", // 1464 + "g", // 1465 + "gain", // 1466 + "gallery", // 1467 + "gamma", // 1468 + "gap", // 1469 + "gapDepth", // 1470 + "gapWidth", // 1471 + "gd", // 1472 + "gdLst", // 1473 + "gdRefAng", // 1474 + "gdRefR", // 1475 + "gdRefX", // 1476 + "gdRefY", // 1477 + "gfxdata", // 1478 + "ghostCol", // 1479 + "ghostRow", // 1480 + "glossaryDocument", // 1481 + "glow", // 1482 + "goal", // 1483 + "gradFill", // 1484 + "gradientFill", // 1485 + "gradientshapeok", // 1486 + "grammar", // 1487 + "grandCol", // 1488 + "grandRow", // 1489 + "grandTotalCaption", // 1490 + "graphic", // 1491 + "graphicData", // 1492 + "graphicEl", // 1493 + "graphicFrame", // 1494 + "graphicFrameLocks", // 1495 + "gray", // 1496 + "grayscale", // 1497 + "grayscl", // 1498 + "green", // 1499 + "greenMod", // 1500 + "greenOff", // 1501 + "gridAfter", // 1502 + "gridBefore", // 1503 + "gridCol", // 1504 + "gridDropZones", // 1505 + "gridLines", // 1506 + "gridLinesSet", // 1507 + "gridSpacing", // 1508 + "gridSpan", // 1509 + "group", // 1510 + "groupBy", // 1511 + "groupChr", // 1512 + "groupChrPr", // 1513 + "groupInterval", // 1514 + "groupItems", // 1515 + "groupLevel", // 1516 + "groupLevels", // 1517 + "groupMember", // 1518 + "groupMembers", // 1519 + "grouping", // 1520 + "groups", // 1521 + "grow", // 1522 + "growAutofit", // 1523 + "growShrinkType", // 1524 + "grpFill", // 1525 + "grpId", // 1526 + "grpSp", // 1527 + "grpSpLocks", // 1528 + "grpSpPr", // 1529 + "gs", // 1530 + "gsLst", // 1531 + "gte", // 1532 + "guid", // 1533 + "guide", // 1534 + "guideLst", // 1535 + "gutter", // 1536 + "gutterAtTop", // 1537 + "h", // 1538 + "hAnchor", // 1539 + "hAnsi", // 1540 + "hAnsiTheme", // 1541 + "hMerge", // 1542 + "hMode", // 1543 + "hPercent", // 1544 + "hR", // 1545 + "hRule", // 1546 + "hSpace", // 1547 + "handles", // 1548 + "handoutMaster", // 1549 + "handoutMasterId", // 1550 + "handoutMasterIdLst", // 1551 + "hanging", // 1552 + "hangingChars", // 1553 + "hangingPunct", // 1554 + "hasCustomPrompt", // 1555 + "hash", // 1556 + "hashData", // 1557 + "hdr", // 1558 + "hdrShapeDefaults", // 1559 + "headEnd", // 1560 + "header", // 1561 + "headerFooter", // 1562 + "headerReference", // 1563 + "headerRowBorderDxfId", // 1564 + "headerRowCellStyle", // 1565 + "headerRowCount", // 1566 + "headerRowDxfId", // 1567 + "headerSource", // 1568 + "headers", // 1569 + "headersInLastRefresh", // 1570 + "heading", // 1571 + "headings", // 1572 + "help", // 1573 + "helpText", // 1574 + "hf", // 1575 + "hiLowLines", // 1576 + "hidden", // 1577 + "hiddenButton", // 1578 + "hiddenColumn", // 1579 + "hiddenColumns", // 1580 + "hiddenLevel", // 1581 + "hiddenRow", // 1582 + "hiddenRows", // 1583 + "hiddenSlides", // 1584 + "hideBot", // 1585 + "hideGeom", // 1586 + "hideGrammaticalErrors", // 1587 + "hideLastTrans", // 1588 + "hideLeft", // 1589 + "hideMark", // 1590 + "hideNewItems", // 1591 + "hidePivotFieldList", // 1592 + "hideRight", // 1593 + "hideSpellingErrors", // 1594 + "hideTop", // 1595 + "hier", // 1596 + "hierBranch", // 1597 + "hierarchy", // 1598 + "hierarchyUsage", // 1599 + "highlight", // 1600 + "highlightClick", // 1601 + "hint", // 1602 + "history", // 1603 + "hlink", // 1604 + "hlinkClick", // 1605 + "hlinkHover", // 1606 + "hlinkMouseOver", // 1607 + "holeSize", // 1608 + "horizontal", // 1609 + "horizontalCentered", // 1610 + "horizontalDpi", // 1611 + "horzAnchor", // 1612 + "horzBarState", // 1613 + "horzOverflow", // 1614 + "hour", // 1615 + "how", // 1616 + "hps", // 1617 + "hpsBaseText", // 1618 + "hpsRaise", // 1619 + "hr", // 1620 + "hralign", // 1621 + "href", // 1622 + "hrnoshade", // 1623 + "hrpct", // 1624 + "hrstd", // 1625 + "hsl", // 1626 + "hslClr", // 1627 + "ht", // 1628 + "htmlFormat", // 1629 + "htmlPubPr", // 1630 + "htmlTables", // 1631 + "hue", // 1632 + "hueDir", // 1633 + "hueMod", // 1634 + "hueOff", // 1635 + "hyperlink", // 1636 + "hyperlinks", // 1637 + "hyphenationZone", // 1638 + "i", // 1639 + "i1", // 1640 + "i2", // 1641 + "i3", // 1642 + "i4", // 1643 + "i8", // 1644 + "iCs", // 1645 + "iLevel", // 1646 + "iMeasureFld", // 1647 + "iMeasureHier", // 1648 + "icon", // 1649 + "iconFilter", // 1650 + "iconId", // 1651 + "iconSet", // 1652 + "id", // 1653 + "idcntr", // 1654 + "iddest", // 1655 + "idmap", // 1656 + "idref", // 1657 + "idsrc", // 1658 + "idx", // 1659 + "if", // 1660 + "ignoreMixedContent", // 1661 + "ignoredError", // 1662 + "ignoredErrors", // 1663 + "ilvl", // 1664 + "image", // 1665 + "imagealignshape", // 1666 + "imageaspect", // 1667 + "imagedata", // 1668 + "imagesize", // 1669 + "imeMode", // 1670 + "imgH", // 1671 + "imgSz", // 1672 + "imgW", // 1673 + "immersive", // 1674 + "imprint", // 1675 + "in", // 1676 + "includeHiddenRowCol", // 1677 + "includeNewItemsInFilter", // 1678 + "includePrintSettings", // 1679 + "ind", // 1680 + "indent", // 1681 + "index", // 1682 + "indexed", // 1683 + "indexedColors", // 1684 + "initials", // 1685 + "ink", // 1686 + "inkAnnotations", // 1687 + "inkTgt", // 1688 + "inline", // 1689 + "innerShdw", // 1690 + "inputCells", // 1691 + "ins", // 1692 + "insDel", // 1693 + "insertBlankRow", // 1694 + "insertColumns", // 1695 + "insertHyperlinks", // 1696 + "insertPageBreak", // 1697 + "insertRow", // 1698 + "insertRowShift", // 1699 + "insertRows", // 1700 + "inset", // 1701 + "insetmode", // 1702 + "insetpen", // 1703 + "insetpenok", // 1704 + "insideH", // 1705 + "insideV", // 1706 + "instr", // 1707 + "instrText", // 1708 + "int", // 1709 + "intLim", // 1710 + "intVal", // 1711 + "integer", // 1712 + "interSp", // 1713 + "intercept", // 1714 + "intermediate", // 1715 + "interval", // 1716 + "intraSp", // 1717 + "inv", // 1718 + "invGamma", // 1719 + "invalEndChars", // 1720 + "invalStChars", // 1721 + "invalid", // 1722 + "invalidUrl", // 1723 + "invertIfNegative", // 1724 + "invx", // 1725 + "invy", // 1726 + "is", // 1727 + "isLgl", // 1728 + "isNarration", // 1729 + "isPhoto", // 1730 + "iscomment", // 1731 + "issignatureline", // 1732 + "italic", // 1733 + "item", // 1734 + "itemID", // 1735 + "itemPageCount", // 1736 + "itemPrintTitles", // 1737 + "items", // 1738 + "iterate", // 1739 + "iterateCount", // 1740 + "iterateDelta", // 1741 + "jc", // 1742 + "joinstyle", // 1743 + "justifyLastLine", // 1744 + "k", // 1745 + "keepAlive", // 1746 + "keepChangeHistory", // 1747 + "keepLines", // 1748 + "keepNext", // 1749 + "kern", // 1750 + "key", // 1751 + "keyAttribute", // 1752 + "kinsoku", // 1753 + "kiosk", // 1754 + "kpi", // 1755 + "kpis", // 1756 + "kumimoji", // 1757 + "kx", // 1758 + "ky", // 1759 + "l", // 1760 + "lBounds", // 1761 + "lIns", // 1762 + "lMargin", // 1763 + "label", // 1764 + "labelOnly", // 1765 + "lang", // 1766 + "lastClr", // 1767 + "lastCol", // 1768 + "lastEdited", // 1769 + "lastGuid", // 1770 + "lastIdx", // 1771 + "lastRenderedPageBreak", // 1772 + "lastRow", // 1773 + "lastValue", // 1774 + "lastView", // 1775 + "lat", // 1776 + "latentStyles", // 1777 + "latin", // 1778 + "latinLnBrk", // 1779 + "layout", // 1780 + "layoutDef", // 1781 + "layoutDefHdr", // 1782 + "layoutDefHdrLst", // 1783 + "layoutInCell", // 1784 + "layoutNode", // 1785 + "layoutRawTableWidth", // 1786 + "layoutTableRowsApart", // 1787 + "layoutTarget", // 1788 + "lblAlgn", // 1789 + "lblOffset", // 1790 + "leader", // 1791 + "leaderLines", // 1792 + "left", // 1793 + "leftChars", // 1794 + "leftFromText", // 1795 + "leftLabels", // 1796 + "legacy", // 1797 + "legacyDrawing", // 1798 + "legacyDrawingHF", // 1799 + "legacyIndent", // 1800 + "legacySpace", // 1801 + "legend", // 1802 + "legendEntry", // 1803 + "legendPos", // 1804 + "len", // 1805 + "length", // 1806 + "lengthspecified", // 1807 + "level", // 1808 + "lid", // 1809 + "lightRig", // 1810 + "lightface", // 1811 + "lightharsh", // 1812 + "lightharsh2", // 1813 + "lightlevel", // 1814 + "lightlevel2", // 1815 + "lightposition", // 1816 + "lightposition2", // 1817 + "lim", // 1818 + "limLoc", // 1819 + "limLow", // 1820 + "limLowPr", // 1821 + "limUpp", // 1822 + "limUppPr", // 1823 + "limo", // 1824 + "lin", // 1825 + "linClrLst", // 1826 + "line", // 1827 + "line3DChart", // 1828 + "lineChart", // 1829 + "linePitch", // 1830 + "lineRule", // 1831 + "lineTo", // 1832 + "lineWrapLikeWord6", // 1833 + "lines", // 1834 + "linestyle", // 1835 + "link", // 1836 + "linkStyles", // 1837 + "linkTarget", // 1838 + "linkToQuery", // 1839 + "linkedToFile", // 1840 + "listDataValidation", // 1841 + "listEntry", // 1842 + "listItem", // 1843 + "listSeparator", // 1844 + "lit", // 1845 + "lkTxEntry", // 1846 + "ln", // 1847 + "lnB", // 1848 + "lnBlToTr", // 1849 + "lnDef", // 1850 + "lnL", // 1851 + "lnNumType", // 1852 + "lnR", // 1853 + "lnRef", // 1854 + "lnSpc", // 1855 + "lnSpcReduction", // 1856 + "lnStyleLst", // 1857 + "lnT", // 1858 + "lnTlToBr", // 1859 + "lnTo", // 1860 + "lo", // 1861 + "loCatId", // 1862 + "loTypeId", // 1863 + "local", // 1864 + "localConnection", // 1865 + "localRefresh", // 1866 + "localSheetId", // 1867 + "location", // 1868 + "lock", // 1869 + "lockRevision", // 1870 + "lockStructure", // 1871 + "lockWindows", // 1872 + "locked", // 1873 + "lockedCanvas", // 1874 + "lockrotationcenter", // 1875 + "logBase", // 1876 + "lon", // 1877 + "longFileNames", // 1878 + "longText", // 1879 + "loop", // 1880 + "lowestEdited", // 1881 + "lpstr", // 1882 + "lpwstr", // 1883 + "lsdException", // 1884 + "lstStyle", // 1885 + "lt1", // 1886 + "lt2", // 1887 + "lum", // 1888 + "lumMod", // 1889 + "lumOff", // 1890 + "lvl", // 1891 + "lvl1pPr", // 1892 + "lvl2pPr", // 1893 + "lvl3pPr", // 1894 + "lvl4pPr", // 1895 + "lvl5pPr", // 1896 + "lvl6pPr", // 1897 + "lvl7pPr", // 1898 + "lvl8pPr", // 1899 + "lvl9pPr", // 1900 + "lvlJc", // 1901 + "lvlOverride", // 1902 + "lvlPicBulletId", // 1903 + "lvlRestart", // 1904 + "lvlText", // 1905 + "m", // 1906 + "mPr", // 1907 + "macro", // 1908 + "mailAsAttachment", // 1909 + "mailMerge", // 1910 + "mailSubject", // 1911 + "main", // 1912 + "mainDocumentType", // 1913 + "majorFont", // 1914 + "majorGridlines", // 1915 + "majorTickMark", // 1916 + "majorTimeUnit", // 1917 + "majorUnit", // 1918 + "man", // 1919 + "manifestLocation", // 1920 + "manualBreakCount", // 1921 + "manualLayout", // 1922 + "map", // 1923 + "mapId", // 1924 + "mappedName", // 1925 + "mappingCount", // 1926 + "maps", // 1927 + "marB", // 1928 + "marBottom", // 1929 + "marH", // 1930 + "marL", // 1931 + "marLeft", // 1932 + "marR", // 1933 + "marRight", // 1934 + "marT", // 1935 + "marTop", // 1936 + "marW", // 1937 + "marker", // 1938 + "markup", // 1939 + "master", // 1940 + "masterClrMapping", // 1941 + "masterRel", // 1942 + "matchSrc", // 1943 + "matchingName", // 1944 + "mathFont", // 1945 + "mathPr", // 1946 + "matrix", // 1947 + "max", // 1948 + "maxAng", // 1949 + "maxDate", // 1950 + "maxDist", // 1951 + "maxLength", // 1952 + "maxR", // 1953 + "maxRId", // 1954 + "maxRank", // 1955 + "maxSheetId", // 1956 + "maxSubtotal", // 1957 + "maxVal", // 1958 + "maxValue", // 1959 + "maxX", // 1960 + "maxY", // 1961 + "maximized", // 1962 + "mc", // 1963 + "mcJc", // 1964 + "mcPr", // 1965 + "mcs", // 1966 + "mdx", // 1967 + "mdxMetadata", // 1968 + "mdxSubqueries", // 1969 + "measure", // 1970 + "measureFilter", // 1971 + "measureGroup", // 1972 + "measureGroups", // 1973 + "measures", // 1974 + "member", // 1975 + "memberName", // 1976 + "memberPropertyField", // 1977 + "memberValueDatatype", // 1978 + "members", // 1979 + "merge", // 1980 + "mergeCell", // 1981 + "mergeCells", // 1982 + "mergeInterval", // 1983 + "mergeItem", // 1984 + "metadata", // 1985 + "metadataStrings", // 1986 + "metadataType", // 1987 + "metadataTypes", // 1988 + "metal", // 1989 + "meth", // 1990 + "method", // 1991 + "min", // 1992 + "minAng", // 1993 + "minDate", // 1994 + "minLength", // 1995 + "minR", // 1996 + "minRId", // 1997 + "minRefreshableVersion", // 1998 + "minSubtotal", // 1999 + "minSupportedVersion", // 2000 + "minValue", // 2001 + "minVer", // 2002 + "minX", // 2003 + "minY", // 2004 + "minimized", // 2005 + "minimumVersion", // 2006 + "minorFont", // 2007 + "minorGridlines", // 2008 + "minorTickMark", // 2009 + "minorTimeUnit", // 2010 + "minorUnit", // 2011 + "minus", // 2012 + "minusx", // 2013 + "minusy", // 2014 + "minute", // 2015 + "mirrorIndents", // 2016 + "mirrorMargins", // 2017 + "missingCaption", // 2018 + "missingItemsLimit", // 2019 + "miter", // 2020 + "miterlimit", // 2021 + "mod", // 2022 + "modelId", // 2023 + "modifyVerifier", // 2024 + "month", // 2025 + "monthLong", // 2026 + "monthShort", // 2027 + "moveFrom", // 2028 + "moveFromRangeEnd", // 2029 + "moveFromRangeStart", // 2030 + "moveTo", // 2031 + "moveToRangeEnd", // 2032 + "moveToRangeStart", // 2033 + "moveWith", // 2034 + "movie", // 2035 + "mp", // 2036 + "mpFld", // 2037 + "mpMap", // 2038 + "mps", // 2039 + "mr", // 2040 + "mruColors", // 2041 + "ms", // 2042 + "multiLevelType", // 2043 + "multiLine", // 2044 + "multiLvlStrCache", // 2045 + "multiLvlStrRef", // 2046 + "multipleFieldFilters", // 2047 + "multipleItemSelectionAllowed", // 2048 + "mute", // 2049 + "mwSmallCaps", // 2050 + "n", // 2051 + "name", // 2052 + "nameLen", // 2053 + "namespaceUri", // 2054 + "namespaceuri", // 2055 + "nary", // 2056 + "naryLim", // 2057 + "naryPr", // 2058 + "nc", // 2059 + "ndxf", // 2060 + "neCell", // 2061 + "new", // 2062 + "newLength", // 2063 + "newName", // 2064 + "newsflash", // 2065 + "next", // 2066 + "nextAc", // 2067 + "nextCondLst", // 2068 + "nextId", // 2069 + "nf", // 2070 + "nlCheck", // 2071 + "noAdjustHandles", // 2072 + "noAutofit", // 2073 + "noBorder", // 2074 + "noBreak", // 2075 + "noBreakHyphen", // 2076 + "noChangeArrowheads", // 2077 + "noChangeAspect", // 2078 + "noChangeShapeType", // 2079 + "noColumnBalance", // 2080 + "noCrop", // 2081 + "noDrilldown", // 2082 + "noEditPoints", // 2083 + "noEndCap", // 2084 + "noEndnote", // 2085 + "noExtraLineSpacing", // 2086 + "noFill", // 2087 + "noGrp", // 2088 + "noLabel", // 2089 + "noLeading", // 2090 + "noLineBreaksAfter", // 2091 + "noLineBreaksBefore", // 2092 + "noMove", // 2093 + "noMultiLvlLbl", // 2094 + "noProof", // 2095 + "noPunctuationKerning", // 2096 + "noResize", // 2097 + "noResizeAllowed", // 2098 + "noRot", // 2099 + "noSelect", // 2100 + "noSpaceRaiseLower", // 2101 + "noTabHangInd", // 2102 + "noTextEdit", // 2103 + "noUngrp", // 2104 + "noWrap", // 2105 + "nodePh", // 2106 + "nodeType", // 2107 + "nonAutoSortDefault", // 2108 + "nor", // 2109 + "norm", // 2110 + "normAutofit", // 2111 + "normalViewPr", // 2112 + "normalizeH", // 2113 + "notTrueType", // 2114 + "notes", // 2115 + "notesMaster", // 2116 + "notesMasterId", // 2117 + "notesMasterIdLst", // 2118 + "notesStyle", // 2119 + "notesSz", // 2120 + "notesTextViewPr", // 2121 + "notesViewPr", // 2122 + "np", // 2123 + "ns", // 2124 + "nsid", // 2125 + "null", // 2126 + "num", // 2127 + "numCache", // 2128 + "numCol", // 2129 + "numFmt", // 2130 + "numFmtId", // 2131 + "numFmts", // 2132 + "numId", // 2133 + "numIdMacAtCleanup", // 2134 + "numLit", // 2135 + "numPicBullet", // 2136 + "numPicBulletId", // 2137 + "numPr", // 2138 + "numRef", // 2139 + "numRestart", // 2140 + "numSld", // 2141 + "numStart", // 2142 + "numStyleLink", // 2143 + "numberStoredAsText", // 2144 + "numbering", // 2145 + "numberingChange", // 2146 + "nvCxnSpPr", // 2147 + "nvGraphicFramePr", // 2148 + "nvGrpSpPr", // 2149 + "nvPicPr", // 2150 + "nvPr", // 2151 + "nvSpPr", // 2152 + "nwCell", // 2153 + "o", // 2154 + "oMath", // 2155 + "oMathPara", // 2156 + "oMathParaPr", // 2157 + "objDist", // 2158 + "object", // 2159 + "objectDefaults", // 2160 + "objects", // 2161 + "oblob", // 2162 + "obscured", // 2163 + "oc", // 2164 + "odcFile", // 2165 + "oddFooter", // 2166 + "oddHeader", // 2167 + "odso", // 2168 + "odxf", // 2169 + "ofPieChart", // 2170 + "ofPieType", // 2171 + "off", // 2172 + "offset", // 2173 + "offset2", // 2174 + "offsetFrom", // 2175 + "olapPr", // 2176 + "old", // 2177 + "oldComment", // 2178 + "oldCustomMenu", // 2179 + "oldDescription", // 2180 + "oldFormula", // 2181 + "oldFunction", // 2182 + "oldFunctionGroupId", // 2183 + "oldHelp", // 2184 + "oldHidden", // 2185 + "oldLength", // 2186 + "oldName", // 2187 + "oldPh", // 2188 + "oldQuotePrefix", // 2189 + "oldShortcutKey", // 2190 + "oldStatusBar", // 2191 + "ole", // 2192 + "oleChartEl", // 2193 + "oleItem", // 2194 + "oleItems", // 2195 + "oleLink", // 2196 + "oleObj", // 2197 + "oleObject", // 2198 + "oleObjects", // 2199 + "oleSize", // 2200 + "oleUpdate", // 2201 + "oleicon", // 2202 + "oleid", // 2203 + "on", // 2204 + "oneCellAnchor", // 2205 + "oneField", // 2206 + "oned", // 2207 + "onlySync", // 2208 + "onlyUseConnectionFile", // 2209 + "op", // 2210 + "opEmu", // 2211 + "opacity", // 2212 + "opacity2", // 2213 + "operator", // 2214 + "optimizeForBrowser", // 2215 + "optimizeMemory", // 2216 + "order", // 2217 + "orgChart", // 2218 + "organizeInFolders", // 2219 + "orient", // 2220 + "orientation", // 2221 + "orientationangle", // 2222 + "origin", // 2223 + "original", // 2224 + "ostorage", // 2225 + "ostream", // 2226 + "other", // 2227 + "otherStyle", // 2228 + "outerShdw", // 2229 + "outline", // 2230 + "outlineData", // 2231 + "outlineLevel", // 2232 + "outlineLevelCol", // 2233 + "outlineLevelRow", // 2234 + "outlineLvl", // 2235 + "outlinePr", // 2236 + "outlineSymbols", // 2237 + "outlineViewPr", // 2238 + "oval", // 2239 + "overflowPunct", // 2240 + "overlap", // 2241 + "overlay", // 2242 + "override", // 2243 + "overrideClrMapping", // 2244 + "p", // 2245 + "pBdr", // 2246 + "pLen", // 2247 + "pPos", // 2248 + "pPr", // 2249 + "pPrChange", // 2250 + "pPrDefault", // 2251 + "pRg", // 2252 + "pStyle", // 2253 + "page", // 2254 + "pageBreakBefore", // 2255 + "pageField", // 2256 + "pageFields", // 2257 + "pageItem", // 2258 + "pageMargins", // 2259 + "pageOrder", // 2260 + "pageOverThenDown", // 2261 + "pageSetUpPr", // 2262 + "pageSetup", // 2263 + "pageStyle", // 2264 + "pageWrap", // 2265 + "pages", // 2266 + "pane", // 2267 + "panose", // 2268 + "panose1", // 2269 + "paperSize", // 2270 + "paperSrc", // 2271 + "par", // 2272 + "parTransId", // 2273 + "param", // 2274 + "parameter", // 2275 + "parameterType", // 2276 + "parameters", // 2277 + "parent", // 2278 + "parentSet", // 2279 + "parsePre", // 2280 + "password", // 2281 + "pasteAll", // 2282 + "pasteBorders", // 2283 + "pasteColWidths", // 2284 + "pasteComments", // 2285 + "pasteDataValidation", // 2286 + "pasteFormats", // 2287 + "pasteFormulas", // 2288 + "pasteNumberFormats", // 2289 + "pasteValues", // 2290 + "path", // 2291 + "pathEditMode", // 2292 + "pathLst", // 2293 + "pattFill", // 2294 + "patternFill", // 2295 + "patternType", // 2296 + "penClr", // 2297 + "percent", // 2298 + "period", // 2299 + "permEnd", // 2300 + "permStart", // 2301 + "personal", // 2302 + "personalCompose", // 2303 + "personalReply", // 2304 + "personalView", // 2305 + "perspective", // 2306 + "pgBorders", // 2307 + "pgMar", // 2308 + "pgNum", // 2309 + "pgNumType", // 2310 + "pgSz", // 2311 + "ph", // 2312 + "phant", // 2313 + "phantPr", // 2314 + "phldr", // 2315 + "phldrT", // 2316 + "phonetic", // 2317 + "phoneticPr", // 2318 + "photoAlbum", // 2319 + "pic", // 2320 + "picLocks", // 2321 + "pict", // 2322 + "picture", // 2323 + "pictureFormat", // 2324 + "pictureOptions", // 2325 + "pictureStackUnit", // 2326 + "pid", // 2327 + "pie3DChart", // 2328 + "pieChart", // 2329 + "pitch", // 2330 + "pitchFamily", // 2331 + "pivot", // 2332 + "pivotArea", // 2333 + "pivotAreas", // 2334 + "pivotButton", // 2335 + "pivotCache", // 2336 + "pivotCacheDefinition", // 2337 + "pivotCacheRecords", // 2338 + "pivotCaches", // 2339 + "pivotField", // 2340 + "pivotFields", // 2341 + "pivotFmt", // 2342 + "pivotFmts", // 2343 + "pivotHierarchies", // 2344 + "pivotHierarchy", // 2345 + "pivotSelection", // 2346 + "pivotSource", // 2347 + "pivotTableDefinition", // 2348 + "pivotTableStyle", // 2349 + "pivotTableStyleInfo", // 2350 + "pivotTables", // 2351 + "pixelsPerInch", // 2352 + "placeholder", // 2353 + "plane", // 2354 + "plcHide", // 2355 + "plotArea", // 2356 + "plotVisOnly", // 2357 + "plus", // 2358 + "points", // 2359 + "polar", // 2360 + "polyline", // 2361 + "pos", // 2362 + "posOffset", // 2363 + "position", // 2364 + "positionH", // 2365 + "positionV", // 2366 + "post", // 2367 + "postSp", // 2368 + "prLst", // 2369 + "prSet", // 2370 + "preSp", // 2371 + "preferPic", // 2372 + "preferRelativeResize", // 2373 + "preferSingleView", // 2374 + "preferrelative", // 2375 + "prefixMappings", // 2376 + "presAssocID", // 2377 + "presId", // 2378 + "presLayoutVars", // 2379 + "presName", // 2380 + "presOf", // 2381 + "presStyleCnt", // 2382 + "presStyleIdx", // 2383 + "presStyleLbl", // 2384 + "present", // 2385 + "presentation", // 2386 + "presentationPr", // 2387 + "preserve", // 2388 + "preserveFormatting", // 2389 + "preserveHistory", // 2390 + "preserveSortFilterLayout", // 2391 + "presetClass", // 2392 + "presetID", // 2393 + "presetSubtype", // 2394 + "prevAc", // 2395 + "prevCondLst", // 2396 + "previousCol", // 2397 + "previousRow", // 2398 + "pri", // 2399 + "print", // 2400 + "printArea", // 2401 + "printBodyTextBeforeHeader", // 2402 + "printColBlack", // 2403 + "printDrill", // 2404 + "printFormsData", // 2405 + "printFractionalCharacterWidth", // 2406 + "printOptions", // 2407 + "printPostScriptOverText", // 2408 + "printSettings", // 2409 + "printTwoOnOne", // 2410 + "printerSettings", // 2411 + "priority", // 2412 + "prnPr", // 2413 + "prnWhat", // 2414 + "productSubtotal", // 2415 + "progId", // 2416 + "progress", // 2417 + "prompt", // 2418 + "promptTitle", // 2419 + "promptedSolutions", // 2420 + "proofErr", // 2421 + "proofState", // 2422 + "property", // 2423 + "propertyName", // 2424 + "protected", // 2425 + "protectedRange", // 2426 + "protectedRanges", // 2427 + "protection", // 2428 + "provid", // 2429 + "proxy", // 2430 + "prst", // 2431 + "prstClr", // 2432 + "prstDash", // 2433 + "prstGeom", // 2434 + "prstMaterial", // 2435 + "prstShdw", // 2436 + "prstTxWarp", // 2437 + "pt", // 2438 + "ptCount", // 2439 + "ptLst", // 2440 + "ptType", // 2441 + "ptab", // 2442 + "ptsTypes", // 2443 + "pubBrowser", // 2444 + "publishItems", // 2445 + "publishToServer", // 2446 + "published", // 2447 + "pull", // 2448 + "push", // 2449 + "qFormat", // 2450 + "qs", // 2451 + "qsCatId", // 2452 + "qsTypeId", // 2453 + "quadBezTo", // 2454 + "qualifier", // 2455 + "query", // 2456 + "queryCache", // 2457 + "queryFailed", // 2458 + "queryTable", // 2459 + "queryTableDeletedFields", // 2460 + "queryTableField", // 2461 + "queryTableFieldId", // 2462 + "queryTableFields", // 2463 + "queryTableRefresh", // 2464 + "quickTimeFile", // 2465 + "quotePrefix", // 2466 + "r", // 2467 + "r1", // 2468 + "r2", // 2469 + "r4", // 2470 + "r8", // 2471 + "rAng", // 2472 + "rAngAx", // 2473 + "rCtr", // 2474 + "rFont", // 2475 + "rFonts", // 2476 + "rId", // 2477 + "rIns", // 2478 + "rMargin", // 2479 + "rPh", // 2480 + "rPr", // 2481 + "rPrChange", // 2482 + "rPrDefault", // 2483 + "rSp", // 2484 + "rSpRule", // 2485 + "rStyle", // 2486 + "ra", // 2487 + "rad", // 2488 + "radPr", // 2489 + "radarChart", // 2490 + "radarStyle", // 2491 + "radiusrange", // 2492 + "raf", // 2493 + "random", // 2494 + "randomBar", // 2495 + "rangePr", // 2496 + "rangeSet", // 2497 + "rangeSets", // 2498 + "rank", // 2499 + "rankBy", // 2500 + "rc", // 2501 + "rcc", // 2502 + "rcft", // 2503 + "rcmt", // 2504 + "rctx", // 2505 + "rcv", // 2506 + "rdn", // 2507 + "readModeInkLockDown", // 2508 + "readOnlyRecommended", // 2509 + "readingOrder", // 2510 + "recipientData", // 2511 + "recipients", // 2512 + "recolor", // 2513 + "recolortarget", // 2514 + "recommended", // 2515 + "reconnectionMethod", // 2516 + "recordCount", // 2517 + "rect", // 2518 + "red", // 2519 + "redMod", // 2520 + "redOff", // 2521 + "ref", // 2522 + "ref3D", // 2523 + "refFor", // 2524 + "refForName", // 2525 + "refMode", // 2526 + "refPtType", // 2527 + "refType", // 2528 + "reference", // 2529 + "references", // 2530 + "refersTo", // 2531 + "reflection", // 2532 + "refreshAllConnections", // 2533 + "refreshError", // 2534 + "refreshOnChange", // 2535 + "refreshOnLoad", // 2536 + "refreshedBy", // 2537 + "refreshedDate", // 2538 + "refreshedVersion", // 2539 + "regroupid", // 2540 + "regrouptable", // 2541 + "regular", // 2542 + "rel", // 2543 + "relIds", // 2544 + "relOff", // 2545 + "relSizeAnchor", // 2546 + "relation", // 2547 + "relationtable", // 2548 + "relative", // 2549 + "relativeFrom", // 2550 + "relativeHeight", // 2551 + "relativeIndent", // 2552 + "relativeTo", // 2553 + "relid", // 2554 + "relyOnVML", // 2555 + "relyOnVml", // 2556 + "removeDataOnSave", // 2557 + "removeDateAndTime", // 2558 + "removePersonalInfoOnSave", // 2559 + "removePersonalInformation", // 2560 + "render", // 2561 + "repairLoad", // 2562 + "repeatCount", // 2563 + "repeatDur", // 2564 + "resId", // 2565 + "reservationPassword", // 2566 + "resizeGraphics", // 2567 + "resizeHandles", // 2568 + "restart", // 2569 + "restoredLeft", // 2570 + "restoredTop", // 2571 + "result", // 2572 + "rev", // 2573 + "reverse", // 2574 + "reviewed", // 2575 + "reviewedList", // 2576 + "revisionId", // 2577 + "revisionView", // 2578 + "revisions", // 2579 + "revisionsPassword", // 2580 + "rfmt", // 2581 + "rgb", // 2582 + "rgbColor", // 2583 + "rich", // 2584 + "richText", // 2585 + "rig", // 2586 + "right", // 2587 + "rightChars", // 2588 + "rightFromText", // 2589 + "rightToLeft", // 2590 + "ris", // 2591 + "rm", // 2592 + "rot", // 2593 + "rotWithShape", // 2594 + "rotX", // 2595 + "rotY", // 2596 + "rotate", // 2597 + "rotation", // 2598 + "rotationangle", // 2599 + "rotationcenter", // 2600 + "round", // 2601 + "roundedCorners", // 2602 + "roundrect", // 2603 + "row", // 2604 + "rowBreaks", // 2605 + "rowColShift", // 2606 + "rowDrillCount", // 2607 + "rowFields", // 2608 + "rowGrandTotals", // 2609 + "rowHeaderCaption", // 2610 + "rowHierarchiesUsage", // 2611 + "rowHierarchyUsage", // 2612 + "rowItems", // 2613 + "rowNumbers", // 2614 + "rowOff", // 2615 + "rowPageCount", // 2616 + "rowSpan", // 2617 + "rows", // 2618 + "rqt", // 2619 + "rrc", // 2620 + "rsid", // 2621 + "rsidDel", // 2622 + "rsidP", // 2623 + "rsidR", // 2624 + "rsidRDefault", // 2625 + "rsidRPr", // 2626 + "rsidRoot", // 2627 + "rsidSect", // 2628 + "rsidTr", // 2629 + "rsids", // 2630 + "rsnm", // 2631 + "rt", // 2632 + "rtl", // 2633 + "rtlCol", // 2634 + "rtlGutter", // 2635 + "rtn", // 2636 + "ruby", // 2637 + "rubyAlign", // 2638 + "rubyBase", // 2639 + "rubyPr", // 2640 + "rule", // 2641 + "ruleLst", // 2642 + "rules", // 2643 + "rupBuild", // 2644 + "s", // 2645 + "sId", // 2646 + "sPre", // 2647 + "sPrePr", // 2648 + "sSub", // 2649 + "sSubPr", // 2650 + "sSubSup", // 2651 + "sSubSupPr", // 2652 + "sSup", // 2653 + "sSupPr", // 2654 + "salt", // 2655 + "saltData", // 2656 + "sampData", // 2657 + "sat", // 2658 + "satMod", // 2659 + "satOff", // 2660 + "saveData", // 2661 + "saveExternalLinkValues", // 2662 + "saveFormsData", // 2663 + "saveInvalidXml", // 2664 + "savePassword", // 2665 + "savePreviewPicture", // 2666 + "saveSmartTagsAsXml", // 2667 + "saveSubsetFonts", // 2668 + "saveThroughXslt", // 2669 + "saveXmlDataOnly", // 2670 + "sb", // 2671 + "scale", // 2672 + "scaleToFitPaper", // 2673 + "scaleWithDoc", // 2674 + "scaled", // 2675 + "scaling", // 2676 + "scatterChart", // 2677 + "scatterStyle", // 2678 + "scenario", // 2679 + "scenarios", // 2680 + "scene3d", // 2681 + "schema", // 2682 + "schemaLibrary", // 2683 + "schemaLocation", // 2684 + "schemaRef", // 2685 + "schemaRefs", // 2686 + "scheme", // 2687 + "schemeClr", // 2688 + "scope", // 2689 + "scr", // 2690 + "scrgbClr", // 2691 + "script", // 2692 + "scrollbar", // 2693 + "sd", // 2694 + "sdt", // 2695 + "sdtContent", // 2696 + "sdtEndPr", // 2697 + "sdtPr", // 2698 + "seCell", // 2699 + "second", // 2700 + "secondPiePt", // 2701 + "secondPieSize", // 2702 + "sectPr", // 2703 + "sectPrChange", // 2704 + "securityDescriptor", // 2705 + "selectFldWithFirstOrLastChar", // 2706 + "selectLockedCells", // 2707 + "selectUnlockedCells", // 2708 + "selected", // 2709 + "selection", // 2710 + "semiHidden", // 2711 + "semicolon", // 2712 + "sendLocale", // 2713 + "sep", // 2714 + "sepChr", // 2715 + "separator", // 2716 + "seq", // 2717 + "ser", // 2718 + "serAx", // 2719 + "serLines", // 2720 + "series", // 2721 + "seriesIdx", // 2722 + "serverCommand", // 2723 + "serverField", // 2724 + "serverFill", // 2725 + "serverFont", // 2726 + "serverFontColor", // 2727 + "serverFormat", // 2728 + "serverFormats", // 2729 + "serverNumberFormat", // 2730 + "serverSldId", // 2731 + "serverSldModifiedTime", // 2732 + "serverZoom", // 2733 + "set", // 2734 + "setDefinition", // 2735 + "sets", // 2736 + "settings", // 2737 + "shade", // 2738 + "shadeToTitle", // 2739 + "shadow", // 2740 + "shadowcolor", // 2741 + "shadowok", // 2742 + "shape", // 2743 + "shapeDefaults", // 2744 + "shapeId", // 2745 + "shapeLayoutLikeWW8", // 2746 + "shapedefaults", // 2747 + "shapeid", // 2748 + "shapelayout", // 2749 + "shapetype", // 2750 + "shared", // 2751 + "sharedItems", // 2752 + "shd", // 2753 + "sheet", // 2754 + "sheetCalcPr", // 2755 + "sheetData", // 2756 + "sheetDataSet", // 2757 + "sheetFormatPr", // 2758 + "sheetId", // 2759 + "sheetIdMap", // 2760 + "sheetName", // 2761 + "sheetNames", // 2762 + "sheetPosition", // 2763 + "sheetPr", // 2764 + "sheetProtection", // 2765 + "sheetView", // 2766 + "sheetViews", // 2767 + "sheets", // 2768 + "shininess", // 2769 + "shortcutKey", // 2770 + "show", // 2771 + "showAll", // 2772 + "showAnimation", // 2773 + "showAsCaption", // 2774 + "showAsIcon", // 2775 + "showAutoFilter", // 2776 + "showBorderUnselectedTables", // 2777 + "showBreaksInFrames", // 2778 + "showBubbleSize", // 2779 + "showButton", // 2780 + "showCalcMbrs", // 2781 + "showCaptions", // 2782 + "showCatName", // 2783 + "showCell", // 2784 + "showColHeaders", // 2785 + "showColStripes", // 2786 + "showColumnStripes", // 2787 + "showComments", // 2788 + "showDLblsOverMax", // 2789 + "showDataAs", // 2790 + "showDataDropDown", // 2791 + "showDataTips", // 2792 + "showDrill", // 2793 + "showDropDown", // 2794 + "showDropDowns", // 2795 + "showDropZones", // 2796 + "showEmptyCol", // 2797 + "showEmptyRow", // 2798 + "showEnvelope", // 2799 + "showError", // 2800 + "showErrorMessage", // 2801 + "showFirstColumn", // 2802 + "showFormatting", // 2803 + "showFormulaBar", // 2804 + "showFormulas", // 2805 + "showGridLines", // 2806 + "showGuides", // 2807 + "showHeader", // 2808 + "showHeaders", // 2809 + "showHorizontalScroll", // 2810 + "showHorzBorder", // 2811 + "showInFieldList", // 2812 + "showInkAnnotation", // 2813 + "showInputMessage", // 2814 + "showItems", // 2815 + "showKeys", // 2816 + "showLastColumn", // 2817 + "showLeaderLines", // 2818 + "showLegendKey", // 2819 + "showMasterPhAnim", // 2820 + "showMasterSp", // 2821 + "showMemberPropertyTips", // 2822 + "showMissing", // 2823 + "showMultipleLabel", // 2824 + "showNarration", // 2825 + "showNegBubbles", // 2826 + "showObjects", // 2827 + "showOutline", // 2828 + "showOutlineIcons", // 2829 + "showOutlineSymbols", // 2830 + "showPageBreaks", // 2831 + "showPercent", // 2832 + "showPivotChartFilter", // 2833 + "showPr", // 2834 + "showPropAsCaption", // 2835 + "showPropCell", // 2836 + "showPropTip", // 2837 + "showRowCol", // 2838 + "showRowColHeaders", // 2839 + "showRowHeaders", // 2840 + "showRowStripes", // 2841 + "showRuler", // 2842 + "showScrollbar", // 2843 + "showSerName", // 2844 + "showSheetTabs", // 2845 + "showSpeakerNotes", // 2846 + "showSpecialPlsOnTitleSld", // 2847 + "showStatusbar", // 2848 + "showTip", // 2849 + "showVal", // 2850 + "showValue", // 2851 + "showVertBorder", // 2852 + "showVerticalScroll", // 2853 + "showWhenStopped", // 2854 + "showWhiteSpace", // 2855 + "showXMLTags", // 2856 + "showZeros", // 2857 + "showingPlcHdr", // 2858 + "showsigndate", // 2859 + "shp", // 2860 + "shrinkToFit", // 2861 + "si", // 2862 + "sibTransId", // 2863 + "side", // 2864 + "sideWall", // 2865 + "sig", // 2866 + "signatureline", // 2867 + "signinginstructions", // 2868 + "signinginstructionsset", // 2869 + "sigprovurl", // 2870 + "simplePos", // 2871 + "singleSignOnId", // 2872 + "singleXmlCell", // 2873 + "singleXmlCells", // 2874 + "singleclick", // 2875 + "size", // 2876 + "sizeAuto", // 2877 + "sizeRepresents", // 2878 + "skew", // 2879 + "skewamt", // 2880 + "skewangle", // 2881 + "sld", // 2882 + "sldAll", // 2883 + "sldId", // 2884 + "sldIdLst", // 2885 + "sldLayout", // 2886 + "sldLayoutId", // 2887 + "sldLayoutIdLst", // 2888 + "sldLst", // 2889 + "sldMaster", // 2890 + "sldMasterId", // 2891 + "sldMasterIdLst", // 2892 + "sldNum", // 2893 + "sldRg", // 2894 + "sldSyncPr", // 2895 + "sldSz", // 2896 + "sldTgt", // 2897 + "slideViewPr", // 2898 + "smallCaps", // 2899 + "smallFrac", // 2900 + "smartTag", // 2901 + "smartTagPr", // 2902 + "smartTagType", // 2903 + "smartTagTypes", // 2904 + "smartTags", // 2905 + "smooth", // 2906 + "smtClean", // 2907 + "smtId", // 2908 + "snapToGrid", // 2909 + "snapToObjects", // 2910 + "snapVertSplitter", // 2911 + "snd", // 2912 + "sndAc", // 2913 + "sndTgt", // 2914 + "softEdge", // 2915 + "softHyphen", // 2916 + "solidFill", // 2917 + "solutionID", // 2918 + "solveOrder", // 2919 + "sort", // 2920 + "sortBy", // 2921 + "sortByTuple", // 2922 + "sortCondition", // 2923 + "sortMethod", // 2924 + "sortState", // 2925 + "sortType", // 2926 + "sorterViewPr", // 2927 + "source", // 2928 + "sourceData", // 2929 + "sourceFile", // 2930 + "sourceFileName", // 2931 + "sourceLinked", // 2932 + "sourceObject", // 2933 + "sourceRef", // 2934 + "sourceSheetId", // 2935 + "sourceType", // 2936 + "sp", // 2937 + "sp3d", // 2938 + "spAutoFit", // 2939 + "spDef", // 2940 + "spLocks", // 2941 + "spPr", // 2942 + "spTgt", // 2943 + "spTree", // 2944 + "space", // 2945 + "spaceForUL", // 2946 + "spacing", // 2947 + "spacingInWholePoints", // 2948 + "spans", // 2949 + "spc", // 2950 + "spcAft", // 2951 + "spcBef", // 2952 + "spcCol", // 2953 + "spcFirstLastPara", // 2954 + "spcPct", // 2955 + "spcPts", // 2956 + "spd", // 2957 + "specVanish", // 2958 + "specularity", // 2959 + "spelling", // 2960 + "spid", // 2961 + "spidmax", // 2962 + "spinCount", // 2963 + "split", // 2964 + "splitAll", // 2965 + "splitFirst", // 2966 + "splitPgBreakAndParaMark", // 2967 + "splitPos", // 2968 + "splitType", // 2969 + "spokes", // 2970 + "spt", // 2971 + "sqlType", // 2972 + "sqref", // 2973 + "src", // 2974 + "srcId", // 2975 + "srcOrd", // 2976 + "srcRect", // 2977 + "srgbClr", // 2978 + "sst", // 2979 + "st", // 2980 + "stA", // 2981 + "stAng", // 2982 + "stCondLst", // 2983 + "stCxn", // 2984 + "stPos", // 2985 + "stSnd", // 2986 + "start", // 2987 + "startAngle", // 2988 + "startAt", // 2989 + "startDate", // 2990 + "startNum", // 2991 + "startOverride", // 2992 + "startarrow", // 2993 + "startarrowlength", // 2994 + "startarrowwidth", // 2995 + "state", // 2996 + "status", // 2997 + "statusBar", // 2998 + "statusText", // 2999 + "stdDev", // 3000 + "stdDevPSubtotal", // 3001 + "stdDevSubtotal", // 3002 + "step", // 3003 + "stockChart", // 3004 + "stop", // 3005 + "stopIfTrue", // 3006 + "storage", // 3007 + "storeItemID", // 3008 + "storeMappedDataAs", // 3009 + "stp", // 3010 + "strCache", // 3011 + "strLit", // 3012 + "strRef", // 3013 + "strVal", // 3014 + "stream", // 3015 + "stretch", // 3016 + "strictFirstAndLastChars", // 3017 + "strike", // 3018 + "strikeBLTR", // 3019 + "strikeH", // 3020 + "strikeTLBR", // 3021 + "strikeV", // 3022 + "string", // 3023 + "stringValue1", // 3024 + "stringValue2", // 3025 + "strips", // 3026 + "stroke", // 3027 + "strokecolor", // 3028 + "stroked", // 3029 + "strokeok", // 3030 + "strokeweight", // 3031 + "sty", // 3032 + "style", // 3033 + "styleData", // 3034 + "styleDef", // 3035 + "styleDefHdr", // 3036 + "styleDefHdrLst", // 3037 + "styleId", // 3038 + "styleLbl", // 3039 + "styleLink", // 3040 + "styleLockQFSet", // 3041 + "styleLockTheme", // 3042 + "styleName", // 3043 + "stylePaneFormatFilter", // 3044 + "stylePaneSortMethod", // 3045 + "styleSheet", // 3046 + "styles", // 3047 + "sub", // 3048 + "subDoc", // 3049 + "subFontBySize", // 3050 + "subHide", // 3051 + "subSp", // 3052 + "subTnLst", // 3053 + "subsetted", // 3054 + "subtotal", // 3055 + "subtotalCaption", // 3056 + "subtotalHiddenItems", // 3057 + "subtotalTop", // 3058 + "suff", // 3059 + "suggestedsigner", // 3060 + "suggestedsigner2", // 3061 + "suggestedsigneremail", // 3062 + "sumSubtotal", // 3063 + "summaryBelow", // 3064 + "summaryLength", // 3065 + "summaryRight", // 3066 + "sup", // 3067 + "supHide", // 3068 + "supportAdvancedDrill", // 3069 + "supportSubquery", // 3070 + "suppressAutoHyphens", // 3071 + "suppressBottomSpacing", // 3072 + "suppressLineNumbers", // 3073 + "suppressOverlap", // 3074 + "suppressSpBfAfterPgBrk", // 3075 + "suppressSpacingAtTopOfPage", // 3076 + "suppressTopSpacing", // 3077 + "suppressTopSpacingWP", // 3078 + "surface3DChart", // 3079 + "surfaceChart", // 3080 + "swAng", // 3081 + "swCell", // 3082 + "swapBordersFacingPages", // 3083 + "switch", // 3084 + "sx", // 3085 + "sy", // 3086 + "sym", // 3087 + "symbol", // 3088 + "syncBehavior", // 3089 + "syncHorizontal", // 3090 + "syncRef", // 3091 + "syncVertical", // 3092 + "sysClr", // 3093 + "sz", // 3094 + "szCs", // 3095 + "t", // 3096 + "t1", // 3097 + "t2", // 3098 + "tIns", // 3099 + "tab", // 3100 + "tabColor", // 3101 + "tabLst", // 3102 + "tabRatio", // 3103 + "tabSelected", // 3104 + "table", // 3105 + "tableBorderDxfId", // 3106 + "tableColumn", // 3107 + "tableColumnId", // 3108 + "tableColumns", // 3109 + "tablePart", // 3110 + "tableParts", // 3111 + "tableStyle", // 3112 + "tableStyleElement", // 3113 + "tableStyleId", // 3114 + "tableStyleInfo", // 3115 + "tableStyles", // 3116 + "tableType", // 3117 + "tablelimits", // 3118 + "tableproperties", // 3119 + "tables", // 3120 + "tabs", // 3121 + "tag", // 3122 + "tagLst", // 3123 + "tags", // 3124 + "tailEnd", // 3125 + "target", // 3126 + "targetScreenSize", // 3127 + "targetScreenSz", // 3128 + "targetscreensize", // 3129 + "tav", // 3130 + "tavLst", // 3131 + "tbl", // 3132 + "tblBg", // 3133 + "tblBorders", // 3134 + "tblCellMar", // 3135 + "tblCellSpacing", // 3136 + "tblGrid", // 3137 + "tblGridChange", // 3138 + "tblHeader", // 3139 + "tblInd", // 3140 + "tblLayout", // 3141 + "tblLook", // 3142 + "tblOverlap", // 3143 + "tblPr", // 3144 + "tblPrChange", // 3145 + "tblPrEx", // 3146 + "tblPrExChange", // 3147 + "tblStyle", // 3148 + "tblStyleColBandSize", // 3149 + "tblStyleLst", // 3150 + "tblStylePr", // 3151 + "tblStyleRowBandSize", // 3152 + "tblW", // 3153 + "tblpPr", // 3154 + "tblpX", // 3155 + "tblpXSpec", // 3156 + "tblpY", // 3157 + "tblpYSpec", // 3158 + "tc", // 3159 + "tcBdr", // 3160 + "tcBorders", // 3161 + "tcFitText", // 3162 + "tcMar", // 3163 + "tcPr", // 3164 + "tcPrChange", // 3165 + "tcStyle", // 3166 + "tcTxStyle", // 3167 + "tcW", // 3168 + "temporary", // 3169 + "tentative", // 3170 + "text", // 3171 + "textAlignment", // 3172 + "textDates", // 3173 + "textDirection", // 3174 + "textField", // 3175 + "textFields", // 3176 + "textInput", // 3177 + "textPr", // 3178 + "textRotation", // 3179 + "textborder", // 3180 + "textbox", // 3181 + "textboxTightWrap", // 3182 + "textboxrect", // 3183 + "textdata", // 3184 + "textlink", // 3185 + "textpath", // 3186 + "textpathok", // 3187 + "tgtEl", // 3188 + "tgtFrame", // 3189 + "theme", // 3190 + "themeColor", // 3191 + "themeElements", // 3192 + "themeFill", // 3193 + "themeFillShade", // 3194 + "themeFillTint", // 3195 + "themeFontLang", // 3196 + "themeManager", // 3197 + "themeOverride", // 3198 + "themeShade", // 3199 + "themeTint", // 3200 + "thickBot", // 3201 + "thickBottom", // 3202 + "thickTop", // 3203 + "thicket", // 3204 + "thickness", // 3205 + "thousands", // 3206 + "thresh", // 3207 + "thruBlk", // 3208 + "tickLblPos", // 3209 + "tickLblSkip", // 3210 + "tickMarkSkip", // 3211 + "tile", // 3212 + "tileRect", // 3213 + "time", // 3214 + "timePeriod", // 3215 + "timing", // 3216 + "tint", // 3217 + "title", // 3218 + "titlePg", // 3219 + "titleStyle", // 3220 + "tl2br", // 3221 + "tm", // 3222 + "tmAbs", // 3223 + "tmFilter", // 3224 + "tmPct", // 3225 + "tmpl", // 3226 + "tmplLst", // 3227 + "tn", // 3228 + "tnLst", // 3229 + "to", // 3230 + "tooltip", // 3231 + "top", // 3232 + "top10", // 3233 + "topAutoShow", // 3234 + "topFromText", // 3235 + "topLabels", // 3236 + "topLeftCell", // 3237 + "topLinePunct", // 3238 + "totalsRowBorderDxfId", // 3239 + "totalsRowCellStyle", // 3240 + "totalsRowCount", // 3241 + "totalsRowDxfId", // 3242 + "totalsRowFormula", // 3243 + "totalsRowFunction", // 3244 + "totalsRowLabel", // 3245 + "totalsRowShown", // 3246 + "tp", // 3247 + "tpl", // 3248 + "tplc", // 3249 + "tpls", // 3250 + "tr", // 3251 + "tr2bl", // 3252 + "trHeight", // 3253 + "trPr", // 3254 + "trPrChange", // 3255 + "track", // 3256 + "trackRevisions", // 3257 + "transition", // 3258 + "transitionEntry", // 3259 + "transitionEvaluation", // 3260 + "transp", // 3261 + "trend", // 3262 + "trendline", // 3263 + "trendlineLbl", // 3264 + "trendlineType", // 3265 + "trim", // 3266 + "truncateFontHeightsLikeWP6", // 3267 + "tupleCache", // 3268 + "twoCellAnchor", // 3269 + "twoDigitTextYear", // 3270 + "tx", // 3271 + "tx1", // 3272 + "tx2", // 3273 + "txBody", // 3274 + "txBox", // 3275 + "txDef", // 3276 + "txEffectClrLst", // 3277 + "txEl", // 3278 + "txFillClrLst", // 3279 + "txLinClrLst", // 3280 + "txPr", // 3281 + "txSp", // 3282 + "txStyles", // 3283 + "txbxContent", // 3284 + "ty", // 3285 + "type", // 3286 + "typeface", // 3287 + "types", // 3288 + "u", // 3289 + "uBounds", // 3290 + "uFill", // 3291 + "uFillTx", // 3292 + "uLn", // 3293 + "uLnTx", // 3294 + "ua", // 3295 + "udl", // 3296 + "ui1", // 3297 + "ui2", // 3298 + "ui4", // 3299 + "ui8", // 3300 + "uiCompat97To2003", // 3301 + "uiExpand", // 3302 + "uiPriority", // 3303 + "uint", // 3304 + "ulTrailSpace", // 3305 + "un", // 3306 + "unbalanced", // 3307 + "unbalancedGroup", // 3308 + "unboundColumnsLeft", // 3309 + "unboundColumnsRight", // 3310 + "underlineTabInNumList", // 3311 + "undo", // 3312 + "undone", // 3313 + "ungrouping", // 3314 + "unhideWhenUsed", // 3315 + "uniqueCount", // 3316 + "uniqueId", // 3317 + "uniqueList", // 3318 + "uniqueMemberProperty", // 3319 + "uniqueName", // 3320 + "uniqueParent", // 3321 + "uniqueTag", // 3322 + "unlockedFormula", // 3323 + "up", // 3324 + "upBars", // 3325 + "upDownBars", // 3326 + "updateAutomatic", // 3327 + "updateFields", // 3328 + "updateLinks", // 3329 + "updatedVersion", // 3330 + "upgradeOnRefresh", // 3331 + "upright", // 3332 + "uri", // 3333 + "url", // 3334 + "usb0", // 3335 + "usb1", // 3336 + "usb2", // 3337 + "usb3", // 3338 + "useA", // 3339 + "useAltKinsokuLineBreakRules", // 3340 + "useAnsiKerningPairs", // 3341 + "useAutoFormatting", // 3342 + "useBgFill", // 3343 + "useDef", // 3344 + "useFELayout", // 3345 + "useFirstPageNumber", // 3346 + "useLongFilenames", // 3347 + "useNormalStyleForList", // 3348 + "usePrinterDefaults", // 3349 + "usePrinterMetrics", // 3350 + "useSingleBorderforContiguousCells", // 3351 + "useSpRect", // 3352 + "useTimings", // 3353 + "useWord2002TableStyleRules", // 3354 + "useWord97LineBreakRules", // 3355 + "useXSLTWhenSaving", // 3356 + "user", // 3357 + "userDrawn", // 3358 + "userInfo", // 3359 + "userInterface", // 3360 + "userName", // 3361 + "userShapes", // 3362 + "userdrawn", // 3363 + "userhidden", // 3364 + "users", // 3365 + "v", // 3366 + "vAlign", // 3367 + "vAnchor", // 3368 + "vMerge", // 3369 + "vMergeOrig", // 3370 + "vSpace", // 3371 + "vacatedStyle", // 3372 + "val", // 3373 + "valAx", // 3374 + "value", // 3375 + "valueMetadata", // 3376 + "valueType", // 3377 + "values", // 3378 + "vanish", // 3379 + "varLst", // 3380 + "varPSubtotal", // 3381 + "varScale", // 3382 + "varSubtotal", // 3383 + "variant", // 3384 + "varyColors", // 3385 + "vbProcedure", // 3386 + "vector", // 3387 + "vendorID", // 3388 + "version", // 3389 + "vert", // 3390 + "vertAlign", // 3391 + "vertAnchor", // 3392 + "vertBarState", // 3393 + "vertCompress", // 3394 + "vertJc", // 3395 + "vertOverflow", // 3396 + "vertical", // 3397 + "verticalCentered", // 3398 + "verticalDpi", // 3399 + "verticies", // 3400 + "video", // 3401 + "videoFile", // 3402 + "view", // 3403 + "view3D", // 3404 + "viewMergedData", // 3405 + "viewPr", // 3406 + "viewpoint", // 3407 + "viewpointorigin", // 3408 + "visibility", // 3409 + "visualTotals", // 3410 + "vm", // 3411 + "vml", // 3412 + "vocabulary", // 3413 + "vol", // 3414 + "volType", // 3415 + "volTypes", // 3416 + "vstream", // 3417 + "w", // 3418 + "wAfter", // 3419 + "wBefore", // 3420 + "wMode", // 3421 + "wR", // 3422 + "wavAudioFile", // 3423 + "webHidden", // 3424 + "webPr", // 3425 + "webPublishItem", // 3426 + "webPublishItems", // 3427 + "webPublishObject", // 3428 + "webPublishObjects", // 3429 + "webPublishing", // 3430 + "webSettings", // 3431 + "wedge", // 3432 + "weight", // 3433 + "wheel", // 3434 + "whole", // 3435 + "wholeTbl", // 3436 + "widowControl", // 3437 + "width", // 3438 + "windowHeight", // 3439 + "windowProtection", // 3440 + "windowWidth", // 3441 + "wipe", // 3442 + "wireframe", // 3443 + "wordWrap", // 3444 + "workbook", // 3445 + "workbookParameter", // 3446 + "workbookPassword", // 3447 + "workbookPr", // 3448 + "workbookProtection", // 3449 + "workbookView", // 3450 + "workbookViewId", // 3451 + "worksheet", // 3452 + "worksheetSource", // 3453 + "wpJustification", // 3454 + "wpSpaceWidth", // 3455 + "wrap", // 3456 + "wrapIndent", // 3457 + "wrapNone", // 3458 + "wrapPolygon", // 3459 + "wrapRight", // 3460 + "wrapSquare", // 3461 + "wrapText", // 3462 + "wrapThrough", // 3463 + "wrapTight", // 3464 + "wrapTopAndBottom", // 3465 + "wrapTrailSpaces", // 3466 + "wrapcoords", // 3467 + "writeProtection", // 3468 + "wsDr", // 3469 + "x", // 3470 + "xAlign", // 3471 + "xMode", // 3472 + "xSplit", // 3473 + "xVal", // 3474 + "xWindow", // 3475 + "xf", // 3476 + "xfDxf", // 3477 + "xfId", // 3478 + "xfrm", // 3479 + "xfrmType", // 3480 + "xl2000", // 3481 + "xl97", // 3482 + "xlm", // 3483 + "xml", // 3484 + "xmlBased", // 3485 + "xmlCellPr", // 3486 + "xmlColumnPr", // 3487 + "xmlDataType", // 3488 + "xmlPr", // 3489 + "xpath", // 3490 + "xrange", // 3491 + "xscale", // 3492 + "y", // 3493 + "yAlign", // 3494 + "yMode", // 3495 + "ySplit", // 3496 + "yVal", // 3497 + "yWindow", // 3498 + "year", // 3499 + "yearLong", // 3500 + "yearShort", // 3501 + "yrange", // 3502 + "z", // 3503 + "zOrder", // 3504 + "zOrderOff", // 3505 + "zeroAsc", // 3506 + "zeroDesc", // 3507 + "zeroHeight", // 3508 + "zeroValues", // 3509 + "zeroWid", // 3510 + "zoom", // 3511 + "zoomContents", // 3512 + "zoomScale", // 3513 + "zoomScaleNormal", // 3514 + "zoomScalePageLayoutView", // 3515 + "zoomScaleSheetLayoutView", // 3516 + "zoomToFit" // 3517 +}; + +size_t token_name_count = 3518;
\ No newline at end of file diff --git a/src/liborcus/ooxml_types.cpp b/src/liborcus/ooxml_types.cpp new file mode 100644 index 0000000..f5165a0 --- /dev/null +++ b/src/liborcus/ooxml_types.cpp @@ -0,0 +1,27 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "ooxml_types.hpp" + +namespace orcus { + +opc_rel_extra::~opc_rel_extra() = default; + +opc_rel_extras_t::opc_rel_extras_t() = default; +opc_rel_extras_t::~opc_rel_extras_t() = default; + +opc_rel_extras_t::opc_rel_extras_t(opc_rel_extras_t&& other) : + data(std::move(other.data)) {} + +void opc_rel_extras_t::swap(opc_rel_extras_t& other) +{ + data.swap(other.data); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/ooxml_types.hpp b/src/liborcus/ooxml_types.hpp new file mode 100644 index 0000000..2b9e43c --- /dev/null +++ b/src/liborcus/ooxml_types.hpp @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_OOXML_TYPES_HPP +#define INCLUDED_ORCUS_OOXML_TYPES_HPP + +#include <iostream> +#include <memory> +#include <unordered_map> + +namespace orcus { + +typedef const char* content_type_t; +typedef const char* schema_t; + +/** + * Part name (first) and content type (second). + */ +typedef ::std::pair<std::string_view, content_type_t> xml_part_t; + +/** + * Single OPC relationship that corresponds with a Relationship element in + * .rels parts. + */ +struct opc_rel_t +{ + std::string_view rid; + std::string_view target; + schema_t type; + + opc_rel_t() : type(nullptr) {} + opc_rel_t(std::string_view _rid, const std::string_view& _target, schema_t _type) : + rid(_rid), target(_target), type(_type) {} +}; + +/** + * Used as a base struct only to allow storage of custom data associated + * with a relationship. + */ +struct opc_rel_extra +{ + virtual ~opc_rel_extra() = 0; +}; + +struct opc_rel_extras_t +{ + typedef std::unordered_map<std::string_view, std::unique_ptr<opc_rel_extra>> map_type; + + /** + * Key is a textual relation ID, while the value is an arbitrary data + * associated with the relation ID. + */ + map_type data; + + opc_rel_extras_t(opc_rel_extras_t&& other); + + opc_rel_extras_t(const opc_rel_extras_t&) = delete; + opc_rel_extras_t& operator=(const opc_rel_extras_t&) = delete; + + opc_rel_extras_t(); + ~opc_rel_extras_t(); + + void swap(opc_rel_extras_t& other); +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/opc_context.cpp b/src/liborcus/opc_context.cpp new file mode 100644 index 0000000..e3b1bb5 --- /dev/null +++ b/src/liborcus/opc_context.cpp @@ -0,0 +1,310 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "opc_context.hpp" +#include "opc_token_constants.hpp" +#include "ooxml_content_types.hpp" +#include "ooxml_namespace_types.hpp" +#include "ooxml_schemas.hpp" +#include "session_context.hpp" + +#include "orcus/exception.hpp" + +#include <cassert> +#include <iostream> +#include <algorithm> + +namespace orcus { + +namespace { + +class part_ext_attr_parser +{ +public: + part_ext_attr_parser( + opc_content_types_context::ct_cache_type* p_ct_cache, xml_token_t attr_name, const config* conf) : + mp_ct_cache(p_ct_cache), + m_attr_name(attr_name), + m_config(conf), + m_content_type(nullptr) {} + + part_ext_attr_parser(const part_ext_attr_parser& r) : + mp_ct_cache(r.mp_ct_cache), + m_attr_name(r.m_attr_name), + m_config(r.m_config), + m_name(r.m_name), + m_content_type(r.m_content_type) {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.name == m_attr_name) + m_name = attr.value; + else if (attr.name == XML_ContentType) + m_content_type = to_content_type(attr.value); + } + + const std::string_view& get_name() const { return m_name; } + content_type_t get_content_type() const { return m_content_type; } + +private: + content_type_t to_content_type(const std::string_view& p) const + { + opc_content_types_context::ct_cache_type::const_iterator itr = + mp_ct_cache->find(p); + if (itr == mp_ct_cache->end()) + { + if (m_config->debug) + std::cout << "unknown content type: " << p << std::endl; + return nullptr; + } + std::string_view val = *itr; + return val.data(); + } + +private: + const opc_content_types_context::ct_cache_type* mp_ct_cache; + xml_token_t m_attr_name; + const config* m_config; + std::string_view m_name; + content_type_t m_content_type; +}; + +} + +opc_content_types_context::opc_content_types_context(session_context& session_cxt, const tokens& _tokens) : + xml_context_base(session_cxt, _tokens) +{ + // build content type cache. + for (const content_type_t* p = CT_all; *p; ++p) + m_ct_cache.insert(std::string_view(*p)); +} + +opc_content_types_context::~opc_content_types_context() +{ +} + +xml_context_base* opc_content_types_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void opc_content_types_context::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void opc_content_types_context::start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t> &attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + switch (name) + { + case XML_Types: + { + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + if (get_config().debug) + print_attrs(get_tokens(), attrs); + } + break; + case XML_Override: + { + xml_element_expected(parent, NS_opc_ct, XML_Types); + part_ext_attr_parser func(&m_ct_cache, XML_PartName, &get_config()); + func = for_each(attrs.begin(), attrs.end(), func); + + // We need to use allocated strings for part names here because + // the part names need to survive after the [Content_Types].xml + // stream is destroyed. + std::string_view part_name = get_session_context().spool.intern(func.get_name()).first; + m_parts.push_back( + xml_part_t(part_name, func.get_content_type())); + } + break; + case XML_Default: + { + xml_element_expected(parent, NS_opc_ct, XML_Types); + part_ext_attr_parser func(&m_ct_cache, XML_Extension, &get_config()); + func = for_each(attrs.begin(), attrs.end(), func); + + // Like the part names, we need to use allocated strings for + // extension names. + std::string_view ext_name = get_session_context().spool.intern(func.get_name()).first; + m_ext_defaults.push_back( + xml_part_t(ext_name, func.get_content_type())); + } + break; + default: + warn_unhandled(); + } +} + +bool opc_content_types_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + return pop_stack(ns, name); +} + +void opc_content_types_context::characters(std::string_view /*str*/, bool /*transient*/) +{ +} + +void opc_content_types_context::pop_parts(std::vector<xml_part_t>& parts) +{ + m_parts.swap(parts); +} + +void opc_content_types_context::pop_ext_defaults(std::vector<xml_part_t>& ext_defaults) +{ + m_ext_defaults.swap(ext_defaults); +} + +// ============================================================================ + +namespace { + +class rel_attr_parser +{ +public: + rel_attr_parser(session_context* cxt, const opc_relations_context::schema_cache_type* cache, const config* conf) : + m_cxt(cxt), mp_schema_cache(cache), mp_config(conf) {} + + void operator() (const xml_token_attr_t& attr) + { + // Target and rId strings must be interned as they must survive after + // the rels part gets destroyed. + + switch (attr.name) + { + case XML_Target: + m_rel.target = m_cxt->spool.intern(attr.value).first; + break; + case XML_Type: + m_rel.type = to_schema(attr.value); + break; + case XML_Id: + m_rel.rid = m_cxt->spool.intern(attr.value).first; + break; + } + } + + const opc_rel_t& get_rel() const { return m_rel; } + +private: + schema_t to_schema(const std::string_view& p) const + { + opc_relations_context::schema_cache_type::const_iterator itr = + mp_schema_cache->find(p); + if (itr == mp_schema_cache->end()) + { + if (mp_config->debug) + std::cout << "unknown schema: " << p << std::endl; + return nullptr; + } + std::string_view val = *itr; + return val.data(); + } + +private: + session_context* m_cxt; + const opc_relations_context::schema_cache_type* mp_schema_cache; + const config* mp_config; + opc_rel_t m_rel; +}; + +/** + * Compare relations by the rId. + */ +struct compare_rels +{ + bool operator() (const opc_rel_t& r1, const opc_rel_t& r2) const + { + std::size_t n1 = r1.rid.size(), n2 = r2.rid.size(); + std::size_t n = std::min(n1, n2); + const char *p1 = r1.rid.data(), *p2 = r2.rid.data(); + for (std::size_t i = 0; i < n; ++i, ++p1, ++p2) + { + if (*p1 < *p2) + return true; + if (*p1 > *p2) + return false; + assert(*p1 == *p2); + } + return n1 < n2; + } +}; + +} + +opc_relations_context::opc_relations_context(session_context& session_cxt, const tokens &_tokens) : + xml_context_base(session_cxt, _tokens) +{ + // build content type cache. + for (schema_t* p = SCH_all; *p; ++p) + m_schema_cache.insert(std::string_view(*p)); +} + +opc_relations_context::~opc_relations_context() +{ +} + +xml_context_base* opc_relations_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void opc_relations_context::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void opc_relations_context::start_element( + xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t> &attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + switch (name) + { + case XML_Relationships: + { + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + if (get_config().debug) + print_attrs(get_tokens(), attrs); + } + break; + case XML_Relationship: + { + rel_attr_parser func(&get_session_context(), &m_schema_cache, &get_config()); + xml_element_expected(parent, NS_opc_rel, XML_Relationships); + func = for_each(attrs.begin(), attrs.end(), func); + const opc_rel_t& rel = func.get_rel(); + if (rel.type) + m_rels.push_back(rel); + } + break; + default: + warn_unhandled(); + } +} + +bool opc_relations_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + return pop_stack(ns, name); +} + +void opc_relations_context::characters(std::string_view /*str*/, bool /*transient*/) +{ +} + +void opc_relations_context::init() +{ + m_rels.clear(); +} + +void opc_relations_context::pop_rels(std::vector<opc_rel_t>& rels) +{ + // Sort by the rId. + sort(m_rels.begin(), m_rels.end(), compare_rels()); + m_rels.swap(rels); +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/opc_context.hpp b/src/liborcus/opc_context.hpp new file mode 100644 index 0000000..c965895 --- /dev/null +++ b/src/liborcus/opc_context.hpp @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_OPC_CONTEXT_HPP +#define INCLUDED_ORCUS_OPC_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "ooxml_types.hpp" + +#include <unordered_set> +#include <vector> + +namespace orcus { + +/** + * Main context class for the [Content_Types].xml part. This context does + * not use any child contexts; [Content_Types].xml part is simple enough + * that we can handle all in a single context class. + */ +class opc_content_types_context : public xml_context_base +{ +public: + typedef std::unordered_set<std::string_view> ct_cache_type; + + opc_content_types_context(session_context& session_cxt, const tokens& _tokens); + virtual ~opc_content_types_context(); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base *child); + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t> &attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + virtual void characters(std::string_view str, bool transient); + + /** + * Swap stored xml part info with the instance passed as the argument. + * Calling this will clear the storage. + * + * @param parts instance to swap the stored xml part info with. + */ + void pop_parts(::std::vector<xml_part_t>& parts); + + /** + * Swap stored xml extension info with the instance passed as the + * argument. Calling this will clear the storage. + * + * @param parts instance to swap the stored extension info with. + */ + void pop_ext_defaults(::std::vector<xml_part_t>& ext_defaults); + +private: + ct_cache_type m_ct_cache; // content type cache; + ::std::vector<xml_part_t> m_parts; + ::std::vector<xml_part_t> m_ext_defaults; +}; + +/** + * Context class for relations parts. + */ +class opc_relations_context : public xml_context_base +{ +public: + typedef std::unordered_set<std::string_view> schema_cache_type; + + opc_relations_context(session_context& session_cxt, const tokens& _tokens); + virtual ~opc_relations_context(); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base *child); + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t> &attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + virtual void characters(std::string_view str, bool transient); + + void init(); + void pop_rels(::std::vector<opc_rel_t>& rels); + +private: + schema_cache_type m_schema_cache; + ::std::vector<opc_rel_t> m_rels; +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/opc_reader.cpp b/src/liborcus/opc_reader.cpp new file mode 100644 index 0000000..7126f66 --- /dev/null +++ b/src/liborcus/opc_reader.cpp @@ -0,0 +1,306 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "opc_reader.hpp" +#include "xml_stream_parser.hpp" + +#include "ooxml_global.hpp" +#include "opc_context.hpp" +#include "ooxml_tokens.hpp" + +#include "orcus/config.hpp" + +#include <iostream> + +using namespace std; + +namespace orcus { + +namespace { + +class print_xml_content_types +{ +public: + print_xml_content_types(const char* prefix) : + m_prefix(prefix) {} + + void operator() (const xml_part_t& v) const + { + cout << "* " << m_prefix << ": " << v.first; + if (v.second) + cout << " (" << v.second << ")"; + else + cout << " (<unknown content type>)"; + cout << endl; + } +private: + const char* m_prefix; +}; + +} + +opc_reader::part_handler::~part_handler() {} + +opc_reader::opc_reader(const config& opt, xmlns_repository& ns_repo, session_context& cxt, part_handler& handler) : + m_config(opt), + m_ns_repo(ns_repo), + m_session_cxt(cxt), + m_handler(handler), + m_opc_rel_handler(m_session_cxt, opc_tokens, std::make_unique<opc_relations_context>(m_session_cxt, opc_tokens)) {} + +void opc_reader::read_file(std::unique_ptr<zip_archive_stream>&& stream) +{ + m_archive_stream.reset(stream.release()); + m_archive.reset(new zip_archive(m_archive_stream.get())); + + m_archive->load(); + + m_dir_stack.push_back(string()); // push root directory. + + if (m_config.debug) + list_content(); + read_content(); + + m_archive.reset(); + m_archive_stream.reset(); +} + +bool opc_reader::open_zip_stream(const string& path, vector<unsigned char>& buf) +{ + try + { + std::vector<unsigned char> entry = m_archive->read_file_entry(path.c_str()); + buf.swap(entry); + return true; + } + catch (const std::exception&) + { + return false; + } +} + +void opc_reader::read_part(std::string_view path, const schema_t type, opc_rel_extra* data) +{ + assert(!m_dir_stack.empty()); + + dir_stack_type dir_changed; + + // Change current directory and read the in-file. + const char* p = path.data(); + const char* p_name = nullptr; + size_t name_len = 0; + for (size_t i = 0, n = path.size(); i < n; ++i, ++p) + { + if (!p_name) + p_name = p; + + ++name_len; + + if (*p == '/') + { + // Push a new directory. + string dir_name(p_name, name_len); + if (dir_name == "..") + { + dir_changed.push_back(m_dir_stack.back()); + m_dir_stack.pop_back(); + } + else + { + m_dir_stack.push_back(dir_name); + + // Add a null directory to the change record to remove it at the end. + dir_changed.push_back(string()); + } + + p_name = nullptr; + name_len = 0; + } + } + + if (p_name) + { + // This is a file. + string file_name(p_name, name_len); + string cur_dir = get_current_dir(); + string full_path = resolve_file_path(cur_dir, file_name); + + if (m_handled_parts.count(full_path) > 0) + { + // This part has been previously read. Let's not read it twice. + if (m_config.debug) + { + cout << "---" << endl; + cout << "skipping previously read part: " << full_path << endl; + } + } + else if (m_handler.handle_part(type, cur_dir, file_name, data)) + { + m_handled_parts.insert(full_path); + } + else if (m_config.debug) + { + cout << "---" << endl; + cout << "unhandled relationship type: " << type << endl; + } + } + + // Unwind to the original directory. + while (!dir_changed.empty()) + { + const string& dir = dir_changed.back(); + if (dir.empty()) + // remove added directory. + m_dir_stack.pop_back(); + else + // re-add removed directory. + m_dir_stack.push_back(dir); + + dir_changed.pop_back(); + } +} + +void opc_reader::check_relation_part( + const std::string& file_name, opc_rel_extras_t* extras, sort_compare_type* sorter) +{ + // Read the relationship file associated with this file, located at + // _rels/<file name>.rels. + vector<opc_rel_t> rels; + m_dir_stack.push_back(string("_rels/")); + string rels_file_name = file_name + ".rels"; + read_relations(rels_file_name.c_str(), rels); + m_dir_stack.pop_back(); + + if (sorter) + std::sort(rels.begin(), rels.end(), *sorter); + + if (m_config.debug) + for_each(rels.begin(), rels.end(), print_opc_rel()); + + for_each(rels.begin(), rels.end(), + [&](opc_rel_t& v) + { + opc_rel_extra* data = nullptr; + if (extras) + { + // See if there is an extra data associated with this relation ID. + opc_rel_extras_t::map_type::iterator it = extras->data.find(v.rid); + if (it != extras->data.end()) + // There is one ! + data = it->second.get(); + } + read_part(v.target, v.type, data); + } + ); +} + +void opc_reader::list_content() const +{ + size_t num = m_archive->get_file_entry_count(); + cout << "number of files this archive contains: " << num << endl; + + for (size_t i = 0; i < num; ++i) + { + std::string_view filename = m_archive->get_file_entry_name(i); + cout << filename << endl; + } +} + +void opc_reader::read_content() +{ + if (m_dir_stack.empty()) + return; + + // [Content_Types].xml + + read_content_types(); + if (m_config.debug) + { + for_each(m_parts.begin(), m_parts.end(), print_xml_content_types("part name")); + for_each(m_ext_defaults.begin(), m_ext_defaults.end(), print_xml_content_types("extension default")); + } + + // _rels/.rels + + m_dir_stack.push_back(string("_rels/")); + vector<opc_rel_t> rels; + read_relations(".rels", rels); + m_dir_stack.pop_back(); + + if (m_config.debug) + for_each(rels.begin(), rels.end(), print_opc_rel()); + + for_each(rels.begin(), rels.end(), + [this](opc_rel_t& v) + { + read_part(v.target, v.type, nullptr); + } + ); +} + +void opc_reader::read_content_types() +{ + string filepath("[Content_Types].xml"); + vector<unsigned char> buffer; + if (!open_zip_stream(filepath, buffer)) + return; + + if (buffer.empty()) + return; + + xml_stream_parser parser( + m_config, m_ns_repo, opc_tokens, + reinterpret_cast<const char*>(&buffer[0]), buffer.size()); + + auto handler = std::make_unique<xml_simple_stream_handler>( + m_session_cxt, opc_tokens, + std::make_unique<opc_content_types_context>(m_session_cxt, opc_tokens)); + + parser.set_handler(handler.get()); + parser.parse(); + + opc_content_types_context& context = + static_cast<opc_content_types_context&>(handler->get_context()); + context.pop_parts(m_parts); + context.pop_ext_defaults(m_ext_defaults); +} + +void opc_reader::read_relations(const char* path, vector<opc_rel_t>& rels) +{ + string filepath = resolve_file_path(get_current_dir(), path); + if (m_config.debug) + cout << "relation file path: " << filepath << endl; + + vector<unsigned char> buffer; + if (!open_zip_stream(filepath, buffer)) + return; + + if (buffer.empty()) + return; + + xml_stream_parser parser( + m_config, m_ns_repo, opc_tokens, reinterpret_cast<const char*>(&buffer[0]), buffer.size()); + + opc_relations_context& context = + static_cast<opc_relations_context&>(m_opc_rel_handler.get_context()); + context.init(); + parser.set_handler(&m_opc_rel_handler); + parser.parse(); + context.pop_rels(rels); +} + +string opc_reader::get_current_dir() const +{ + string pwd; + vector<string>::const_iterator itr = m_dir_stack.begin(), itr_end = m_dir_stack.end(); + for (; itr != itr_end; ++itr) + pwd += *itr; + return pwd; +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/opc_reader.hpp b/src/liborcus/opc_reader.hpp new file mode 100644 index 0000000..5733c02 --- /dev/null +++ b/src/liborcus/opc_reader.hpp @@ -0,0 +1,127 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_OPC_READER_HPP +#define INCLUDED_ORCUS_OPC_READER_HPP + +#include "orcus/env.hpp" +#include "orcus/zip_archive.hpp" +#include "orcus/zip_archive_stream.hpp" + +#include "ooxml_schemas.hpp" +#include "xml_simple_stream_handler.hpp" + +#include <vector> +#include <string> +#include <unordered_set> + +namespace orcus { + +struct config; + +class xmlns_repository; +struct session_context; +struct opc_rel_extra; + +/** + * Class to handle parsing through all xml parts stored in a file packaged + * according to the Open Package Convention (OPC). + */ +class opc_reader +{ + typedef std::vector<std::string> dir_stack_type; + typedef std::unordered_set<std::string> part_set_type; + + opc_reader(const opc_reader&) = delete; + opc_reader& operator=(const opc_reader&) = delete; + +public: + + using sort_compare_type = std::function<bool(const opc_rel_t&, const opc_rel_t&)>; + + /** + * Interface class for the user of opc_reader to receive callback to + * handle each xml part. + */ + class part_handler + { + public: + virtual ~part_handler() = 0; + + /** + * Client code needs to implement this method to handle each xml part. + * + * @param type schema type signifying the content type stored in this + * part. + * @param dir_path directory path relative to package root. + * @param file_name name of the xml part without the directory path. + * @param data extra data passed on from the client code. + * + * @return true if handled, false if not handled. + */ + virtual bool handle_part( + schema_t type, const std::string& dir_path, const std::string& file_name, opc_rel_extra* data) = 0; + }; + + opc_reader(const config& opt, xmlns_repository& ns_repo, session_context& session_cxt, part_handler& handler); + + void read_file(std::unique_ptr<zip_archive_stream>&& stream); + bool open_zip_stream(const std::string& path, std::vector<unsigned char>& buf); + + /** + * Read an xml part inside package. The path is relative to the relation + * file. + * + * @param path the path to the xml part. + * @param type schema type. + */ + void read_part(std::string_view path, const schema_t type, opc_rel_extra* data); + + /** + * Check if a relation file exists for a given xml part, and if it does, + * read and process it. + * + * @param file_name name of the current xml part. + * @param extras optional extra data file for client code to pass on to + * the next xml part(s). + * @param sorter optoinal comparator function used to sort the relation + * items prior to processing them. + */ + void check_relation_part( + const std::string& file_name, opc_rel_extras_t* extras = nullptr, + sort_compare_type* sorter = nullptr); + +private: + + void list_content() const; + void read_content(); + void read_content_types(); + void read_relations(const char* path, std::vector<opc_rel_t>& rels); + + std::string get_current_dir() const; + +private: + const config& m_config; + xmlns_repository& m_ns_repo; + session_context& m_session_cxt; + part_handler& m_handler; + + std::unique_ptr<zip_archive> m_archive; + std::unique_ptr<zip_archive_stream> m_archive_stream; + + xml_simple_stream_handler m_opc_rel_handler; + + std::vector<xml_part_t> m_parts; + std::vector<xml_part_t> m_ext_defaults; + dir_stack_type m_dir_stack; + part_set_type m_handled_parts; +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/opc_token_constants.hpp b/src/liborcus/opc_token_constants.hpp new file mode 100644 index 0000000..a7b1370 --- /dev/null +++ b/src/liborcus/opc_token_constants.hpp @@ -0,0 +1,20 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef __ORCUS_OPC_TOKEN_CONSTANTS_HPP__ +#define __ORCUS_OPC_TOKEN_CONSTANTS_HPP__ + +#include "orcus/types.hpp" + +namespace orcus { + +#include "opc_token_constants.inl" + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/opc_token_constants.inl b/src/liborcus/opc_token_constants.inl new file mode 100644 index 0000000..7f3c7da --- /dev/null +++ b/src/liborcus/opc_token_constants.inl @@ -0,0 +1,31 @@ +// This file has been auto-generated. Do not hand-edit this. + +const xml_token_t XML_ContentType = 1; +const xml_token_t XML_Default = 2; +const xml_token_t XML_Extension = 3; +const xml_token_t XML_Format = 4; +const xml_token_t XML_Id = 5; +const xml_token_t XML_Override = 6; +const xml_token_t XML_PartName = 7; +const xml_token_t XML_Relationship = 8; +const xml_token_t XML_RelationshipReference = 9; +const xml_token_t XML_Relationships = 10; +const xml_token_t XML_RelationshipsGroupReference = 11; +const xml_token_t XML_SignatureTime = 12; +const xml_token_t XML_SourceId = 13; +const xml_token_t XML_SourceType = 14; +const xml_token_t XML_Target = 15; +const xml_token_t XML_TargetMode = 16; +const xml_token_t XML_Type = 17; +const xml_token_t XML_Types = 18; +const xml_token_t XML_Value = 19; +const xml_token_t XML_category = 20; +const xml_token_t XML_contentStatus = 21; +const xml_token_t XML_contentType = 22; +const xml_token_t XML_coreProperties = 23; +const xml_token_t XML_keywords = 24; +const xml_token_t XML_lastModifiedBy = 25; +const xml_token_t XML_lastPrinted = 26; +const xml_token_t XML_revision = 27; +const xml_token_t XML_version = 28; + diff --git a/src/liborcus/opc_tokens.inl b/src/liborcus/opc_tokens.inl new file mode 100644 index 0000000..5f72a6a --- /dev/null +++ b/src/liborcus/opc_tokens.inl @@ -0,0 +1,36 @@ +// This file has been auto-generated. Do not hand-edit this. + +const char* token_names[] = { + "??", // 0 + "ContentType", // 1 + "Default", // 2 + "Extension", // 3 + "Format", // 4 + "Id", // 5 + "Override", // 6 + "PartName", // 7 + "Relationship", // 8 + "RelationshipReference", // 9 + "Relationships", // 10 + "RelationshipsGroupReference", // 11 + "SignatureTime", // 12 + "SourceId", // 13 + "SourceType", // 14 + "Target", // 15 + "TargetMode", // 16 + "Type", // 17 + "Types", // 18 + "Value", // 19 + "category", // 20 + "contentStatus", // 21 + "contentType", // 22 + "coreProperties", // 23 + "keywords", // 24 + "lastModifiedBy", // 25 + "lastPrinted", // 26 + "revision", // 27 + "version" // 28 +}; + +size_t token_name_count = 29; + diff --git a/src/liborcus/orcus_csv.cpp b/src/liborcus/orcus_csv.cpp new file mode 100644 index 0000000..dff2b2d --- /dev/null +++ b/src/liborcus/orcus_csv.cpp @@ -0,0 +1,196 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/orcus_csv.hpp" + +#include "orcus/csv_parser.hpp" +#include "orcus/stream.hpp" +#include "orcus/spreadsheet/import_interface.hpp" +#include "orcus/config.hpp" +#include "orcus/string_pool.hpp" + +#include <cstring> +#include <iostream> + +using namespace std; + +namespace orcus { + +namespace { + +constexpr const char* base_sheet_name = "data"; + +struct header_cell +{ + spreadsheet::row_t row; + spreadsheet::col_t col; + std::string_view value; + + header_cell(spreadsheet::row_t _row, spreadsheet::col_t _col, std::string_view _value) : + row(_row), col(_col), value(_value) {} +}; + +class max_row_size_reached {}; + +class orcus_csv_handler +{ +public: + orcus_csv_handler(spreadsheet::iface::import_factory& factory, const orcus::config& app_config) : + m_factory(factory), + m_app_config(app_config), + mp_sheet(nullptr), + m_sheet(0), + m_row(0), + m_col(0) {} + + void begin_parse() + { + std::string sheet_name = get_sheet_name(); + mp_sheet = m_factory.append_sheet(m_sheet, sheet_name); + } + + void end_parse() {} + void begin_row() + { + // Check to see if this row is beyond the max row of the current + // sheet, and if so, append a new sheet and reset the current row to + // 0. + if (m_row >= mp_sheet->get_sheet_size().rows) + { + auto csv = std::get<config::csv_config>(m_app_config.data); + + if (!csv.split_to_multiple_sheets) + throw max_row_size_reached(); + + // The next row will be outside the boundary of the current sheet. + ++m_sheet; + std::string sheet_name = get_sheet_name(); + mp_sheet = m_factory.append_sheet(m_sheet, sheet_name); + m_row = 0; + + if (!m_header_cells.empty()) + { + // Duplicate the header rows from the first sheet. + for (const header_cell& c : m_header_cells) + mp_sheet->set_auto(c.row, c.col, c.value); + + m_row += csv.header_row_size; + } + } + } + + void end_row() + { + ++m_row; + m_col = 0; + } + + void cell(std::string_view v, bool transient) + { + auto csv = std::get<config::csv_config>(m_app_config.data); + + if (m_sheet == 0 && size_t(m_row) < csv.header_row_size) + { + if (transient) + v = m_pool.intern(v).first; + + m_header_cells.emplace_back(m_row, m_col, v); + } + + mp_sheet->set_auto(m_row, m_col, v); + ++m_col; + } + +private: + std::string get_sheet_name() const + { + if (!m_sheet) + // First sheet has no suffix. + return base_sheet_name; + + // Add a suffix to keep the sheet name unique. + std::ostringstream os; + os << base_sheet_name << '_' << m_sheet; + return os.str(); + } + +private: + string_pool m_pool; + std::vector<header_cell> m_header_cells; + + spreadsheet::iface::import_factory& m_factory; + const config& m_app_config; + spreadsheet::iface::import_sheet* mp_sheet; + spreadsheet::sheet_t m_sheet; + spreadsheet::row_t m_row; + spreadsheet::col_t m_col; +}; + +} + +struct orcus_csv::impl +{ + spreadsheet::iface::import_factory* factory; + + impl(spreadsheet::iface::import_factory* _factory) : factory(_factory) {} + + void parse(std::string_view stream, const config& conf) + { + if (stream.empty()) + return; + + orcus_csv_handler handler(*factory, conf); + csv::parser_config config; + config.delimiters.push_back(','); + config.text_qualifier = '"'; + csv_parser<orcus_csv_handler> parser(stream, handler, config); + try + { + parser.parse(); + } + catch (const max_row_size_reached&) + { + // The parser has decided to end the import due to the destination + // sheet being full. + } + catch (const parse_error& e) + { + cout << "parse failed at offset " << e.offset() << ": " << e.what() << endl; + } + } +}; + +orcus_csv::orcus_csv(spreadsheet::iface::import_factory* factory) : + iface::import_filter(format_t::csv), + mp_impl(std::make_unique<impl>(factory)) {} + +orcus_csv::~orcus_csv() {} + +void orcus_csv::read_file(std::string_view filepath) +{ + file_content fc(filepath); + mp_impl->parse(fc.str(), get_config()); + mp_impl->factory->finalize(); +} + +void orcus_csv::read_stream(std::string_view stream) +{ + if (stream.empty()) + return; + + mp_impl->parse(stream, get_config()); + mp_impl->factory->finalize(); +} + +std::string_view orcus_csv::get_name() const +{ + return "csv"; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/orcus_gnumeric.cpp b/src/liborcus/orcus_gnumeric.cpp new file mode 100644 index 0000000..849759b --- /dev/null +++ b/src/liborcus/orcus_gnumeric.cpp @@ -0,0 +1,163 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/orcus_gnumeric.hpp" +#include "orcus/xml_namespace.hpp" +#include "orcus/spreadsheet/import_interface.hpp" +#include "orcus/stream.hpp" +#include "orcus/config.hpp" + +#include "xml_stream_parser.hpp" +#include "gnumeric_handler.hpp" +#include "gnumeric_tokens.hpp" +#include "gnumeric_namespace_types.hpp" +#include "gnumeric_detection_handler.hpp" +#include "session_context.hpp" +#include "detection_result.hpp" + +#define ORCUS_DEBUG_GNUMERIC 0 +#define BOOST_IOSTREAMS_NO_LIB 1 + +#include <iostream> +#include <string> + +#include <boost/iostreams/filtering_stream.hpp> +#include <boost/iostreams/filter/gzip.hpp> + +using namespace std; + +namespace orcus { + +namespace { + +bool decompress_gzip(const char* buffer, size_t size, string& decompressed) +{ + string buf; + + try + { + boost::iostreams::filtering_ostream os; + os.push(boost::iostreams::gzip_decompressor()); + os.push(boost::iostreams::back_inserter(buf)); + boost::iostreams::write(os, buffer, size); + os.flush(); + } + catch (const exception&) + { + return false; + } + + buf.swap(decompressed); + return true; +} + +} + +struct orcus_gnumeric::impl +{ + xmlns_repository m_ns_repo; + session_context m_cxt; + spreadsheet::iface::import_factory* mp_factory; + + impl(spreadsheet::iface::import_factory* im_factory) : + mp_factory(im_factory) {} + + void read_content_xml(std::string_view s, const config& conf) + { + xml_stream_parser parser(conf, m_ns_repo, gnumeric_tokens, s.data(), s.size()); + + auto handler = std::make_unique<gnumeric_content_xml_handler>( + m_cxt, gnumeric_tokens, mp_factory); + + parser.set_handler(handler.get()); + parser.parse(); + } +}; + +orcus_gnumeric::orcus_gnumeric(spreadsheet::iface::import_factory* factory) : + iface::import_filter(format_t::gnumeric), + mp_impl(std::make_unique<impl>(factory)) +{ + mp_impl->m_ns_repo.add_predefined_values(NS_gnumeric_all); +} + +orcus_gnumeric::~orcus_gnumeric() +{ +} + +bool orcus_gnumeric::detect(const unsigned char* buffer, size_t size) +{ + // Detect gnumeric format that's already in memory. + + string decompressed; + if (!decompress_gzip(reinterpret_cast<const char*>(buffer), size, decompressed)) + return false; + + if (decompressed.empty()) + return false; + + // Parse this xml stream for detection. + config opt(format_t::gnumeric); + xmlns_repository ns_repo; + ns_repo.add_predefined_values(NS_gnumeric_all); + session_context cxt; + xml_stream_parser parser(opt, ns_repo, gnumeric_tokens, &decompressed[0], decompressed.size()); + gnumeric_detection_handler handler(cxt, gnumeric_tokens); + parser.set_handler(&handler); + + try + { + parser.parse(); + } + catch (const detection_result& res) + { + return res.get_result(); + } + catch (...) {} + + return false; +} + +void orcus_gnumeric::read_file(std::string_view filepath) +{ +#if ORCUS_DEBUG_GNUMERIC + cout << "reading " << filepath << endl; +#endif + + file_content content(filepath); + if (content.empty()) + return; + + read_stream(content.str()); +} + +void orcus_gnumeric::read_stream(std::string_view stream) +{ + if (stream.empty()) + return; + + std::string file_content; + if (!decompress_gzip(stream.data(), stream.size(), file_content)) + return; + + if (auto* gs = mp_impl->mp_factory->get_global_settings(); gs) + { + gs->set_origin_date(1899, 12, 30); + gs->set_default_formula_grammar(spreadsheet::formula_grammar_t::gnumeric); + } + + mp_impl->read_content_xml(file_content, get_config()); + mp_impl->mp_factory->finalize(); +} + +std::string_view orcus_gnumeric::get_name() const +{ + return "gnumeric"; +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/orcus_import_ods.cpp b/src/liborcus/orcus_import_ods.cpp new file mode 100644 index 0000000..0c73472 --- /dev/null +++ b/src/liborcus/orcus_import_ods.cpp @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/orcus_import_ods.hpp" + +#include "orcus/xml_namespace.hpp" +#include "orcus/spreadsheet/import_interface.hpp" +#include "orcus/config.hpp" + +#include "odf_styles_context.hpp" +#include "odf_tokens.hpp" +#include "odf_namespace_types.hpp" +#include "session_context.hpp" +#include "ods_session_data.hpp" + +#include "xml_stream_parser.hpp" + +namespace orcus { + +void import_ods::read_styles(std::string_view s, spreadsheet::iface::import_styles* styles) +{ + if (!styles) + return; + + if (s.empty()) + return; + + session_context cxt{std::make_unique<ods_session_data>()}; + auto context = std::make_unique<styles_context>(cxt, odf_tokens, styles); + + xml_stream_handler stream_handler(cxt, odf_tokens, std::move(context)); + + xmlns_repository ns_repo; + ns_repo.add_predefined_values(NS_odf_all); + + orcus::config config(format_t::ods); + config.debug = true; + xml_stream_parser parser( + config, ns_repo, odf_tokens, + s.data(), s.size()); + parser.set_handler(&stream_handler); + parser.parse(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/orcus_import_xlsx.cpp b/src/liborcus/orcus_import_xlsx.cpp new file mode 100644 index 0000000..265f419 --- /dev/null +++ b/src/liborcus/orcus_import_xlsx.cpp @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/orcus_import_xlsx.hpp" + +#include "orcus/xml_namespace.hpp" +#include "orcus/spreadsheet/import_interface.hpp" +#include "orcus/config.hpp" + +#include "xlsx_types.hpp" +#include "xlsx_handler.hpp" +#include "ooxml_tokens.hpp" + +#include "xml_stream_parser.hpp" +#include "ooxml_namespace_types.hpp" +#include "xlsx_session_data.hpp" +#include "ooxml_global.hpp" + +namespace orcus { + +void import_xlsx::read_table( + std::string_view s, + spreadsheet::iface::import_table& table, + spreadsheet::iface::import_reference_resolver& resolver) +{ + if (s.empty()) + return; + + session_context cxt; + auto handler = std::make_unique<xlsx_table_xml_handler>(cxt, ooxml_tokens, table, resolver); + + xmlns_repository ns_repo; + ns_repo.add_predefined_values(NS_ooxml_all); + ns_repo.add_predefined_values(NS_opc_all); + ns_repo.add_predefined_values(NS_misc_all); + + orcus::config config(format_t::xlsx); + xml_stream_parser parser( + config, ns_repo, ooxml_tokens, + s.data(), s.size()); + parser.set_handler(handler.get()); + parser.parse(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/orcus_json.cpp b/src/liborcus/orcus_json.cpp new file mode 100644 index 0000000..9b6195f --- /dev/null +++ b/src/liborcus/orcus_json.cpp @@ -0,0 +1,513 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/orcus_json.hpp> +#include <orcus/json_document_tree.hpp> +#include <orcus/json_structure_tree.hpp> +#include <orcus/config.hpp> +#include <orcus/spreadsheet/import_interface.hpp> +#include <orcus/json_parser.hpp> +#include <orcus/stream.hpp> + +#include "json_map_tree.hpp" +#include "json_structure_mapper.hpp" + +#include <iostream> +#include <sstream> + +namespace orcus { + +namespace { + +struct json_value +{ + enum class value_type { string, numeric, boolean, null }; + + value_type type; + + union + { + struct { const char* p; size_t n; } str; + double numeric; + bool boolean; + + } value; + + json_value(double v) : type(value_type::numeric) + { + value.numeric = v; + } + + json_value(const char* p, size_t n) : type(value_type::string) + { + value.str.p = p; + value.str.n = n; + } + + json_value(bool v) : type(value_type::boolean) + { + value.boolean = v; + } + + json_value(value_type vt) : type(vt) {} + + void commit(spreadsheet::iface::import_factory& im_factory, const cell_position_t& pos) const + { + spreadsheet::iface::import_sheet* sheet = im_factory.get_sheet(pos.sheet); + + if (!sheet) + return; + + switch (type) + { + case value_type::string: + { + spreadsheet::iface::import_shared_strings* ss = im_factory.get_shared_strings(); + if (!ss) + break; + + size_t sid = ss->add({value.str.p, value.str.n}); + sheet->set_string(pos.row, pos.col, sid); + break; + } + case value_type::numeric: + sheet->set_value(pos.row, pos.col, value.numeric); + break; + case value_type::boolean: + sheet->set_bool(pos.row, pos.col, value.boolean); + break; + case value_type::null: + break; + } + } +}; + +class json_content_handler +{ + json_map_tree::walker m_walker; + json_map_tree::node* mp_current_node; + json_map_tree::range_reference_type* mp_increment_row; + + struct row_group_scope + { + json_map_tree::node* node; + spreadsheet::row_t row_position; + + row_group_scope(json_map_tree::node* _node, spreadsheet::row_t _row_position) : + node(_node), row_position(_row_position) {} + }; + + /** + * Stack of row group nodes, used to keep track of whether or not we are + * currently within a linked range. + */ + std::vector<row_group_scope> m_row_group_stack; + + spreadsheet::iface::import_factory& m_im_factory; + +public: + json_content_handler(const json_map_tree& map_tree, spreadsheet::iface::import_factory& im_factory) : + m_walker(map_tree.get_tree_walker()), + mp_current_node(nullptr), + mp_increment_row(nullptr), + m_im_factory(im_factory) {} + + void begin_parse() {} + void end_parse() {} + + void begin_array() + { + push_node(json_map_tree::input_node_type::array); + } + + void end_array() + { + pop_node(json_map_tree::input_node_type::array); + } + + void begin_object() + { + push_node(json_map_tree::input_node_type::object); + } + + void object_key(std::string_view key, bool /*transient*/) + { + m_walker.set_object_key(key.data(), key.size()); + } + + void end_object() + { + pop_node(json_map_tree::input_node_type::object); + } + + void boolean_true() + { + push_node(json_map_tree::input_node_type::value); + commit_value(true); + pop_node(json_map_tree::input_node_type::value); + } + + void boolean_false() + { + push_node(json_map_tree::input_node_type::value); + commit_value(false); + pop_node(json_map_tree::input_node_type::value); + } + + void null() + { + push_node(json_map_tree::input_node_type::value); + commit_value(json_value::value_type::null); + pop_node(json_map_tree::input_node_type::value); + } + + void string(std::string_view val, bool /*transient*/) + { + push_node(json_map_tree::input_node_type::value); + commit_value(json_value(val.data(), val.size())); + pop_node(json_map_tree::input_node_type::value); + } + + void number(double val) + { + push_node(json_map_tree::input_node_type::value); + commit_value(val); + pop_node(json_map_tree::input_node_type::value); + } + +private: + + void push_node(json_map_tree::input_node_type nt) + { + if (!m_row_group_stack.empty() && mp_current_node) + { + if (mp_current_node->row_group && mp_increment_row == mp_current_node->row_group) + { + // The last closing node was a row group boundary. Increment the row position. + ++mp_current_node->row_group->row_position; + mp_increment_row = nullptr; + } + } + + mp_current_node = m_walker.push_node(nt); + + if (mp_current_node && mp_current_node->row_group) + { + m_row_group_stack.emplace_back( + mp_current_node, mp_current_node->row_group->row_position); + } + } + + void pop_node(json_map_tree::input_node_type nt) + { + spreadsheet::row_t row_start = -1; + spreadsheet::row_t row_end = -1; + json_map_tree::range_reference_type* fill_down_ref = nullptr; + + if (mp_current_node && mp_current_node->row_group) + { + // We are exiting a row group. + assert(!m_row_group_stack.empty()); + assert(m_row_group_stack.back().node == mp_current_node); + + // Record the current row range for this level. + row_start = m_row_group_stack.back().row_position; + row_end = mp_current_node->row_group->row_position; + + if (row_end > row_start && m_row_group_stack.size() > 1) + { + // The current range is longer than 1. We need to perform fill-downs for the parent level. + fill_down_ref = mp_current_node->row_group; + + if (fill_down_ref->row_header) + { + // Account for the row header. + ++row_start; + ++row_end; + } + } + + m_row_group_stack.pop_back(); + } + + mp_current_node = m_walker.pop_node(nt); + + if (!m_row_group_stack.empty()) + { + if (mp_current_node && mp_current_node->row_group) + { + assert(m_row_group_stack.back().node == mp_current_node); + mp_increment_row = mp_current_node->row_group; + } + + if (fill_down_ref) + { + // Perform fill-downs for all anchored fields. + const cell_position_t& pos = fill_down_ref->pos; + spreadsheet::iface::import_sheet* sheet = m_im_factory.get_sheet(pos.sheet); + + if (sheet) + { + json_map_tree::node* node = m_row_group_stack.back().node; + for (const json_map_tree::node* anchored_field : node->anchored_fields) + { + spreadsheet::col_t col_offset = + anchored_field->value.range_field_ref->column_pos; + sheet->fill_down_cells( + pos.row + row_start, pos.col + col_offset, row_end - row_start); + } + } + } + } + } + + void commit_value(const json_value& v) + { + if (!mp_current_node) + return; + + switch (mp_current_node->type) + { + case json_map_tree::map_node_type::cell_ref: + { + // Single cell reference + v.commit(m_im_factory, mp_current_node->value.cell_ref->pos); + break; + } + case json_map_tree::map_node_type::range_field_ref: + { + // Range field reference. Offset from the origin before + // pushing the value. + spreadsheet::col_t col_offset = mp_current_node->value.range_field_ref->column_pos; + json_map_tree::range_reference_type* ref = mp_current_node->value.range_field_ref->ref; + + cell_position_t pos = ref->pos; // copy + pos.col += col_offset; + pos.row += ref->row_position; + if (ref->row_header) + ++pos.row; // Account for the row header. + + v.commit(m_im_factory, pos); + break; + } + default: + ; + } + } +}; + +} // anonymous namespace + +struct orcus_json::impl +{ + spreadsheet::iface::import_factory* im_factory; + spreadsheet::sheet_t sheet_count; + json_map_tree map_tree; + + impl(spreadsheet::iface::import_factory* _im_factory) : + im_factory(_im_factory), sheet_count(0) {} +}; + +orcus_json::orcus_json(spreadsheet::iface::import_factory* im_fact) : + mp_impl(std::make_unique<impl>(im_fact)) {} + +orcus_json::~orcus_json() {} + +void orcus_json::set_cell_link(std::string_view path, std::string_view sheet, spreadsheet::row_t row, spreadsheet::col_t col) +{ + mp_impl->map_tree.set_cell_link(path, cell_position_t(sheet, row, col)); +} + +void orcus_json::start_range(std::string_view sheet, spreadsheet::row_t row, spreadsheet::col_t col, bool row_header) +{ + mp_impl->map_tree.start_range(cell_position_t(sheet, row, col), row_header); +} + +void orcus_json::append_field_link(std::string_view path, std::string_view label) +{ + mp_impl->map_tree.append_field_link(path, label); +} + +void orcus_json::set_range_row_group(std::string_view path) +{ + mp_impl->map_tree.set_range_row_group(path); +} + +void orcus_json::commit_range() +{ + mp_impl->map_tree.commit_range(); +} + +void orcus_json::append_sheet(std::string_view name) +{ + if (name.empty()) + return; + + mp_impl->im_factory->append_sheet(mp_impl->sheet_count++, name); +} + +void orcus_json::read_stream(std::string_view stream) +{ + if (!mp_impl->im_factory) + return; + + spreadsheet::iface::import_shared_strings* ss = mp_impl->im_factory->get_shared_strings(); + if (!ss) + return; + + // Insert range headers first (if applicable). + for (const auto& entry : mp_impl->map_tree.get_range_references()) + { + const json_map_tree::range_reference_type& ref = entry.second; + if (!ref.row_header) + // This range does not use row header. + continue; + + const cell_position_t& origin = ref.pos; + + spreadsheet::iface::import_sheet* sheet = mp_impl->im_factory->get_sheet(origin.sheet); + + if (!sheet) + continue; + + for (const json_map_tree::range_field_reference_type* field : ref.fields) + { + cell_position_t pos = origin; + pos.col += field->column_pos; + size_t sid = ss->add(field->label); + sheet->set_string(pos.row, pos.col, sid); + } + } + + json_content_handler hdl(mp_impl->map_tree, *mp_impl->im_factory); + json_parser<json_content_handler> parser(stream, hdl); + parser.parse(); + + mp_impl->im_factory->finalize(); +} + +void orcus_json::read_map_definition(std::string_view stream) +{ + try + { + // Since a typical map file will likely be very small, let's be lazy and + // load the whole thing into a in-memory tree. + json::document_tree map_doc; + json_config jc; + jc.preserve_object_order = false; + jc.persistent_string_values = false; + jc.resolve_references = false; + + map_doc.load(stream, jc); + json::const_node root = map_doc.get_document_root(); + + // Create sheets first. + + if (!root.has_key("sheets")) + throw json_structure_error("The map definition must contains 'sheets' section."); + + for (const json::const_node& node_name : root.child("sheets")) + append_sheet(node_name.string_value()); + + if (root.has_key("cells")) + { + // Set cell links. + for (const json::const_node& link_node : root.child("cells")) + { + std::string_view path = link_node.child("path").string_value(); + std::string_view sheet = link_node.child("sheet").string_value(); + spreadsheet::row_t row = link_node.child("row").numeric_value(); + spreadsheet::col_t col = link_node.child("column").numeric_value(); + + set_cell_link(path, sheet, row, col); + } + } + + if (root.has_key("ranges")) + { + // Set range links. + for (const json::const_node& link_node : root.child("ranges")) + { + std::string_view sheet = link_node.child("sheet").string_value(); + spreadsheet::row_t row = link_node.child("row").numeric_value(); + spreadsheet::col_t col = link_node.child("column").numeric_value(); + + bool row_header = link_node.has_key("row-header") && link_node.child("row-header").type() == json::node_t::boolean_true; + + start_range(sheet, row, col, row_header); + + for (const json::const_node& field_node : link_node.child("fields")) + { + std::string_view path = field_node.child("path").string_value(); + std::string_view label; + if (field_node.has_key("label")) + { + json::const_node label_node = field_node.child("label"); + if (label_node.type() == json::node_t::string) + label = label_node.string_value(); + } + + append_field_link(path, label); + } + + for (const json::const_node& rg_node : link_node.child("row-groups")) + { + std::string_view path = rg_node.child("path").string_value(); + set_range_row_group(path); + } + + commit_range(); + } + } + } + catch (const parse_error& e) + { + std::ostringstream os; + os << "Error parsing the map definition file:" << std::endl + << std::endl + << create_parse_error_output(stream, e.offset()) << std::endl + << e.what(); + + throw invalid_map_error(os.str()); + } +} + +void orcus_json::detect_map_definition(std::string_view stream) +{ + size_t range_count = 0; + std::string sheet_name_prefix = "range-"; + + json::structure_tree::range_handler_type rh = [&](json::table_range_t&& range) + { + // Build sheet name first and insert a new sheet. + std::ostringstream os_sheet_name; + os_sheet_name << sheet_name_prefix << range_count; + std::string sheet_name = os_sheet_name.str(); + append_sheet(sheet_name); + + // Push the linked range. + start_range(sheet_name, 0, 0, true); + + for (const std::string& s : range.paths) + append_field_link(s, std::string_view()); + + for (const std::string& s : range.row_groups) + set_range_row_group(s); + + commit_range(); + + ++range_count; + }; + + json::structure_tree structure; + structure.parse(stream); + structure.process_ranges(rh); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/orcus_ods.cpp b/src/liborcus/orcus_ods.cpp new file mode 100644 index 0000000..41acf65 --- /dev/null +++ b/src/liborcus/orcus_ods.cpp @@ -0,0 +1,230 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/orcus_ods.hpp> +#include <orcus/xml_namespace.hpp> +#include <orcus/zip_archive.hpp> +#include <orcus/zip_archive_stream.hpp> +#include <orcus/measurement.hpp> + +#include "xml_stream_parser.hpp" +#include "ods_content_xml_context.hpp" +#include "ods_session_data.hpp" +#include "odf_document_styles_context.hpp" +#include "odf_tokens.hpp" +#include "odf_styles.hpp" +#include "odf_namespace_types.hpp" +#include "session_context.hpp" + +#include <cstdlib> +#include <iostream> +#include <vector> +#include <cstring> + +namespace orcus { + +struct orcus_ods::impl +{ + xmlns_repository ns_repo; + session_context cxt; + spreadsheet::iface::import_factory* xfactory; + + impl(spreadsheet::iface::import_factory* im_factory) : + cxt(std::make_unique<ods_session_data>()), xfactory(im_factory) {} +}; + +orcus_ods::orcus_ods(spreadsheet::iface::import_factory* factory) : + iface::import_filter(format_t::ods), + mp_impl(std::make_unique<impl>(factory)) +{ + mp_impl->ns_repo.add_predefined_values(NS_odf_all); +} + +orcus_ods::~orcus_ods() = default; + +void orcus_ods::list_content(const zip_archive& archive) +{ + size_t num = archive.get_file_entry_count(); + std::cout << "number of files this archive contains: " << num << std::endl; + + for (size_t i = 0; i < num; ++i) + { + std::string_view filename = archive.get_file_entry_name(i); + if (filename.empty()) + std::cout << "(empty)" << std::endl; + else + std::cout << filename << std::endl; + } +} + +void orcus_ods::read_styles(const zip_archive& archive) +{ + auto* xstyles = mp_impl->xfactory->get_styles(); + if (!xstyles) + return; + + std::vector<unsigned char> buf; + + try + { + buf = archive.read_file_entry("styles.xml"); + } + catch (const std::exception& e) + { + std::cerr << "failed to get stat on styles.xml (reason: " << e.what() << ")" << std::endl; + return; + } + + xml_stream_parser parser( + get_config(), mp_impl->ns_repo, odf_tokens, + reinterpret_cast<const char*>(buf.data()), buf.size()); + + auto& ods_data = mp_impl->cxt.get_data<ods_session_data>(); + auto context = std::make_unique<document_styles_context>( + mp_impl->cxt, odf_tokens, ods_data.styles_map, xstyles); + + xml_stream_handler handler(mp_impl->cxt, odf_tokens, std::move(context)); + + parser.set_handler(&handler); + parser.parse(); + + if (get_config().debug) + dump_state(ods_data.styles_map, std::cout); +} + +void orcus_ods::read_content(const zip_archive& archive) +{ + std::vector<unsigned char> buf; + + try + { + buf = archive.read_file_entry("content.xml"); + } + catch (const std::exception& e) + { + std::cerr << "failed to get stat on content.xml (reason: " << e.what() << ")" << std::endl; + return; + } + + read_content_xml(buf.data(), buf.size()); +} + +void orcus_ods::read_content_xml(const unsigned char* p, size_t size) +{ + bool use_threads = true; + + if (const char* p_env = std::getenv("ORCUS_ODS_USE_THREADS"); p_env) + use_threads = to_bool(p_env); + + auto context = std::make_unique<ods_content_xml_context>( + mp_impl->cxt, odf_tokens, mp_impl->xfactory); + + if (use_threads) + { + threaded_xml_stream_parser parser( + get_config(), mp_impl->ns_repo, odf_tokens, + reinterpret_cast<const char*>(p), size); + + xml_stream_handler handler(mp_impl->cxt, odf_tokens, std::move(context)); + parser.set_handler(&handler); + parser.parse(); + + string_pool this_pool; + parser.swap_string_pool(this_pool); + mp_impl->cxt.spool.merge(this_pool); + } + else + { + xml_stream_parser parser( + get_config(), mp_impl->ns_repo, odf_tokens, + reinterpret_cast<const char*>(p), size); + + xml_stream_handler handler(mp_impl->cxt, odf_tokens, std::move(context)); + parser.set_handler(&handler); + parser.parse(); + } +} + +bool orcus_ods::detect(const unsigned char* blob, size_t size) +{ + zip_archive_stream_blob stream(blob, size); + zip_archive archive(&stream); + + try + { + archive.load(); + + std::vector<unsigned char> buf = archive.read_file_entry("mimetype"); + + if (buf.empty()) + // mimetype is empty. + return false; + + const char* mimetype = "application/vnd.oasis.opendocument.spreadsheet"; + size_t n = std::strlen(mimetype); + if (buf.size() < n) + return false; + + if (strncmp(mimetype, reinterpret_cast<const char*>(buf.data()), n)) + // The mimetype content differs. + return false; + } + catch (const zip_error&) + { + // Not a valid zip archive. + return false; + } + + return true; +} + +void orcus_ods::read_file(std::string_view filepath) +{ + zip_archive_stream_fd stream(std::string{filepath}.c_str()); + read_file_impl(&stream); +} + +void orcus_ods::read_stream(std::string_view stream) +{ + zip_archive_stream_blob blob( + reinterpret_cast<const uint8_t*>(stream.data()), stream.size()); + read_file_impl(&blob); +} + +void orcus_ods::read_file_impl(zip_archive_stream* stream) +{ + zip_archive archive(stream); + archive.load(); + if (get_config().debug) + list_content(archive); + + spreadsheet::formula_grammar_t old_grammar = spreadsheet::formula_grammar_t::unknown; + + spreadsheet::iface::import_global_settings* gs = mp_impl->xfactory->get_global_settings(); + if (gs) + { + old_grammar = gs->get_default_formula_grammar(); + gs->set_default_formula_grammar(spreadsheet::formula_grammar_t::ods); + } + + read_styles(archive); + read_content(archive); + + mp_impl->xfactory->finalize(); + + if (gs) + // This grammar will be used + gs->set_default_formula_grammar(old_grammar); +} + +std::string_view orcus_ods::get_name() const +{ + return "ods"; +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/orcus_parquet.cpp b/src/liborcus/orcus_parquet.cpp new file mode 100644 index 0000000..2bd85ac --- /dev/null +++ b/src/liborcus/orcus_parquet.cpp @@ -0,0 +1,547 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/orcus_parquet.hpp> +#include <orcus/stream.hpp> +#include <orcus/config.hpp> +#include <orcus/spreadsheet/types.hpp> + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#include <arrow/io/file.h> +#include <arrow/io/memory.h> +#include <parquet/stream_reader.h> +#include <parquet/arrow/reader.h> +#pragma GCC diagnostic pop + +#include "filesystem_env.hpp" + +#include <iostream> +#include <unordered_map> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +class orcus_parquet::impl +{ + using columns_type = std::vector<std::pair<ss::col_t, const parquet::ColumnDescriptor*>>; + + const config& m_config; + + ss::iface::import_factory* m_factory = nullptr; + ss::iface::import_shared_strings* m_sstrings = nullptr; + ss::iface::import_sheet* m_sheet = nullptr; + + columns_type m_columns; + + parquet::StreamReader m_stream; + + static columns_type init_columns(const parquet::FileMetaData& file_md) + { + columns_type columns; + + const parquet::SchemaDescriptor* schema_desc = file_md.schema(); + + if (!schema_desc) + return columns; + + columns.reserve(schema_desc->num_columns()); + + for (int i = 0; i < schema_desc->num_columns(); ++i) + { + const parquet::ColumnDescriptor* col_desc = schema_desc->Column(i); + columns.emplace_back(i, col_desc); + } + + return columns; + } + + void warn(std::string_view msg) const + { + if (!m_config.debug) + return; + + std::cerr << "warning: " << msg << std::endl; + } + + /** + * Import column labels as the first row. + */ + void import_column_labels() + { + // Import column labels as first row + for (const auto& [col, p] : m_columns) + { + if (!m_sstrings) + continue; + + std::size_t si = m_sstrings->add(p->name()); + m_sheet->set_string(0, col, si); + } + } + + template<typename T> + std::optional<T> read_or_warn(ss::row_t row, ss::col_t col) + { + T v; + + try + { + m_stream >> v; + return v; + } + catch (const std::exception& e) + { + std::ostringstream os; + os << "failed to read a value for (row=" << row << "; col=" << col << "): " << e.what(); + warn(os.str()); + } + + return std::optional<T>{}; + } + + void import_byte_array(ss::row_t row, ss::col_t col, const parquet::ColumnDescriptor* p) + { + switch (p->converted_type()) + { + case parquet::ConvertedType::UTF8: + { + if (!m_sstrings) + { + m_stream.SkipColumns(1); + break; + } + + if (auto v = read_or_warn<std::string>(row, col); v) + { + std::size_t si = m_sstrings->add(*v); + m_sheet->set_string(row, col, si); + } + break; + } + default: + { + std::ostringstream os; + os << "WIP: unhandled converted type for BYTE_ARRAY (converted=" + << p->converted_type() << ")"; + warn(os.str()); + m_stream.SkipColumns(1); + } + } + } + + void import_fixed_len_byte_array(ss::row_t /*row*/, ss::col_t /*col*/, const parquet::ColumnDescriptor* /*p*/) + { + warn("WIP: physical=FIXED_LEN_BYTE_ARRAY not handled yet"); + m_stream.SkipColumns(1); + } + + void import_int32(ss::row_t row, ss::col_t col, const parquet::ColumnDescriptor* p) + { + switch (p->converted_type()) + { + case parquet::ConvertedType::NONE: + { + if (auto v = read_or_warn<int32_t>(row, col); v) + m_sheet->set_value(row, col, *v); + break; + } + default: + warn("WIP: unhandled converted type for INT32"); + m_stream.SkipColumns(1); + } + } + + void import_int64(ss::row_t row, ss::col_t col, const parquet::ColumnDescriptor* p) + { + switch (p->converted_type()) + { + case parquet::ConvertedType::NONE: + { + if (auto v = read_or_warn<int64_t>(row, col); v) + m_sheet->set_value(row, col, *v); + break; + } + default: + warn("WIP: unhandled converted type for INT64"); + m_stream.SkipColumns(1); + } + } + + void import_int96(ss::row_t /*row*/, ss::col_t /*col*/, const parquet::ColumnDescriptor* /*p*/) + { + warn("WIP: physical=INT96 not handled yet"); + m_stream.SkipColumns(1); + } + + void import_boolean(ss::row_t row, ss::col_t col, const parquet::ColumnDescriptor* p) + { + if (p->converted_type() != parquet::ConvertedType::NONE) + { + warn("WIP: unhandled covnerted type for BOOLEAN"); + m_stream.SkipColumns(1); + return; + } + + if (auto v = read_or_warn<bool>(row, col); v) + m_sheet->set_bool(row, col, *v); + } + + void import_float(ss::row_t row, ss::col_t col, const parquet::ColumnDescriptor* p) + { + if (p->converted_type() != parquet::ConvertedType::NONE) + { + warn("WIP: unhandled covnerted type for FLOAT"); + m_stream.SkipColumns(1); + return; + } + + if (auto v = read_or_warn<float>(row, col); v) + m_sheet->set_value(row, col, *v); + } + + void import_double(ss::row_t row, ss::col_t col, const parquet::ColumnDescriptor* p) + { + if (p->converted_type() != parquet::ConvertedType::NONE) + { + warn("WIP: unhandled covnerted type for DOUBLE"); + m_stream.SkipColumns(1); + return; + } + + if (auto v = read_or_warn<double>(row, col); v) + m_sheet->set_value(row, col, *v); + } + + void dump_metadata(const parquet::FileMetaData& metadata) const + { + if (!m_config.debug) + return; + + auto _bool_v = [](bool v) { return v ? "true" : "false"; }; + + auto _version_v = [](parquet::ParquetVersion::type t) -> std::string + { + const std::unordered_map<parquet::ParquetVersion::type, std::string_view> mapping = + { + { parquet::ParquetVersion::PARQUET_1_0, "PARQUET_1_0" }, + { parquet::ParquetVersion::PARQUET_2_4, "PARQUET_2_4" }, + { parquet::ParquetVersion::PARQUET_2_6, "PARQUET_2_6" }, + }; + + std::ostringstream os; + auto it = mapping.find(t); + os << (it == mapping.end() ? "???" : it->second) << " (" << int(t) << ")"; + return os.str(); + }; + + auto _compression_v = [](parquet::Compression::type t) -> std::string + { + const std::unordered_map<parquet::Compression::type, std::string_view> mapping = + { + { parquet::Compression::UNCOMPRESSED, "UNCOMPRESSED" }, + { parquet::Compression::SNAPPY, "SNAPPY" }, + { parquet::Compression::GZIP, "GZIP" }, + { parquet::Compression::BROTLI, "BROTLI" }, + { parquet::Compression::ZSTD, "ZSTD" }, + { parquet::Compression::LZ4, "LZ4" }, + { parquet::Compression::LZ4_FRAME, "LZ4_FRAME" }, + { parquet::Compression::LZO, "LZO" }, + { parquet::Compression::BZ2, "BZ2" }, + { parquet::Compression::LZ4_HADOOP, "LZ4_HADOOP" }, + }; + + std::ostringstream os; + auto it = mapping.find(t); + os << (it == mapping.end() ? "???" : it->second) << " (" << int(t) << ")"; + return os.str(); + }; + + std::cerr << "metadata size: " << metadata.size() << std::endl; + std::cerr << "version: " << _version_v(metadata.version()) << std::endl; + std::cerr << "created by: " << metadata.created_by() << std::endl; + std::cerr << "num columns: " << metadata.num_columns() << std::endl; + std::cerr << "num rows: " << metadata.num_rows() << std::endl; + std::cerr << "num row groups: " << metadata.num_row_groups() << std::endl; + std::cerr << "num schema elements: " << metadata.num_schema_elements() << std::endl; + std::cerr << "can decompress: " << _bool_v(metadata.can_decompress()) << std::endl; + + for (int i = 0; i < metadata.num_row_groups(); ++i) + { + std::cerr << "row group " << i << ":" << std::endl; + auto rg = metadata.RowGroup(i); + std::cerr << " num rows: " << rg->num_rows() << std::endl; + std::cerr << " total byte size: " << rg->total_byte_size() << std::endl; + std::cerr << " total compressed size: " << rg->total_compressed_size() << std::endl; + std::cerr << " file offset: " << rg->file_offset() << std::endl; + std::cerr << " num columns: " << rg->num_columns() << std::endl; + + for (int j = 0; j < rg->num_columns(); ++j) + { + std::cerr << " column chunk " << j << ":" << std::endl; + auto cc = rg->ColumnChunk(j); + std::cerr << " file path: " << cc->file_path() << std::endl; + std::cerr << " num values: " << cc->num_values() << std::endl; + std::cerr << " type: " << cc->type() << std::endl; + std::cerr << " data page offset: " << std::dec << cc->data_page_offset() << std::endl; + std::cerr << " compression: " << _compression_v(cc->compression()) << std::endl; + std::cerr << " has dictionary page: " << _bool_v(cc->has_dictionary_page()) << std::endl; + + if (cc->has_dictionary_page()) + std::cerr << " dictionary page offset: " << cc->dictionary_page_offset() << std::endl; + + std::cerr << " has index page: " << _bool_v(cc->has_index_page()) << std::endl; + if (cc->has_index_page()) + std::cerr << " index page offset: " << cc->index_page_offset() << std::endl; + } + } + + if (const parquet::SchemaDescriptor* schema_desc = metadata.schema(); schema_desc) + { + std::cerr << "schema:" << std::endl; + std::cerr << " name: " << schema_desc->name() << std::endl; + std::cerr << " num columns: " << schema_desc->num_columns() << std::endl; + + for (int i = 0; i < schema_desc->num_columns(); ++i) + { + if (const parquet::ColumnDescriptor* col_desc = schema_desc->Column(i); col_desc) + { + std::cerr << " column " << i << ":" << std::endl; + std::cerr << " name: " << col_desc->name() << std::endl; + std::cerr << " physical type: " << col_desc->physical_type() << std::endl; + std::cerr << " converted type: " << col_desc->converted_type() << std::endl; + std::cerr << " type length: " << col_desc->type_length() << std::endl; + } + } + } + } + + /** + * Check to see if this file is safe to load. There are some conditions + * that are known to lead to trouble if we proceed to load. + */ + bool is_safe_to_load(const parquet::FileMetaData& metadata) const + { + const parquet::SchemaDescriptor* schema = metadata.schema(); + if (!schema) + return false; + + const auto* gnode = schema->group_node(); + if (!gnode) + return false; + + if (schema->group_node()->field_count() != schema->num_columns()) + // StreamReader assumes these two values to be equal, and crashes + // if not. But with some files the two can be different. + return false; + + return true; + } + + void read_stream_with_sheet_name(std::string_view sheet_name, std::string_view stream) + { + auto buf = std::make_shared<arrow::io::BufferReader>(stream); + + auto file_reader = parquet::ParquetFileReader::Open(buf); + if (!file_reader) + { + warn("failed to open a parquet file reader from an in-memory buffer."); + return; + } + + auto file_md = file_reader->metadata(); + + dump_metadata(*file_md); + + if (!is_safe_to_load(*file_md)) + { + warn("aborting because this file exhibits a condition known to lead to issues if loaded."); + return; + } + + if (file_md->num_rows() < 0 || file_md->num_columns() < 0) + // Nothing to import. Bail out. + return; + + m_sheet = m_factory->append_sheet(0, sheet_name); + + if (!m_sheet) + // Failed to append sheet. Bail out. + return; + + m_columns = init_columns(*file_md); + if (m_columns.empty()) + // Column data initialization failed. Bail out. + return; + + m_stream = parquet::StreamReader{std::move(file_reader)}; + if (m_stream.eof()) + return; + + m_sstrings = m_factory->get_shared_strings(); + + import_column_labels(); + + for (int i = 0; i < file_md->num_rows(); ++i) + { + ss::row_t row = i + 1; // account for the header row + + for (const auto& [col, p] : m_columns) + { + switch (p->physical_type()) + { + case parquet::Type::BOOLEAN: + { + import_boolean(row, col, p); + break; + } + case parquet::Type::INT32: + { + import_int32(row, col, p); + break; + } + case parquet::Type::INT64: + { + import_int64(row, col, p); + break; + } + case parquet::Type::INT96: + { + import_int96(row, col, p); + break; + } + case parquet::Type::FLOAT: + { + import_float(row, col, p); + break; + } + case parquet::Type::DOUBLE: + { + import_double(row, col, p); + break; + } + case parquet::Type::BYTE_ARRAY: + { + import_byte_array(row, col, p); + break; + } + case parquet::Type::FIXED_LEN_BYTE_ARRAY: + { + import_fixed_len_byte_array(row, col, p); + break; + } + default: + { + std::ostringstream os; + os << "WIP: type not handled: physical=" << p->physical_type() << "; converted=" << p->converted_type(); + warn(os.str()); + m_stream.SkipColumns(1); + } + } + } + + m_stream >> parquet::EndRow; + } + + m_factory->finalize(); + } + +public: + impl(const config& c, ss::iface::import_factory* factory) : m_config(c), m_factory(factory) {} + + void read_file(fs::path filepath) + { + file_content fc(filepath.string()); + try + { + read_stream_with_sheet_name(filepath.stem().string(), fc.str()); + } + catch (const std::exception& e) + { + warn(e.what()); + m_factory->finalize(); + } + } + + void read_stream(std::string_view stream) + { + try + { + read_stream_with_sheet_name("Data", stream); + } + catch (const std::exception& e) + { + warn(e.what()); + m_factory->finalize(); + } + } +}; + +orcus_parquet::orcus_parquet(spreadsheet::iface::import_factory* factory) : + iface::import_filter(format_t::parquet), + mp_impl(std::make_unique<impl>(get_config(), factory)) +{ +} + +orcus_parquet::~orcus_parquet() = default; + +bool orcus_parquet::detect(const unsigned char* blob, std::size_t size) +{ + if (size < 12u) + // At minimum header magic bytes (4), footer magic bytes (4), and the + // footer metadata length (4). + return false; + + const auto* p = blob; + + // Check the first 4 bytes. + if (std::string_view(reinterpret_cast<const char*>(p), 4) != "PAR1") + return false; + + // Check the last 4 bytes. + p += size - 4u; + if (std::string_view(reinterpret_cast<const char*>(p), 4) != "PAR1") + return false; + + // Check the footer metadata size (little endian) + p -= 1u; + std::uint32_t footer_size = *p--; + footer_size <<= 8; + footer_size |= *p--; + footer_size <<= 8; + footer_size |= *p--; + footer_size <<= 8; + footer_size |= *p; + + p -= footer_size; + if (p <= blob) + // footer metadata position must be within the stream. + return false; + + return true; +} + +void orcus_parquet::read_file(std::string_view filepath) +{ + mp_impl->read_file(fs::path{std::string{filepath}}); +} + +void orcus_parquet::read_stream(std::string_view stream) +{ + mp_impl->read_stream(stream); +} + +std::string_view orcus_parquet::get_name() const +{ + return "parquet"; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/orcus_xls_xml.cpp b/src/liborcus/orcus_xls_xml.cpp new file mode 100644 index 0000000..b37f9c5 --- /dev/null +++ b/src/liborcus/orcus_xls_xml.cpp @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/orcus_xls_xml.hpp" +#include "orcus/stream.hpp" +#include "orcus/xml_namespace.hpp" +#include "orcus/config.hpp" +#include "orcus/spreadsheet/import_interface.hpp" +#include "orcus/parser_base.hpp" + +#include "xml_stream_parser.hpp" +#include "xls_xml_handler.hpp" +#include "xls_xml_detection_handler.hpp" +#include "session_context.hpp" +#include "xls_xml_tokens.hpp" +#include "xls_xml_namespace_types.hpp" +#include "detection_result.hpp" + +#include <iostream> +#include <locale> +#include <codecvt> + +using namespace std; + +namespace orcus { + +struct orcus_xls_xml::impl +{ + xmlns_repository m_ns_repo; + session_context m_cxt; + spreadsheet::iface::import_factory* mp_factory; + + impl(spreadsheet::iface::import_factory* factory) : mp_factory(factory) {} + + void read_stream(const char* content, size_t len, const config& cnf) + { + if (!content || !len) + return; + + spreadsheet::iface::import_global_settings* gs = + mp_factory->get_global_settings(); + + if (!gs) + return; + + gs->set_origin_date(1899, 12, 30); + gs->set_default_formula_grammar(spreadsheet::formula_grammar_t::xls_xml); + + xml_stream_parser parser(cnf, m_ns_repo, xls_xml_tokens, content, len); + + auto handler = std::make_unique<xls_xml_handler>(m_cxt, xls_xml_tokens, mp_factory); + + parser.set_handler(handler.get()); + try + { + parser.parse(); + } + catch (const parse_error& e) + { + std::cerr << create_parse_error_output(std::string_view(content, len), e.offset()) << std::endl; + std::cerr << e.what() << std::endl; + return; + } + + mp_factory->finalize(); + } +}; + +orcus_xls_xml::orcus_xls_xml(spreadsheet::iface::import_factory* factory) : + iface::import_filter(format_t::xls_xml), + mp_impl(std::make_unique<impl>(factory)) +{ + mp_impl->m_ns_repo.add_predefined_values(NS_xls_xml_all); +} + +orcus_xls_xml::~orcus_xls_xml() = default; + +bool orcus_xls_xml::detect(const unsigned char* buffer, size_t size) +{ + memory_content mem_content({reinterpret_cast<const char*>(buffer), size}); + mem_content.convert_to_utf8(); + + config opt(format_t::xls_xml); + xmlns_repository ns_repo; + ns_repo.add_predefined_values(NS_xls_xml_all); + xml_stream_parser parser(opt, ns_repo, xls_xml_tokens, mem_content.data(), mem_content.size()); + + session_context cxt; + xls_xml_detection_handler handler(cxt, xls_xml_tokens); + parser.set_handler(&handler); + try + { + parser.parse(); + } + catch (const detection_result& res) + { + return res.get_result(); + } + catch (...) {} + + return false; +} + +void orcus_xls_xml::read_file(std::string_view filepath) +{ + file_content content(filepath.data()); + if (content.empty()) + return; + + content.convert_to_utf8(); + mp_impl->read_stream(content.data(), content.size(), get_config()); +} + +void orcus_xls_xml::read_stream(std::string_view stream) +{ + memory_content mem_content(stream); + if (mem_content.empty()) + return; + + mem_content.convert_to_utf8(); + mp_impl->read_stream(mem_content.data(), mem_content.size(), get_config()); +} + +std::string_view orcus_xls_xml::get_name() const +{ + return "xls-xml"; +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/orcus_xlsx.cpp b/src/liborcus/orcus_xlsx.cpp new file mode 100644 index 0000000..db55dd2 --- /dev/null +++ b/src/liborcus/orcus_xlsx.cpp @@ -0,0 +1,824 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/orcus_xlsx.hpp" + +#include "orcus/xml_namespace.hpp" +#include "orcus/spreadsheet/import_interface.hpp" +#include "orcus/exception.hpp" +#include "orcus/config.hpp" +#include "orcus/measurement.hpp" + +#include "xlsx_types.hpp" +#include "xlsx_handler.hpp" +#include "xlsx_shared_strings_context.hpp" +#include "xlsx_styles_context.hpp" +#include "xlsx_workbook_context.hpp" +#include "xlsx_revision_context.hpp" +#include "ooxml_tokens.hpp" + +#include "xml_stream_parser.hpp" +#include "xml_simple_stream_handler.hpp" +#include "opc_reader.hpp" +#include "ooxml_namespace_types.hpp" +#include "xlsx_session_data.hpp" +#include "opc_context.hpp" +#include "ooxml_global.hpp" +#include "spreadsheet_iface_util.hpp" +#include "ooxml_content_types.hpp" + +#include <cstdlib> +#include <iostream> +#include <limits> +#include <string> +#include <cstring> +#include <sstream> + +using namespace std; + +namespace orcus { + +class xlsx_opc_handler : public opc_reader::part_handler +{ + orcus_xlsx& m_parent; +public: + xlsx_opc_handler(orcus_xlsx& parent) : m_parent(parent) {} + virtual ~xlsx_opc_handler() {} + + virtual bool handle_part( + schema_t type, const std::string& dir_path, const std::string& file_name, opc_rel_extra* data) + { + if (type == SCH_od_rels_office_doc) + { + m_parent.read_workbook(dir_path, file_name); + return true; + } + else if (type == SCH_od_rels_worksheet) + { + m_parent.read_sheet(dir_path, file_name, static_cast<xlsx_rel_sheet_info*>(data)); + return true; + } + else if (type == SCH_od_rels_shared_strings) + { + m_parent.read_shared_strings(dir_path, file_name); + return true; + } + else if (type == SCH_od_rels_styles) + { + m_parent.read_styles(dir_path, file_name); + return true; + } + else if (type == SCH_od_rels_drawing) + { + m_parent.read_drawing(dir_path, file_name); + return true; + } + else if (type == SCH_od_rels_table) + { + m_parent.read_table(dir_path, file_name, static_cast<xlsx_rel_table_info*>(data)); + return true; + } + else if (type == SCH_od_rels_pivot_cache_def) + { + m_parent.read_pivot_cache_def( + dir_path, file_name, static_cast<xlsx_rel_pivot_cache_info*>(data)); + return true; + } + else if (type == SCH_od_rels_pivot_cache_rec) + { + m_parent.read_pivot_cache_rec( + dir_path, file_name, + static_cast<const xlsx_rel_pivot_cache_record_info*>(data)); + return true; + } + else if (type == SCH_od_rels_pivot_table) + { + m_parent.read_pivot_table(dir_path, file_name); + return true; + } + else if (type == SCH_od_rels_rev_headers) + { + m_parent.read_rev_headers(dir_path, file_name); + return true; + } + else if (type == SCH_od_rels_rev_log) + { + m_parent.read_rev_log(dir_path, file_name); + return true; + } + + return false; + } +}; + +struct orcus_xlsx::impl +{ + session_context m_cxt; + xmlns_repository m_ns_repo; + spreadsheet::iface::import_factory* mp_factory; + xlsx_opc_handler m_opc_handler; + opc_reader m_opc_reader; + + impl(spreadsheet::iface::import_factory* factory, orcus_xlsx& parent) : + m_cxt(std::make_unique<xlsx_session_data>()), + mp_factory(factory), + m_opc_handler(parent), + m_opc_reader(parent.get_config(), m_ns_repo, m_cxt, m_opc_handler) {} +}; + +orcus_xlsx::orcus_xlsx(spreadsheet::iface::import_factory* factory) : + iface::import_filter(format_t::xlsx), + mp_impl(std::make_unique<impl>(factory, *this)) +{ + if (!factory) + throw std::invalid_argument("factory instance is required."); + + spreadsheet::iface::import_global_settings* gs = factory->get_global_settings(); + if (gs) + { + gs->set_origin_date(1899, 12, 30); + gs->set_default_formula_grammar(spreadsheet::formula_grammar_t::xlsx); + } + + mp_impl->m_ns_repo.add_predefined_values(NS_ooxml_all); + mp_impl->m_ns_repo.add_predefined_values(NS_opc_all); + mp_impl->m_ns_repo.add_predefined_values(NS_misc_all); +} + +orcus_xlsx::~orcus_xlsx() {} + +bool orcus_xlsx::detect(const unsigned char* blob, size_t size) +{ + zip_archive_stream_blob stream(blob, size); + zip_archive archive(&stream); + + try + { + archive.load(); + + // Find and parse [Content_Types].xml which is required for OPC package. + std::vector<unsigned char> buf = archive.read_file_entry("[Content_Types].xml"); + + if (buf.empty()) + return false; + + config opt(format_t::xlsx); + xmlns_repository ns_repo; + ns_repo.add_predefined_values(NS_opc_all); + session_context session_cxt; + xml_stream_parser parser( + opt, ns_repo, opc_tokens, reinterpret_cast<const char*>(&buf[0]), buf.size()); + + xml_simple_stream_handler handler( + session_cxt, opc_tokens, + std::make_unique<opc_content_types_context>(session_cxt, opc_tokens)); + parser.set_handler(&handler); + parser.parse(); + + opc_content_types_context& context = + static_cast<opc_content_types_context&>(handler.get_context()); + + std::vector<xml_part_t> parts; + context.pop_parts(parts); + + if (parts.empty()) + return false; + + // See if we can find the workbook stream. + xml_part_t workbook_part("/xl/workbook.xml", CT_ooxml_xlsx_sheet_main); + return std::find(parts.begin(), parts.end(), workbook_part) != parts.end(); + } + catch (const std::exception&) + { + return false; + } +} + +void orcus_xlsx::read_file(std::string_view filepath) +{ + std::unique_ptr<zip_archive_stream> stream( + new zip_archive_stream_fd(std::string{filepath}.c_str())); + mp_impl->m_opc_reader.read_file(std::move(stream)); + + // Formulas need to be inserted to the document after the shared string + // table get imported, because tokenization of formulas may add new shared + // string instances. + set_formulas_to_doc(); + + mp_impl->mp_factory->finalize(); +} + +void orcus_xlsx::read_stream(std::string_view stream) +{ + std::unique_ptr<zip_archive_stream> blob( + new zip_archive_stream_blob( + reinterpret_cast<const uint8_t*>(stream.data()), stream.size())); + mp_impl->m_opc_reader.read_file(std::move(blob)); + + // Formulas need to be inserted to the document after the shared string + // table get imported, because tokenization of formulas may add new shared + // string instances. + set_formulas_to_doc(); + + mp_impl->mp_factory->finalize(); +} + +std::string_view orcus_xlsx::get_name() const +{ + return "xlsx"; +} + +void orcus_xlsx::set_formulas_to_doc() +{ + auto push_formula_result = [this](spreadsheet::iface::import_formula* formula, const formula_result& res) + { + switch (res.type) + { + case formula_result::result_type::numeric: + formula->set_result_value(res.value_numeric); + break; + case formula_result::result_type::string: + formula->set_result_string({res.value_string.p, res.value_string.n}); + break; + case formula_result::result_type::empty: + break; + default: + { + if (get_config().debug) + std::cerr << "warning: unhandled formula result (orcus_xlsx::set_formulas_to_doc)" << std::endl; + } + } + }; + + auto& sdata = mp_impl->m_cxt.get_data<xlsx_session_data>(); + + // Insert shared formulas first. + for (auto& p : sdata.m_shared_formulas) + { + xlsx_session_data::shared_formula& sf = *p; + spreadsheet::iface::import_sheet* sheet = mp_impl->mp_factory->get_sheet(sf.sheet); + if (!sheet) + continue; + + spreadsheet::iface::import_formula* formula = sheet->get_formula(); + if (!formula) + continue; + + formula->set_position(sf.row, sf.column); + if (sf.master) + formula->set_formula(orcus::spreadsheet::formula_grammar_t::xlsx, sf.formula); + formula->set_shared_formula_index(sf.identifier); + + push_formula_result(formula, sf.result); + formula->commit(); + } + + // Insert regular (non-shared) formulas. + for (auto& p : sdata.m_formulas) + { + xlsx_session_data::formula& f = *p; + spreadsheet::iface::import_sheet* sheet = mp_impl->mp_factory->get_sheet(f.sheet); + if (!sheet) + continue; + + spreadsheet::iface::import_formula* formula = sheet->get_formula(); + if (!formula) + continue; + + formula->set_position(f.ref.row, f.ref.column); + formula->set_formula(orcus::spreadsheet::formula_grammar_t::xlsx, f.exp); + + push_formula_result(formula, f.result); + formula->commit(); + } + + // Insert array formulas. + for (auto& p : sdata.m_array_formulas) + { + xlsx_session_data::array_formula& af = *p; + spreadsheet::iface::import_sheet* sheet = mp_impl->mp_factory->get_sheet(af.sheet); + if (!sheet) + continue; + + spreadsheet::iface::import_array_formula* xaf = sheet->get_array_formula(); + push_array_formula(xaf, af.ref, af.exp, spreadsheet::formula_grammar_t::xlsx, *af.results); + } +} + +namespace { + +size_t get_schema_rank(const schema_t sch) +{ + using map_type = std::unordered_map <schema_t, size_t>; + + static const schema_t schema_rank[] = { + SCH_od_rels_shared_strings, + SCH_od_rels_pivot_cache_def, + SCH_od_rels_worksheet, + nullptr + }; + + static map_type rank_map; + + if (rank_map.empty()) + { + // initialize it. + size_t rank = 0; + for (const schema_t* p = schema_rank; *p; ++rank, ++p) + { + rank_map.insert( + map_type::value_type(*p, rank)); + } + } + + auto it = rank_map.find(sch); + return it == rank_map.end() ? numeric_limits<size_t>::max() : it->second; +} + +} + +void orcus_xlsx::read_workbook(const string& dir_path, const string& file_name) +{ + std::string filepath = resolve_file_path(dir_path, file_name); + if (get_config().debug) + cout << "read_workbook: file path = " << filepath << endl; + + vector<unsigned char> buffer; + if (!mp_impl->m_opc_reader.open_zip_stream(filepath, buffer)) + return; + + if (buffer.empty()) + return; + + auto handler = std::make_unique<xml_simple_stream_handler>( + mp_impl->m_cxt, ooxml_tokens, + std::make_unique<xlsx_workbook_context>(mp_impl->m_cxt, ooxml_tokens, *mp_impl->mp_factory)); + + xml_stream_parser parser( + get_config(), mp_impl->m_ns_repo, ooxml_tokens, + reinterpret_cast<const char*>(&buffer[0]), buffer.size()); + parser.set_handler(handler.get()); + parser.parse(); + + // Get sheet info from the context instance. + xlsx_workbook_context& context = + static_cast<xlsx_workbook_context&>(handler->get_context()); + opc_rel_extras_t workbook_data; + context.pop_workbook_info(workbook_data); + if (get_config().debug) + { + for_each(workbook_data.data.begin(), workbook_data.data.end(), + [](const opc_rel_extras_t::map_type::value_type& v) + { + const xlsx_rel_sheet_info* info = + dynamic_cast<const xlsx_rel_sheet_info*>(v.second.get()); + + if (info) + { + cout << "relationship id: " << v.first << "; sheet name: " << info->name << "; sheet id: " << info->id << endl; + } + + const xlsx_rel_pivot_cache_info* info_pc = + dynamic_cast<const xlsx_rel_pivot_cache_info*>(v.second.get()); + + if (info_pc) + { + cout << "relationship id: " << v.first << "; pivot cache id: " << info_pc->id << endl; + } + } + ); + } + + handler.reset(); + + // Re-order the relation items so that shared strings get imported first, + // pivot caches get imported before the sheets and so on. + + opc_reader::sort_compare_type sort_func = + [](const opc_rel_t& left, const opc_rel_t& right) + { + size_t rank_left = get_schema_rank(left.type), rank_right = get_schema_rank(right.type); + if (rank_left != rank_right) + return rank_left < rank_right; + + std::string_view rid1 = left.rid, rid2 = right.rid; + + if (rid1.size() > 1 && rid2.size() > 1) + { + // numerical comparison of relation ID's. + rid1 = std::string_view(rid1.data()+1, rid1.size()-1); // remove the 'r' prefix. + rid2 = std::string_view(rid2.data()+1, rid2.size()-1); // remove the 'r' prefix. + return to_long(rid1) < to_long(rid2); + } + + // textural comparison of relation ID's. + return left.rid < right.rid; + }; + + mp_impl->m_opc_reader.check_relation_part(file_name, &workbook_data, &sort_func); +} + +void orcus_xlsx::read_sheet( + const std::string& dir_path, const std::string& file_name, xlsx_rel_sheet_info* data) +{ + if (!data || !data->id) + // Sheet ID must not be 0. + return; + + std::string filepath = resolve_file_path(dir_path, file_name); + if (get_config().debug) + { + cout << "---" << endl; + cout << "read_sheet: file path = " << filepath << endl; + } + + vector<unsigned char> buffer; + if (!mp_impl->m_opc_reader.open_zip_stream(filepath, buffer)) + return; + + if (buffer.empty()) + return; + + if (get_config().debug) + { + cout << "relationship sheet data: " << endl; + cout << " sheet name: " << data->name << " sheet ID: " << data->id << endl; + } + + spreadsheet::iface::import_sheet* sheet = mp_impl->mp_factory->get_sheet(data->name); + if (!sheet) + { + std::ostringstream os; + os << "orcus_xlsx::read_sheet: "; + os << "sheet named '" << data->name << "' doesn't exist."; + throw general_error(os.str()); + } + + spreadsheet::iface::import_reference_resolver* resolver = + mp_impl->mp_factory->get_reference_resolver(spreadsheet::formula_ref_context_t::global); + if (!resolver) + throw general_error("orcus_xlsx::read_sheet: reference resolver interface is not available."); + + xml_stream_parser parser( + get_config(), mp_impl->m_ns_repo, ooxml_tokens, + reinterpret_cast<const char*>(&buffer[0]), buffer.size()); + + auto handler = std::make_unique<xlsx_sheet_xml_handler>( + mp_impl->m_cxt, ooxml_tokens, data->id-1, *resolver, *sheet); + + parser.set_handler(handler.get()); + parser.parse(); + + opc_rel_extras_t table_info; + handler->pop_rel_extras(table_info); + handler.reset(); + mp_impl->m_opc_reader.check_relation_part(file_name, &table_info); +} + +void orcus_xlsx::read_shared_strings(const std::string& dir_path, const std::string& file_name) +{ + std::string filepath = resolve_file_path(dir_path, file_name); + if (get_config().debug) + { + cout << "---" << endl; + cout << "read_shared_strings: file path = " << filepath << endl; + } + + vector<unsigned char> buffer; + if (!mp_impl->m_opc_reader.open_zip_stream(filepath, buffer)) + return; + + if (buffer.empty()) + return; + + xml_stream_parser parser( + get_config(), mp_impl->m_ns_repo, ooxml_tokens, + reinterpret_cast<const char*>(&buffer[0]), buffer.size()); + + auto handler = std::make_unique<xml_simple_stream_handler>( + mp_impl->m_cxt, ooxml_tokens, + std::make_unique<xlsx_shared_strings_context>( + mp_impl->m_cxt, ooxml_tokens, mp_impl->mp_factory->get_shared_strings())); + + parser.set_handler(handler.get()); + parser.parse(); +} + +void orcus_xlsx::read_styles(const std::string& dir_path, const std::string& file_name) +{ + std::string filepath = resolve_file_path(dir_path, file_name); + if (get_config().debug) + { + cout << "---" << endl; + cout << "read_styles: file path = " << filepath << endl; + } + + spreadsheet::iface::import_styles* styles = mp_impl->mp_factory->get_styles(); + if (!styles) + // Client code doesn't support styles. + return; + + vector<unsigned char> buffer; + if (!mp_impl->m_opc_reader.open_zip_stream(filepath, buffer)) + return; + + if (buffer.empty()) + return; + + xml_stream_parser parser( + get_config(), mp_impl->m_ns_repo, ooxml_tokens, + reinterpret_cast<const char*>(&buffer[0]), buffer.size()); + + auto handler = std::make_unique<xml_simple_stream_handler>( + mp_impl->m_cxt, ooxml_tokens, + std::make_unique<xlsx_styles_context>( + mp_impl->m_cxt, ooxml_tokens, mp_impl->mp_factory->get_styles())); + + parser.set_handler(handler.get()); + parser.parse(); +} + +void orcus_xlsx::read_table(const std::string& dir_path, const std::string& file_name, xlsx_rel_table_info* data) +{ + if (!data || !data->sheet_interface) + return; + + spreadsheet::iface::import_table* table = data->sheet_interface->get_table(); + if (!table) + // Client code doesn't support tables. No point going further. + return; + + spreadsheet::iface::import_reference_resolver* resolver = + mp_impl->mp_factory->get_reference_resolver(spreadsheet::formula_ref_context_t::global); + + if (!resolver) + // This client doesn't support reference resolver, but is required. + return; + + std::string filepath = resolve_file_path(dir_path, file_name); + if (get_config().debug) + { + cout << "---" << endl; + cout << "read_table: file path = " << filepath << endl; + } + + vector<unsigned char> buffer; + if (!mp_impl->m_opc_reader.open_zip_stream(filepath, buffer)) + { + cerr << "failed to open zip stream: " << filepath << endl; + return; + } + + if (buffer.empty()) + return; + + auto handler = std::make_unique<xlsx_table_xml_handler>( + mp_impl->m_cxt, ooxml_tokens, *table, *resolver); + + xml_stream_parser parser( + get_config(), mp_impl->m_ns_repo, ooxml_tokens, + reinterpret_cast<const char*>(&buffer[0]), buffer.size()); + parser.set_handler(handler.get()); + parser.parse(); + + handler.reset(); +} + +void orcus_xlsx::read_pivot_cache_def( + const std::string& dir_path, const std::string& file_name, + const xlsx_rel_pivot_cache_info* data) +{ + if (!data) + { + if (get_config().debug) + { + cout << "---" << endl; + cout << "required pivot cache relation info was not present." << endl; + } + return; + } + + std::string filepath = resolve_file_path(dir_path, file_name); + if (get_config().debug) + { + cout << "---" << endl; + cout << "read_pivot_cache_def: file path = " << filepath + << "; cache id = " << data->id << endl; + } + + vector<unsigned char> buffer; + if (!mp_impl->m_opc_reader.open_zip_stream(filepath, buffer)) + { + cerr << "failed to open zip stream: " << filepath << endl; + return; + } + + if (buffer.empty()) + return; + + spreadsheet::iface::import_pivot_cache_definition* pcache = + mp_impl->mp_factory->create_pivot_cache_definition(data->id); + + if (!pcache) + // failed to create a cache instance for whatever reason. + return; + + auto handler = std::make_unique<xlsx_pivot_cache_def_xml_handler>( + mp_impl->m_cxt, ooxml_tokens, *pcache, data->id); + + xml_stream_parser parser( + get_config(), mp_impl->m_ns_repo, ooxml_tokens, + reinterpret_cast<const char*>(&buffer[0]), buffer.size()); + parser.set_handler(handler.get()); + parser.parse(); + + opc_rel_extras_t pcache_info = handler->pop_rel_extras(); + + handler.reset(); + mp_impl->m_opc_reader.check_relation_part(file_name, &pcache_info); +} + +void orcus_xlsx::read_pivot_cache_rec( + const std::string& dir_path, const std::string& file_name, + const xlsx_rel_pivot_cache_record_info* data) +{ + if (!data) + { + if (get_config().debug) + { + cout << "---" << endl; + cout << "required pivot cache record relation info was not present." << endl; + } + return; + } + + std::string filepath = resolve_file_path(dir_path, file_name); + if (get_config().debug) + { + cout << "---" << endl; + cout << "read_pivot_cache_rec: file path = " << filepath << "; cache id = " << data->id << endl; + } + + vector<unsigned char> buffer; + if (!mp_impl->m_opc_reader.open_zip_stream(filepath, buffer)) + { + cerr << "failed to open zip stream: " << filepath << endl; + return; + } + + if (buffer.empty()) + return; + + spreadsheet::iface::import_pivot_cache_records* pcache_records = + mp_impl->mp_factory->create_pivot_cache_records(data->id); + + if (!pcache_records) + return; + + auto handler = std::make_unique<xlsx_pivot_cache_rec_xml_handler>( + mp_impl->m_cxt, ooxml_tokens, *pcache_records); + + xml_stream_parser parser( + get_config(), mp_impl->m_ns_repo, ooxml_tokens, + reinterpret_cast<const char*>(&buffer[0]), buffer.size()); + parser.set_handler(handler.get()); + parser.parse(); + + handler.reset(); +} + +void orcus_xlsx::read_pivot_table(const std::string& dir_path, const std::string& file_name) +{ + std::string filepath = resolve_file_path(dir_path, file_name); + if (get_config().debug) + { + cout << "---" << endl; + cout << "read_pivot_table: file path = " << filepath << endl; + } + + vector<unsigned char> buffer; + if (!mp_impl->m_opc_reader.open_zip_stream(filepath, buffer)) + { + cerr << "failed to open zip stream: " << filepath << endl; + return; + } + + if (buffer.empty()) + return; + + auto handler = std::make_unique<xlsx_pivot_table_xml_handler>(mp_impl->m_cxt, ooxml_tokens); + + xml_stream_parser parser( + get_config(), mp_impl->m_ns_repo, ooxml_tokens, + reinterpret_cast<const char*>(&buffer[0]), buffer.size()); + parser.set_handler(handler.get()); + parser.parse(); + + handler.reset(); + mp_impl->m_opc_reader.check_relation_part(file_name, nullptr); +} + +void orcus_xlsx::read_rev_headers(const std::string& dir_path, const std::string& file_name) +{ + std::string filepath = resolve_file_path(dir_path, file_name); + if (get_config().debug) + { + cout << "---" << endl; + cout << "read_rev_headers: file path = " << filepath << endl; + } + + vector<unsigned char> buffer; + if (!mp_impl->m_opc_reader.open_zip_stream(filepath, buffer)) + { + cerr << "failed to open zip stream: " << filepath << endl; + return; + } + + if (buffer.empty()) + return; + + xml_stream_parser parser( + get_config(), mp_impl->m_ns_repo, ooxml_tokens, + reinterpret_cast<const char*>(&buffer[0]), buffer.size()); + + auto handler = std::make_unique<xml_simple_stream_handler>( + mp_impl->m_cxt, ooxml_tokens, + std::make_unique<xlsx_revheaders_context>(mp_impl->m_cxt, ooxml_tokens)); + + parser.set_handler(handler.get()); + parser.parse(); + + handler.reset(); + mp_impl->m_opc_reader.check_relation_part(file_name, nullptr); +} + +void orcus_xlsx::read_rev_log(const std::string& dir_path, const std::string& file_name) +{ + std::string filepath = resolve_file_path(dir_path, file_name); + if (get_config().debug) + { + cout << "---" << endl; + cout << "read_rev_log: file path = " << filepath << endl; + } + + vector<unsigned char> buffer; + if (!mp_impl->m_opc_reader.open_zip_stream(filepath, buffer)) + { + cerr << "failed to open zip stream: " << filepath << endl; + return; + } + + if (buffer.empty()) + return; + + xml_stream_parser parser( + get_config(), mp_impl->m_ns_repo, ooxml_tokens, + reinterpret_cast<const char*>(&buffer[0]), buffer.size()); + + auto handler = std::make_unique<xml_simple_stream_handler>( + mp_impl->m_cxt, ooxml_tokens, + std::make_unique<xlsx_revlog_context>(mp_impl->m_cxt, ooxml_tokens)); + + parser.set_handler(handler.get()); + parser.parse(); + + handler.reset(); +} + +void orcus_xlsx::read_drawing(const std::string& dir_path, const std::string& file_name) +{ + std::string filepath = resolve_file_path(dir_path, file_name); + if (get_config().debug) + { + cout << "---" << endl; + cout << "read_drawing: file path = " << filepath << endl; + } + + vector<unsigned char> buffer; + if (!mp_impl->m_opc_reader.open_zip_stream(filepath, buffer)) + { + cerr << "failed to open zip stream: " << filepath << endl; + return; + } + + if (buffer.empty()) + return; + + auto handler = std::make_unique<xlsx_drawing_xml_handler>( + mp_impl->m_cxt, ooxml_tokens); + + xml_stream_parser parser( + get_config(), mp_impl->m_ns_repo, ooxml_tokens, + reinterpret_cast<const char*>(&buffer[0]), buffer.size()); + parser.set_handler(handler.get()); + parser.parse(); + + handler.reset(); +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/orcus_xml.cpp b/src/liborcus/orcus_xml.cpp new file mode 100644 index 0000000..e123265 --- /dev/null +++ b/src/liborcus/orcus_xml.cpp @@ -0,0 +1,702 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/orcus_xml.hpp> +#include <orcus/sax_ns_parser.hpp> +#include <orcus/spreadsheet/import_interface.hpp> +#include <orcus/spreadsheet/export_interface.hpp> +#include <orcus/stream.hpp> +#include <orcus/string_pool.hpp> + +#include "orcus_xml_impl.hpp" + +#define ORCUS_DEBUG_XML 0 + +#if ORCUS_DEBUG_XML +#include <iostream> +#endif + +#include <vector> +#include <fstream> + +namespace orcus { + +namespace { + +class xml_data_sax_handler +{ + struct scope + { + xml_name_t name; + std::ptrdiff_t element_open_begin; + std::ptrdiff_t element_open_end; + + xml_map_tree::element_type type; + + scope(xmlns_id_t _ns, std::string_view _name) : + name(_ns, _name), + element_open_begin(0), + element_open_end(0), + type(xml_map_tree::element_type::unknown) {} + }; + + std::vector<sax_ns_parser_attribute> m_attrs; + std::vector<scope> m_scopes; + + string_pool m_pool; + spreadsheet::iface::import_factory& m_factory; + xml_map_tree::const_element_list_type& m_link_positions; + const xml_map_tree& m_map_tree; + xml_map_tree::walker m_map_tree_walker; + + xml_map_tree::element* mp_current_elem; + std::string_view m_current_chars; + bool m_in_range_ref; + xml_map_tree::range_reference* mp_increment_row; + +private: + + const sax_ns_parser_attribute* find_attr_by_name(const xml_name_t& name) + { + for (const sax_ns_parser_attribute& attr : m_attrs) + { + if (attr.ns == name.ns && attr.name == name.name) + return &attr; + } + return nullptr; + } + + void set_single_link_cell(const xml_map_tree::cell_reference& ref, std::string_view val) + { + spreadsheet::iface::import_sheet* sheet = m_factory.get_sheet(ref.pos.sheet); + if (sheet) + sheet->set_auto(ref.pos.row, ref.pos.col, val); + } + + void set_field_link_cell(xml_map_tree::field_in_range& field, std::string_view val) + { + assert(field.ref); + assert(!field.ref->pos.sheet.empty()); + + const xml_map_tree::cell_position& pos = field.ref->pos; + spreadsheet::iface::import_sheet* sheet = m_factory.get_sheet(pos.sheet); + if (sheet) + sheet->set_auto( + pos.row + field.ref->row_position, + pos.col + field.column_pos, + val); + } + +public: + xml_data_sax_handler( + spreadsheet::iface::import_factory& factory, + xml_map_tree::const_element_list_type& link_positions, + const xml_map_tree& map_tree) : + m_factory(factory), + m_link_positions(link_positions), + m_map_tree(map_tree), + m_map_tree_walker(map_tree.get_tree_walker()), + mp_current_elem(nullptr), + m_in_range_ref(false), + mp_increment_row(nullptr) {} + + void doctype(const sax::doctype_declaration&) + { + } + + void start_declaration(std::string_view) + { + } + + void end_declaration(std::string_view) + { + m_attrs.clear(); + } + + void start_element(const sax_ns_parser_element& elem) + { + m_scopes.emplace_back(elem.ns, elem.name); + scope& cur = m_scopes.back(); + cur.element_open_begin = elem.begin_pos; + cur.element_open_end = elem.end_pos; + m_current_chars = std::string_view{}; + + mp_current_elem = m_map_tree_walker.push_element({elem.ns, elem.name}); + if (mp_current_elem) + { + if (mp_current_elem->row_group && mp_increment_row == mp_current_elem->row_group) + { + // The last closing element was a row group boundary. Increment the row position. + xml_map_tree::range_reference* ref = mp_current_elem->row_group; + ++ref->row_position; + mp_increment_row = nullptr; + } + + // Go through all linked attributes that belong to this element, + // and see if they exist in this content xml. + for (const auto& p_attr : mp_current_elem->attributes) + { + const xml_map_tree::attribute& linked_attr = *p_attr; + const sax_ns_parser_attribute* p = find_attr_by_name(linked_attr.name); + if (!p) + continue; + + // This attribute is linked. Import its value. + + std::string_view val_trimmed = trim(p->value); + switch (linked_attr.ref_type) + { + case xml_map_tree::reference_type::cell: + set_single_link_cell(*linked_attr.cell_ref, val_trimmed); + break; + case xml_map_tree::reference_type::range_field: + { + set_field_link_cell(*linked_attr.field_ref, val_trimmed); + break; + } + default: + ; + } + + // Record the namespace alias used in the content stream. + linked_attr.ns_alias = m_map_tree.intern_string(p->ns_alias); + } + + if (mp_current_elem->range_parent) + m_in_range_ref = true; + } + m_attrs.clear(); + } + + void end_element(const sax_ns_parser_element& elem) + { + assert(!m_scopes.empty()); + + if (mp_current_elem) + { + switch (mp_current_elem->ref_type) + { + case xml_map_tree::reference_type::cell: + { + set_single_link_cell(*mp_current_elem->cell_ref, m_current_chars); + break; + } + case xml_map_tree::reference_type::range_field: + { + set_field_link_cell(*mp_current_elem->field_ref, m_current_chars); + break; + } + default: + ; + } + + if (mp_current_elem->row_group) + { + // This element defines a row-group boundary. + spreadsheet::row_t row_start = mp_current_elem->row_group_position; + spreadsheet::row_t row_end = mp_current_elem->row_group->row_position - 1; + if (row_end > row_start) + { + // This is the end of a parent row-group. Fill down the + // cell values. + const xml_map_tree::range_reference& ref = *mp_current_elem->row_group; + + spreadsheet::iface::import_sheet* sheet = m_factory.get_sheet(ref.pos.sheet); + + if (sheet) + { + row_start += ref.pos.row + 1; + row_end += ref.pos.row + 1; + + for (spreadsheet::col_t col : mp_current_elem->linked_range_fields) + { + col += ref.pos.col; + sheet->fill_down_cells(row_start, col, row_end - row_start); + } + } + } + + mp_current_elem->row_group_position = mp_current_elem->row_group->row_position; + mp_increment_row = mp_current_elem->row_group; + } + + // Store the end element position in stream for linked elements. + const scope& cur = m_scopes.back(); + if (mp_current_elem->ref_type == xml_map_tree::reference_type::cell || + mp_current_elem->range_parent || + (!m_in_range_ref && mp_current_elem->unlinked_attribute_anchor())) + { + // either single link element, parent of range link elements, + // or an unlinked attribute anchor outside linked ranges. + mp_current_elem->stream_pos.open_begin = cur.element_open_begin; + mp_current_elem->stream_pos.open_end = cur.element_open_end; + mp_current_elem->stream_pos.close_begin = elem.begin_pos; + mp_current_elem->stream_pos.close_end = elem.end_pos; + m_link_positions.push_back(mp_current_elem); + } + + if (mp_current_elem->range_parent) + m_in_range_ref = false; + + // Record the namespace alias used in the content stream. + mp_current_elem->ns_alias = m_map_tree.intern_string(elem.ns_alias); + } + + m_scopes.pop_back(); + mp_current_elem = m_map_tree_walker.pop_element({elem.ns, elem.name}); + } + + void characters(std::string_view val, bool transient) + { + if (!mp_current_elem) + return; + + m_current_chars = trim(val); + if (transient) + m_current_chars = m_pool.intern(m_current_chars).first; + } + + void attribute(std::string_view name, std::string_view val) + { + if (name == "encoding") + { + if (auto* gs = m_factory.get_global_settings(); gs) + { + character_set_t cs = to_character_set(val); + gs->set_character_set(cs); + } + } + } + + void attribute(const sax_ns_parser_attribute& at) + { + m_attrs.push_back(at); + } +}; + +/** + * Used in write_range_reference_group(). + */ +struct scope +{ + const xml_map_tree::element& element; + xml_map_tree::element_store_type::const_iterator current_child_pos; + xml_map_tree::element_store_type::const_iterator end_child_pos; + bool opened:1; + + scope(const scope&) = delete; + scope& operator=(const scope&) = delete; + + scope(const xml_map_tree::element& _elem) : + element(_elem), opened(false) + { + current_child_pos = end_child_pos; + + if (element.elem_type == xml_map_tree::element_type::unlinked) + { + current_child_pos = element.child_elements->begin(); + end_child_pos = element.child_elements->end(); + } + } +}; + +typedef std::vector<std::unique_ptr<scope>> scopes_type; + +void write_opening_element( + std::ostream& os, const xml_map_tree::element& elem, const xml_map_tree::range_reference& ref, + const spreadsheet::iface::export_sheet& sheet, spreadsheet::row_t current_row, bool self_close) +{ + if (elem.attributes.empty()) + { + // This element has no linked attributes. Just write the element name and be done with it. + os << '<' << elem << '>'; + return; + } + + // Element has one or more linked attributes. + + os << '<' << elem; + + for (const auto& p_attr : elem.attributes) + { + const xml_map_tree::attribute& attr = *p_attr; + if (attr.ref_type != xml_map_tree::reference_type::range_field) + // In theory this should never happen but it won't hurt to check. + continue; + + os << ' ' << attr << "=\""; + sheet.write_string(os, ref.pos.row + 1 + current_row, ref.pos.col + attr.field_ref->column_pos); + os << "\""; + } + + if (self_close) + os << '/'; + + os << '>'; +} + +void write_opening_element( + std::ostream& os, const xml_map_tree::element& elem, const spreadsheet::iface::export_factory& fact, bool self_close) +{ + os << '<' << elem; + for (const auto& p_attr : elem.attributes) + { + const xml_map_tree::attribute& attr = *p_attr; + if (attr.ref_type != xml_map_tree::reference_type::cell) + // We should only see single linked cell here, as all + // field links are handled by the range parent above. + continue; + + const xml_map_tree::cell_position& pos = attr.cell_ref->pos; + + const spreadsheet::iface::export_sheet* sheet = fact.get_sheet(pos.sheet); + if (!sheet) + continue; + + os << ' ' << attr << "=\""; + sheet->write_string(os, pos.row, pos.col); + os << "\""; + } + + if (self_close) + os << '/'; + + os << '>'; +} + +/** + * Write to the output stream a single range reference. + * + * @param os output stream. + * @param root root map tree element representing the root of a single range + * reference. + * @param ref range reference data. + * @param factory export factory instance. + */ +void write_range_reference_group( + std::ostream& os, const xml_map_tree::element& root, const xml_map_tree::range_reference& ref, + const spreadsheet::iface::export_factory& factory) +{ + const spreadsheet::iface::export_sheet* sheet = factory.get_sheet(ref.pos.sheet); + if (!sheet) + return; + + scopes_type scopes; + for (spreadsheet::row_t current_row = 0; current_row < ref.row_position; ++current_row) + { + scopes.push_back(std::make_unique<scope>(root)); // root element + + while (!scopes.empty()) + { + bool new_scope = false; + + scope& cur_scope = *scopes.back(); + + // Self-closing element has no child elements nor content. + bool self_close = + (cur_scope.current_child_pos == cur_scope.end_child_pos) && + (cur_scope.element.ref_type != xml_map_tree::reference_type::range_field); + + if (!cur_scope.opened) + { + // Write opening element of this scope only on the 1st entrance. + write_opening_element(os, cur_scope.element, ref, *sheet, current_row, self_close); + cur_scope.opened = true; + } + + if (self_close) + { + scopes.pop_back(); + continue; + } + + // Go though all child elements. + for (; cur_scope.current_child_pos != cur_scope.end_child_pos; ++cur_scope.current_child_pos) + { + const xml_map_tree::element& child_elem = **cur_scope.current_child_pos; + if (child_elem.elem_type == xml_map_tree::element_type::unlinked) + { + // This is a non-leaf element. Push a new scope with this + // element and re-start the loop. + ++cur_scope.current_child_pos; + scopes.push_back(std::make_unique<scope>(child_elem)); + new_scope = true; + break; + } + + // This is a leaf element. This must be a field link element. + if (child_elem.ref_type == xml_map_tree::reference_type::range_field) + { + write_opening_element(os, child_elem, ref, *sheet, current_row, false); + sheet->write_string(os, ref.pos.row + 1 + current_row, ref.pos.col + child_elem.field_ref->column_pos); + os << "</" << child_elem << ">"; + } + } + + if (new_scope) + // Re-start the loop with a new scope. + continue; + + // Write content of this element before closing it (if it's linked). + if (scopes.back()->element.ref_type == xml_map_tree::reference_type::range_field) + sheet->write_string( + os, ref.pos.row + 1 + current_row, ref.pos.col + scopes.back()->element.field_ref->column_pos); + + // Close this element for good, and exit the current scope. + os << "</" << scopes.back()->element << ">"; + scopes.pop_back(); + } + } +} + +/** + * Write to an output stream the sub-structure comprising one or more range + * references. + * + * @param os output stream + * @param elem_top topmost element in the range reference sub-structure. + */ +void write_range_reference(std::ostream& os, const xml_map_tree::element& elem_top, const spreadsheet::iface::export_factory& factory) +{ + // Top element is expected to have one or more child elements, and each + // child element represents a separate database range. + if (elem_top.elem_type != xml_map_tree::element_type::unlinked) + return; + + assert(elem_top.child_elements); + + if (elem_top.child_elements->empty()) + return; + + // TODO: For now, we assume that there is only one child element under the + // range ref parent. + write_range_reference_group( + os, **elem_top.child_elements->begin(), *elem_top.range_parent, factory); +} + +struct less_by_opening_elem_pos +{ + bool operator() (const xml_map_tree::element* left, const xml_map_tree::element* right) const + { + return left->stream_pos.open_begin < right->stream_pos.open_begin; + } +}; + +} // anonymous namespace + +orcus_xml::orcus_xml(xmlns_repository& ns_repo, spreadsheet::iface::import_factory* im_fact, spreadsheet::iface::export_factory* ex_fact) : + mp_impl(std::make_unique<impl>(ns_repo)) +{ + mp_impl->im_factory = im_fact; + mp_impl->ex_factory = ex_fact; +} + +orcus_xml::~orcus_xml() {} + +void orcus_xml::set_namespace_alias(std::string_view alias, std::string_view uri, bool default_ns) +{ + mp_impl->map_tree.set_namespace_alias(alias, uri, default_ns); +} + +void orcus_xml::set_cell_link(std::string_view xpath, std::string_view sheet, spreadsheet::row_t row, spreadsheet::col_t col) +{ + std::string_view sheet_safe = mp_impl->map_tree.intern_string(sheet); + mp_impl->map_tree.set_cell_link(xpath, xml_map_tree::cell_position(sheet_safe, row, col)); +} + +void orcus_xml::start_range(std::string_view sheet, spreadsheet::row_t row, spreadsheet::col_t col) +{ + std::string_view sheet_safe = mp_impl->map_tree.intern_string(sheet); + mp_impl->cur_range_ref = xml_map_tree::cell_position(sheet_safe, row, col); + mp_impl->map_tree.start_range(mp_impl->cur_range_ref); +} + +void orcus_xml::append_field_link(std::string_view xpath, std::string_view label) +{ + mp_impl->map_tree.append_range_field_link(xpath, label); +} + +void orcus_xml::set_range_row_group(std::string_view xpath) +{ + mp_impl->map_tree.set_range_row_group(xpath); +} + +void orcus_xml::commit_range() +{ + mp_impl->cur_range_ref = xml_map_tree::cell_position(); + mp_impl->map_tree.commit_range(); +} + +void orcus_xml::append_sheet(std::string_view name) +{ + if (name.empty()) + return; + + mp_impl->im_factory->append_sheet(mp_impl->sheet_count++, name); +} + +void orcus_xml::read_stream(std::string_view stream) +{ + if (stream.empty()) + return; + + // Insert the range headers and reset the row size counters. + xml_map_tree::range_ref_map_type& range_refs = mp_impl->map_tree.get_range_references(); + + for (const auto& ref_pair : range_refs) + { + const xml_map_tree::cell_position& ref = ref_pair.first; + xml_map_tree::range_reference& range_ref = *ref_pair.second; + range_ref.row_position = 1; // Reset the row offset. + + spreadsheet::iface::import_sheet* sheet = mp_impl->im_factory->get_sheet(ref.sheet); + + if (!sheet) + continue; + + spreadsheet::row_t row = ref.row; + spreadsheet::col_t col = ref.col; + + for (const xml_map_tree::linkable* e : range_ref.field_nodes) + { + if (e->label.empty()) + { + // No custom header label. Create a label from the name of the linkable. + std::string s = e->name.to_string(mp_impl->ns_repo); + if (!s.empty()) + sheet->set_auto(row, col, s); + } + else + sheet->set_auto(row, col, e->label); + + ++col; + } + } + + // Parse the content xml. + xmlns_context ns_cxt = mp_impl->ns_repo.create_context(); // new ns context for the content xml stream. + xml_data_sax_handler handler( + *mp_impl->im_factory, mp_impl->link_positions, mp_impl->map_tree); + + sax_ns_parser<xml_data_sax_handler> parser(stream, ns_cxt, handler); + parser.parse(); +} + +#if ORCUS_DEBUG_XML + +namespace { + +void dump_links(const xml_map_tree::const_element_list_type& links) +{ + cout << "link count: " << links.size() << endl; +} + +} + +#endif + +void orcus_xml::write(std::string_view stream, std::ostream& out) const +{ + if (!mp_impl->ex_factory) + // We can't export data witout export factory. + return; + + if (stream.empty()) + // Source input stream is empty. + return; + + xml_map_tree::const_element_list_type& links = mp_impl->link_positions; + if (links.empty()) + // nothing to write. + return; + + // Sort all link position by opening element positions. + std::sort(links.begin(), links.end(), less_by_opening_elem_pos()); + + spreadsheet::iface::export_factory& fact = *mp_impl->ex_factory; + xml_map_tree::const_element_list_type::const_iterator it = links.begin(), it_end = links.end(); + +#if ORCUS_DEBUG_XML + dump_links(links); +#endif + + const char* p0 = stream.data(); + std::ptrdiff_t begin_pos = 0; + + for (; it != it_end; ++it) + { + const xml_map_tree::element& elem = **it; + if (elem.ref_type == xml_map_tree::reference_type::cell) + { + // Single cell link + const xml_map_tree::cell_position& pos = elem.cell_ref->pos; + + const spreadsheet::iface::export_sheet* sheet = fact.get_sheet(pos.sheet); + if (!sheet) + continue; + + std::ptrdiff_t open_begin = elem.stream_pos.open_begin; + std::ptrdiff_t close_begin = elem.stream_pos.close_begin; + std::ptrdiff_t close_end = elem.stream_pos.close_end; + + assert(open_begin > begin_pos); + out << std::string_view(p0+begin_pos, open_begin-begin_pos); // stream since last linked element. + + write_opening_element(out, elem, fact, false); + sheet->write_string(out, pos.row, pos.col); + out << std::string_view(p0+close_begin, close_end-close_begin); // closing element. + begin_pos = close_end; + } + else if (elem.range_parent) + { + // Range link + const xml_map_tree::range_reference& ref = *elem.range_parent; + const xml_map_tree::cell_position& pos = ref.pos; + + const spreadsheet::iface::export_sheet* sheet = fact.get_sheet(pos.sheet); + if (!sheet) + continue; + + std::ptrdiff_t open_begin = elem.stream_pos.open_begin; + std::ptrdiff_t close_begin = elem.stream_pos.close_begin; + std::ptrdiff_t close_end = elem.stream_pos.close_end; + + assert(open_begin > begin_pos); + out << std::string_view(p0+begin_pos, open_begin-begin_pos); // stream since last linked element. + + write_opening_element(out, elem, fact, false); + write_range_reference(out, elem, fact); + out << std::string_view(p0+close_begin, close_end-close_begin); // closing element. + begin_pos = close_end; + } + else if (elem.unlinked_attribute_anchor()) + { + // Element is not linked but has one or more attributes that are + // linked. Here, only write the opening element with attributes. + + std::ptrdiff_t open_begin = elem.stream_pos.open_begin; + std::ptrdiff_t open_end = elem.stream_pos.open_end; + + bool self_close = elem.stream_pos.open_begin == elem.stream_pos.close_begin; + + assert(open_begin > begin_pos); + out << std::string_view(p0+begin_pos, open_begin-begin_pos); // stream since last linked element. + + write_opening_element(out, elem, fact, self_close); + begin_pos = open_end; + } + else + throw general_error("Non-link element type encountered."); + } + + // Flush the remaining stream. + out << std::string_view(p0+begin_pos, stream.size()-begin_pos); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/orcus_xml_impl.cpp b/src/liborcus/orcus_xml_impl.cpp new file mode 100644 index 0000000..4718f3c --- /dev/null +++ b/src/liborcus/orcus_xml_impl.cpp @@ -0,0 +1,22 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus_xml_impl.hpp" + +namespace orcus { + +orcus_xml::impl::impl(xmlns_repository& _ns_repo) : + im_factory(nullptr), + ex_factory(nullptr), + ns_repo(_ns_repo), + ns_cxt_map(ns_repo.create_context()), + map_tree(ns_repo), + sheet_count(0) {} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/orcus_xml_impl.hpp b/src/liborcus/orcus_xml_impl.hpp new file mode 100644 index 0000000..56c8156 --- /dev/null +++ b/src/liborcus/orcus_xml_impl.hpp @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_ORCUS_XML_IMPL_HPP +#define INCLUDED_ORCUS_ORCUS_XML_IMPL_HPP + +#include "orcus/orcus_xml.hpp" +#include "orcus/xml_namespace.hpp" + +#include "xml_map_tree.hpp" + +namespace orcus { + +struct orcus_xml::impl +{ + spreadsheet::iface::import_factory* im_factory; + spreadsheet::iface::export_factory* ex_factory; + + /** xml namespace repository for the whole session. */ + xmlns_repository& ns_repo; + + /** xml namespace context */ + xmlns_context ns_cxt_map; + + /** xml element tree that represents all mapped paths. */ + xml_map_tree map_tree; + + spreadsheet::sheet_t sheet_count; + + /** + * Positions of all linked elements, single and range reference alike. + * Stored link elements must be sorted in order of stream positions, and + * as such, no linked elements should be nested; there should never be a + * linked element inside the substructure of another linked element. + */ + xml_map_tree::const_element_list_type link_positions; + + xml_map_tree::cell_position cur_range_ref; + + explicit impl(xmlns_repository& _ns_repo); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/orcus_xml_map_def.cpp b/src/liborcus/orcus_xml_map_def.cpp new file mode 100644 index 0000000..5c484de --- /dev/null +++ b/src/liborcus/orcus_xml_map_def.cpp @@ -0,0 +1,299 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/orcus_xml.hpp" +#include "orcus/sax_parser_base.hpp" +#include "orcus/sax_parser.hpp" +#include "orcus/stream.hpp" +#include "orcus/xml_structure_tree.hpp" +#include "orcus/xml_namespace.hpp" +#include "orcus/xml_writer.hpp" +#include "orcus/measurement.hpp" + +#include "orcus_xml_impl.hpp" + +#include <vector> +#include <iostream> + +namespace orcus { + +namespace { + +class xml_map_sax_handler +{ + struct scope + { + std::string_view ns; + std::string_view name; + + scope(std::string_view _ns, std::string_view _name) : ns(_ns), name(_name) {} + }; + + std::vector<sax::parser_attribute> m_attrs; + std::vector<scope> m_scopes; + orcus_xml& m_app; + +public: + + xml_map_sax_handler(orcus_xml& app) : m_app(app) {} + + void doctype(const sax::doctype_declaration&) {} + void start_declaration(std::string_view /*name*/) {} + + void end_declaration(std::string_view /*name*/) + { + m_attrs.clear(); + } + + void start_element(const sax::parser_element& elem); + + void end_element(const sax::parser_element& elem) + { + if (elem.name == "range") + m_app.commit_range(); + + m_scopes.pop_back(); + } + + void attribute(const sax::parser_attribute& attr) + { + m_attrs.push_back(attr); + } + + void characters(std::string_view, bool) {} +}; + +void xml_map_sax_handler::start_element(const sax::parser_element& elem) +{ + std::string_view xpath, sheet, label; + spreadsheet::row_t row = -1; + spreadsheet::col_t col = -1; + + auto to_row = [](std::string_view s) -> spreadsheet::row_t + { + long v; + parse_integer(s.data(), s.data() + s.size(), v); + return v; + }; + + auto to_col = [](std::string_view s) -> spreadsheet::col_t + { + long v; + parse_integer(s.data(), s.data() + s.size(), v); + return v; + }; + + if (elem.name == "ns") + { + // empty alias is associated with default namespace. + std::string_view alias, uri; + bool default_ns = false; + + for (const sax::parser_attribute& attr : m_attrs) + { + if (attr.name == "alias") + alias = attr.value; + else if (attr.name == "uri") + uri = attr.value; + else if (attr.name == "default") + default_ns = to_bool(attr.value); + } + + if (!uri.empty()) + m_app.set_namespace_alias(alias, uri, default_ns); + } + else if (elem.name == "cell") + { + for (const sax::parser_attribute& attr : m_attrs) + { + if (attr.name == "path") + xpath = attr.value; + else if (attr.name == "sheet") + sheet = attr.value; + else if (attr.name == "row") + row = to_row(attr.value); + else if (attr.name == "column") + col = to_col(attr.value); + } + + m_app.set_cell_link(xpath, sheet, row, col); + } + else if (elem.name == "range") + { + for (const sax::parser_attribute& attr : m_attrs) + { + if (attr.name == "sheet") + sheet = attr.value; + else if (attr.name == "row") + row = to_row(attr.value); + else if (attr.name == "column") + col = to_col(attr.value); + } + + m_app.start_range(sheet, row, col); + } + else if (elem.name == "field") + { + for (const sax::parser_attribute& attr : m_attrs) + { + if (attr.name == "path") + xpath = attr.value; + else if (attr.name == "label") + label = attr.value; + } + + m_app.append_field_link(xpath, label); + } + else if (elem.name == "row-group") + { + for (const sax::parser_attribute& attr : m_attrs) + { + if (attr.name == "path") + { + xpath = attr.value; + break; + } + } + + m_app.set_range_row_group(xpath); + } + else if (elem.name == "sheet") + { + std::string_view sheet_name; + for (const sax::parser_attribute& attr : m_attrs) + { + if (attr.name == "name") + { + sheet_name = attr.value; + break; + } + } + + if (!sheet_name.empty()) + m_app.append_sheet(sheet_name); + } + + m_scopes.push_back(scope(elem.ns, elem.name)); + m_attrs.clear(); +} + +} // anonymous namespace + +void orcus_xml::read_map_definition(std::string_view stream) +{ + try + { + xml_map_sax_handler handler(*this); + sax_parser<xml_map_sax_handler> parser(stream, handler); + parser.parse(); + } + catch (const parse_error& e) + { + std::ostringstream os; + os << "Error parsing the map definition file:" << std::endl + << std::endl + << create_parse_error_output(stream, e.offset()) << std::endl + << e.what(); + + throw invalid_map_error(os.str()); + } +} + +void orcus_xml::detect_map_definition(std::string_view stream) +{ + size_t range_count = 0; + std::string sheet_name_prefix = "range-"; + + xml_structure_tree::range_handler_type rh = [&](xml_table_range_t&& range) + { + // Build sheet name first and insert a new sheet. + std::ostringstream os_sheet_name; + os_sheet_name << sheet_name_prefix << range_count; + std::string sheet_name = os_sheet_name.str(); + append_sheet(sheet_name); + + // Push the linked range. + start_range(sheet_name, 0, 0); + + for (const auto& path : range.paths) + append_field_link(path, std::string_view()); + + for (const auto& row_group : range.row_groups) + set_range_row_group(row_group); + + commit_range(); + + ++range_count; + }; + + xmlns_repository repo; + xmlns_context cxt = repo.create_context(); + xml_structure_tree structure(cxt); + structure.parse(stream); + + // Register all namespace aliases first. + for (const xmlns_id_t& ns : cxt.get_all_namespaces()) + set_namespace_alias(cxt.get_short_name(ns), std::string_view(ns)); + + structure.process_ranges(rh); +} + +void orcus_xml::write_map_definition(std::string_view stream, std::ostream& out) const +{ + xmlns_context cxt = mp_impl->ns_repo.create_context(); + xml_structure_tree tree(cxt); + tree.parse(stream); + + xml_writer writer(mp_impl->ns_repo, out); + xmlns_id_t default_ns = writer.add_namespace("", "https://gitlab.com/orcus/orcus/xml-map-definition"); + auto map_scope = writer.push_element_scope({default_ns, "map"}); + + for (const xmlns_id_t& ns : cxt.get_all_namespaces()) + { + writer.add_attribute({default_ns, "alias"}, cxt.get_short_name(ns)); + writer.add_attribute({default_ns, "uri"}, ns); + writer.push_element_scope({default_ns, "ns"}); + } + + size_t range_count = 0; + std::string sheet_name_prefix = "range-"; + + xml_structure_tree::range_handler_type rh = [&](xml_table_range_t&& range) + { + std::ostringstream os_sheet_name; + os_sheet_name << sheet_name_prefix << range_count; + std::string sheet_name = os_sheet_name.str(); + + writer.add_attribute({default_ns, "name"}, sheet_name); + writer.push_element_scope({default_ns, "sheet"}); + + writer.add_attribute({default_ns, "sheet"}, sheet_name); + writer.add_attribute({default_ns, "row"}, "0"); + writer.add_attribute({default_ns, "column"}, "0"); + auto range_scope = writer.push_element_scope({default_ns, "range"}); + + for (const auto& path : range.paths) + { + writer.add_attribute({default_ns, "path"}, path); + writer.push_element_scope({default_ns, "field"}); + } + + for (const auto& row_group : range.row_groups) + { + writer.add_attribute({default_ns, "path"}, row_group); + writer.push_element_scope({default_ns, "row-group"}); + } + + ++range_count; + }; + + tree.process_ranges(rh); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/session_context.cpp b/src/liborcus/session_context.cpp new file mode 100644 index 0000000..b054106 --- /dev/null +++ b/src/liborcus/session_context.cpp @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "session_context.hpp" + +namespace orcus { + +session_context::custom_data::~custom_data() {} + +session_context::session_context(std::unique_ptr<custom_data> data) : cdata(std::move(data)) {} + +std::string_view session_context::intern(const xml_token_attr_t& attr) +{ + // NB: always intern regardless of the transient flag since the string may + // be used in another stream. + return spool.intern(attr.value).first; +} + +std::string_view session_context::intern(std::string_view s) +{ + return spool.intern(s).first; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/session_context.hpp b/src/liborcus/session_context.hpp new file mode 100644 index 0000000..ab50836 --- /dev/null +++ b/src/liborcus/session_context.hpp @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_SESSION_CONTEXT_HPP +#define INCLUDED_ORCUS_SESSION_CONTEXT_HPP + +#include <orcus/string_pool.hpp> +#include <orcus/types.hpp> + +#include <memory> + +namespace orcus { + +struct session_context +{ + session_context(const session_context&) = delete; + session_context& operator=(const session_context&) = delete; + + string_pool spool; + + /** + * Derive from this class in case the filter needs to store its own + * session data. + */ + struct custom_data + { + virtual ~custom_data() = 0; + }; + + std::unique_ptr<custom_data> cdata; + + session_context() = default; + session_context(std::unique_ptr<custom_data> data); + + template<typename CDataT> + CDataT& get_data() + { + return static_cast<CDataT&>(*cdata); + } + + template<typename CDataT> + const CDataT& get_data() const + { + return static_cast<const CDataT&>(*cdata); + } + + std::string_view intern(const xml_token_attr_t& attr); + std::string_view intern(std::string_view s); +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/spreadsheet_iface_util.cpp b/src/liborcus/spreadsheet_iface_util.cpp new file mode 100644 index 0000000..740864c --- /dev/null +++ b/src/liborcus/spreadsheet_iface_util.cpp @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "spreadsheet_iface_util.hpp" +#include "formula_result.hpp" + +#include "orcus/spreadsheet/import_interface.hpp" + +namespace orcus { + +void push_array_formula( + spreadsheet::iface::import_array_formula* xformula, + const spreadsheet::range_t& range, std::string_view formula, + spreadsheet::formula_grammar_t grammar, const range_formula_results& results) +{ + xformula->set_range(range); + xformula->set_formula(grammar, formula); + + for (size_t row = 0; row < results.row_size(); ++row) + { + for (size_t col = 0; col < results.col_size(); ++col) + { + const formula_result& v = results.get(row, col); + switch (v.type) + { + case formula_result::result_type::numeric: + xformula->set_result_value(row, col, v.value_numeric); + break; + case formula_result::result_type::string: + xformula->set_result_string(row, col, {v.value_string.p, v.value_string.n}); + break; + case formula_result::result_type::boolean: + xformula->set_result_bool(row, col, v.value_boolean); + break; + case formula_result::result_type::empty: + xformula->set_result_empty(row, col); + break; + default: + ; + } + } + } + + xformula->commit(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/spreadsheet_iface_util.hpp b/src/liborcus/spreadsheet_iface_util.hpp new file mode 100644 index 0000000..1262be6 --- /dev/null +++ b/src/liborcus/spreadsheet_iface_util.hpp @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_SPREADSHEET_IFACE_UTIL_HPP +#define INCLUDED_ORCUS_SPREADSHEET_IFACE_UTIL_HPP + +#include "orcus/spreadsheet/types.hpp" + +namespace orcus { + +class range_formula_results; + +namespace spreadsheet { + +namespace iface { + +class import_array_formula; + +} + +} + +void push_array_formula( + spreadsheet::iface::import_array_formula* xformula, + const spreadsheet::range_t& range, std::string_view formula, + spreadsheet::formula_grammar_t grammar, const range_formula_results& results); + +} // namespace orcus + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/spreadsheet_impl_types.cpp b/src/liborcus/spreadsheet_impl_types.cpp new file mode 100644 index 0000000..735f546 --- /dev/null +++ b/src/liborcus/spreadsheet_impl_types.cpp @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "spreadsheet_impl_types.hpp" + +#include <ostream> + +namespace orcus { namespace spreadsheet { namespace detail { + +cell_position_t::cell_position_t() : row(-1), col(-1) {} + +cell_position_t::cell_position_t(std::string_view _sheet, spreadsheet::row_t _row, spreadsheet::col_t _col) : + sheet(_sheet), row(_row), col(_col) {} + +cell_position_t::cell_position_t(const cell_position_t& r) : sheet(r.sheet), row(r.row), col(r.col) {} + +bool cell_position_t::operator== (const cell_position_t& other) const +{ + return sheet == other.sheet && row == other.row && col == other.col; +} + +bool cell_position_t::operator!= (const cell_position_t& other) const +{ + return !operator==(other); +} + +std::ostream& operator<< (std::ostream& os, const cell_position_t& ref) +{ + os << "[sheet='" << ref.sheet << "' row=" << ref.row << " column=" << ref.col << "]"; + return os; +} + +bool operator< (const cell_position_t& left, const cell_position_t& right) +{ + if (left.sheet != right.sheet) + return left.sheet < right.sheet; + + if (left.row != right.row) + return left.row < right.row; + + return left.col < right.col; +} + +}}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/spreadsheet_impl_types.hpp b/src/liborcus/spreadsheet_impl_types.hpp new file mode 100644 index 0000000..0c2c110 --- /dev/null +++ b/src/liborcus/spreadsheet_impl_types.hpp @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_SPREADSHEET_IMPL_TYPES_HPP +#define INCLUDED_ORCUS_SPREADSHEET_IMPL_TYPES_HPP + +#include "orcus/spreadsheet/types.hpp" + +#include <iosfwd> + +namespace orcus { namespace spreadsheet { namespace detail { + +struct cell_position_t +{ + std::string_view sheet; + spreadsheet::row_t row; + spreadsheet::col_t col; + + cell_position_t(); + cell_position_t(std::string_view _sheet, spreadsheet::row_t _row, spreadsheet::col_t _col); + cell_position_t(const cell_position_t& r); + + bool operator== (const cell_position_t& other) const; + bool operator!= (const cell_position_t& other) const; +}; + +std::ostream& operator<< (std::ostream& os, const cell_position_t& ref); + +bool operator< (const cell_position_t& left, const cell_position_t& right); + +}}} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/spreadsheet_interface.cpp b/src/liborcus/spreadsheet_interface.cpp new file mode 100644 index 0000000..0accf63 --- /dev/null +++ b/src/liborcus/spreadsheet_interface.cpp @@ -0,0 +1,159 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/spreadsheet/import_interface.hpp> +#include <orcus/spreadsheet/import_interface_styles.hpp> +#include <orcus/spreadsheet/import_interface_pivot.hpp> +#include <orcus/spreadsheet/import_interface_view.hpp> +#include <orcus/spreadsheet/export_interface.hpp> + +namespace orcus { namespace spreadsheet { namespace iface { + +import_sheet_view::~import_sheet_view() {} + +import_pivot_cache_definition::~import_pivot_cache_definition() {} + +import_pivot_cache_field_group::~import_pivot_cache_field_group() {} + +import_pivot_cache_records::~import_pivot_cache_records() {} + +import_shared_strings::~import_shared_strings() {} + +import_styles::~import_styles() {} + +import_font_style::~import_font_style() {} + +import_fill_style::~import_fill_style() {} + +import_border_style::~import_border_style() {} + +import_cell_protection::~import_cell_protection() {} + +import_number_format::~import_number_format() {} + +import_xf::~import_xf() {} + +import_cell_style::~import_cell_style() {} + +import_sheet_properties::~import_sheet_properties() {} + +import_named_expression::~import_named_expression() {} + +import_data_table::~import_data_table() {} + +import_auto_filter::~import_auto_filter() {} + +import_table::~import_table() {} + +import_conditional_format::~import_conditional_format() {} + +import_auto_filter* import_table::get_auto_filter() +{ + return nullptr; +} + +import_formula::~import_formula() {} + +import_array_formula::~import_array_formula() {} + +import_sheet::~import_sheet() {} + +import_sheet_view* import_sheet::get_sheet_view() +{ + return nullptr; +} + +import_sheet_properties* import_sheet::get_sheet_properties() +{ + return nullptr; +} + +import_data_table* import_sheet::get_data_table() +{ + return nullptr; +} + +import_auto_filter* import_sheet::get_auto_filter() +{ + return nullptr; +} + +import_table* import_sheet::get_table() +{ + return nullptr; +} + +import_conditional_format* import_sheet::get_conditional_format() +{ + return nullptr; +} + +import_named_expression* import_sheet::get_named_expression() +{ + return nullptr; +} + +import_array_formula* import_sheet::get_array_formula() +{ + return nullptr; +} + +import_formula* import_sheet::get_formula() +{ + return nullptr; +} + +import_global_settings::~import_global_settings() {} + +import_reference_resolver::~import_reference_resolver() {} + +import_factory::~import_factory() {} + +import_global_settings* import_factory::get_global_settings() +{ + return nullptr; +} + +import_shared_strings* import_factory::get_shared_strings() +{ + return nullptr; +} + +import_named_expression* import_factory::get_named_expression() +{ + return nullptr; +} + +import_styles* import_factory::get_styles() +{ + return nullptr; +} + +import_reference_resolver* import_factory::get_reference_resolver(formula_ref_context_t /*cxt*/) +{ + return nullptr; +} + +import_pivot_cache_definition* import_factory::create_pivot_cache_definition( + orcus::spreadsheet::pivot_cache_id_t /*cache_id*/) +{ + return nullptr; +} + +import_pivot_cache_records* import_factory::create_pivot_cache_records( + orcus::spreadsheet::pivot_cache_id_t /*cache_id*/) +{ + return nullptr; +} + +export_sheet::~export_sheet() {} + +export_factory::~export_factory() {} + +}}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/spreadsheet_types.cpp b/src/liborcus/spreadsheet_types.cpp new file mode 100644 index 0000000..3b7d357 --- /dev/null +++ b/src/liborcus/spreadsheet_types.cpp @@ -0,0 +1,763 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/spreadsheet/types.hpp> +#include <orcus/exception.hpp> + +#include <limits> +#include <sstream> + +#include <mdds/sorted_string_map.hpp> + +namespace orcus { namespace spreadsheet { + +namespace { + +namespace trf { + +using map_type = mdds::sorted_string_map<totals_row_function_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "average", totals_row_function_t::average }, + { "count", totals_row_function_t::count }, + { "countNums", totals_row_function_t::count_numbers }, + { "custom", totals_row_function_t::custom }, + { "max", totals_row_function_t::maximum }, + { "min", totals_row_function_t::minimum }, + { "none", totals_row_function_t::none }, + { "stdDev", totals_row_function_t::standard_deviation }, + { "sum", totals_row_function_t::sum }, + { "var", totals_row_function_t::variance }, +}; + +const map_type& get() +{ + static const map_type map(entries, std::size(entries), totals_row_function_t::none); + return map; +} + +} // namespace trf + +namespace pc_group_by { + +using map_type = mdds::sorted_string_map<pivot_cache_group_by_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "days", pivot_cache_group_by_t::days }, + { "hours", pivot_cache_group_by_t::hours }, + { "minutes", pivot_cache_group_by_t::minutes }, + { "months", pivot_cache_group_by_t::months }, + { "quarters", pivot_cache_group_by_t::quarters }, + { "range", pivot_cache_group_by_t::range }, + { "seconds", pivot_cache_group_by_t::seconds }, + { "years", pivot_cache_group_by_t::years }, +}; + +const map_type& get() +{ + static const map_type map(entries, std::size(entries), pivot_cache_group_by_t::unknown); + return map; +} + +} // namespace pc_group_by + +namespace error_value { + +using map_type = mdds::sorted_string_map<error_value_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = +{ + { "#DIV/0!", error_value_t::div0 }, + { "#N/A!", error_value_t::na }, + { "#NAME?", error_value_t::name }, + { "#NULL!", error_value_t::null }, + { "#NUM!", error_value_t::num }, + { "#REF!", error_value_t::ref }, + { "#VALUE!", error_value_t::value }, +}; + +const map_type& get() +{ + static const map_type map(entries, std::size(entries), error_value_t::unknown); + return map; +} + +} // namespace error_value + +namespace named_colors { + +using map_type = mdds::sorted_string_map<color_rgb_t, mdds::string_view_map_entry>; + +constexpr map_type::entry entries[] = +{ + { "aliceblue", { 0xF0, 0xF8, 0xFF } }, + { "antiquewhite", { 0xFA, 0xEB, 0xD7 } }, + { "aquamarine", { 0x7F, 0xFF, 0xD4 } }, + { "azure", { 0xF0, 0xFF, 0xFF } }, + { "beige", { 0xF5, 0xF5, 0xDC } }, + { "bisque", { 0xFF, 0xE4, 0xC4 } }, + { "black", { 0x00, 0x00, 0x00 } }, + { "blanchedalmond", { 0xFF, 0xEB, 0xCD } }, + { "blue", { 0x00, 0x00, 0xFF } }, + { "blueviolet", { 0x8A, 0x2B, 0xE2 } }, + { "brown", { 0xA5, 0x2A, 0x2A } }, + { "burlywood", { 0xDE, 0xB8, 0x87 } }, + { "cadetblue", { 0x5F, 0x9E, 0xA0 } }, + { "chartreuse", { 0x7F, 0xFF, 0x00 } }, + { "chocolate", { 0xD2, 0x69, 0x1E } }, + { "coral", { 0xFF, 0x7F, 0x50 } }, + { "cornflowerblue", { 0x64, 0x95, 0xED } }, + { "cornsilk", { 0xFF, 0xF8, 0xDC } }, + { "crimson", { 0xDC, 0x14, 0x3C } }, + { "cyan", { 0x00, 0xFF, 0xFF } }, + { "darkblue", { 0x00, 0x00, 0x8B } }, + { "darkcyan", { 0x00, 0x8B, 0x8B } }, + { "darkgoldenrod", { 0xB8, 0x86, 0x0B } }, + { "darkgray", { 0xA9, 0xA9, 0xA9 } }, + { "darkgreen", { 0x00, 0x64, 0x00 } }, + { "darkkhaki", { 0xBD, 0xB7, 0x6B } }, + { "darkmagenta", { 0x8B, 0x00, 0x8B } }, + { "darkolivegreen", { 0x55, 0x6B, 0x2F } }, + { "darkorange", { 0xFF, 0x8C, 0x00 } }, + { "darkorchid", { 0x99, 0x32, 0xCC } }, + { "darkred", { 0x8B, 0x00, 0x00 } }, + { "darksalmon", { 0xE9, 0x96, 0x7A } }, + { "darkseagreen", { 0x8F, 0xBC, 0x8F } }, + { "darkslateblue", { 0x48, 0x3D, 0x8B } }, + { "darkslategray", { 0x2F, 0x4F, 0x4F } }, + { "darkturquoise", { 0x00, 0xCE, 0xD1 } }, + { "darkviolet", { 0x94, 0x00, 0xD3 } }, + { "deeppink", { 0xFF, 0x14, 0x93 } }, + { "deepskyblue", { 0x00, 0xBF, 0xFF } }, + { "dimgray", { 0x69, 0x69, 0x69 } }, + { "dodgerblue", { 0x1E, 0x90, 0xFF } }, + { "firebrick", { 0xB2, 0x22, 0x22 } }, + { "floralwhite", { 0xFF, 0xFA, 0xF0 } }, + { "forestgreen", { 0x22, 0x8B, 0x22 } }, + { "gainsboro", { 0xDC, 0xDC, 0xDC } }, + { "ghostwhite", { 0xF8, 0xF8, 0xFF } }, + { "gold", { 0xFF, 0xD7, 0x00 } }, + { "goldenrod", { 0xDA, 0xA5, 0x20 } }, + { "gray", { 0x80, 0x80, 0x80 } }, + { "green", { 0x00, 0x80, 0x00 } }, + { "greenyellow", { 0xAD, 0xFF, 0x2F } }, + { "honeydew", { 0xF0, 0xFF, 0xF0 } }, + { "hotpink", { 0xFF, 0x69, 0xB4 } }, + { "indianred", { 0xCD, 0x5C, 0x5C } }, + { "indigo", { 0x4B, 0x00, 0x82 } }, + { "ivory", { 0xFF, 0xFF, 0xF0 } }, + { "khaki", { 0xF0, 0xE6, 0x8C } }, + { "lavender", { 0xE6, 0xE6, 0xFA } }, + { "lavenderblush", { 0xFF, 0xF0, 0xF5 } }, + { "lawngreen", { 0x7C, 0xFC, 0x00 } }, + { "lemonchiffon", { 0xFF, 0xFA, 0xCD } }, + { "lightblue", { 0xAD, 0xD8, 0xE6 } }, + { "lightcoral", { 0xF0, 0x80, 0x80 } }, + { "lightcyan", { 0xE0, 0xFF, 0xFF } }, + { "lightgoldenrodyellow", { 0xFA, 0xFA, 0xD2 } }, + { "lightgray", { 0xD3, 0xD3, 0xD3 } }, + { "lightgreen", { 0x90, 0xEE, 0x90 } }, + { "lightpink", { 0xFF, 0xB6, 0xC1 } }, + { "lightsalmon", { 0xFF, 0xA0, 0x7A } }, + { "lightseagreen", { 0x20, 0xB2, 0xAA } }, + { "lightskyblue", { 0x87, 0xCE, 0xFA } }, + { "lightslategray", { 0x77, 0x88, 0x99 } }, + { "lightsteelblue", { 0xB0, 0xC4, 0xDE } }, + { "lightyellow", { 0xFF, 0xFF, 0xE0 } }, + { "lime", { 0x00, 0xFF, 0x00 } }, + { "limegreen", { 0x32, 0xCD, 0x32 } }, + { "linen", { 0xFA, 0xF0, 0xE6 } }, + { "magenta", { 0xFF, 0x00, 0xFF } }, + { "maroon", { 0x80, 0x00, 0x00 } }, + { "mediumaquamarine", { 0x66, 0xCD, 0xAA } }, + { "mediumblue", { 0x00, 0x00, 0xCD } }, + { "mediumorchid", { 0xBA, 0x55, 0xD3 } }, + { "mediumpurple", { 0x93, 0x70, 0xDB } }, + { "mediumseagreen", { 0x3C, 0xB3, 0x71 } }, + { "mediumslateblue", { 0x7B, 0x68, 0xEE } }, + { "mediumspringgreen", { 0x00, 0xFA, 0x9A } }, + { "mediumturquoise", { 0x48, 0xD1, 0xCC } }, + { "mediumvioletred", { 0xC7, 0x15, 0x85 } }, + { "midnightblue", { 0x19, 0x19, 0x70 } }, + { "mintcream", { 0xF5, 0xFF, 0xFA } }, + { "mistyrose", { 0xFF, 0xE4, 0xE1 } }, + { "moccasin", { 0xFF, 0xE4, 0xB5 } }, + { "navajowhite", { 0xFF, 0xDE, 0xAD } }, + { "navy", { 0x00, 0x00, 0x80 } }, + { "oldlace", { 0xFD, 0xF5, 0xE6 } }, + { "olive", { 0x80, 0x80, 0x00 } }, + { "olivedrab", { 0x6B, 0x8E, 0x23 } }, + { "orange", { 0xFF, 0xA5, 0x00 } }, + { "orangered", { 0xFF, 0x45, 0x00 } }, + { "orchid", { 0xDA, 0x70, 0xD6 } }, + { "palegoldenrod", { 0xEE, 0xE8, 0xAA } }, + { "palegreen", { 0x98, 0xFB, 0x98 } }, + { "paleturquoise", { 0xAF, 0xEE, 0xEE } }, + { "palevioletred", { 0xDB, 0x70, 0x93 } }, + { "papayawhip", { 0xFF, 0xEF, 0xD5 } }, + { "peachpuff", { 0xFF, 0xDA, 0xB9 } }, + { "peru", { 0xCD, 0x85, 0x3F } }, + { "pink", { 0xFF, 0xC0, 0xCB } }, + { "plum", { 0xDD, 0xA0, 0xDD } }, + { "powderblue", { 0xB0, 0xE0, 0xE6 } }, + { "purple", { 0x80, 0x00, 0x80 } }, + { "red", { 0xFF, 0x00, 0x00 } }, + { "rosybrown", { 0xBC, 0x8F, 0x8F } }, + { "royalblue", { 0x41, 0x69, 0xE1 } }, + { "saddlebrown", { 0x8B, 0x45, 0x13 } }, + { "salmon", { 0xFA, 0x80, 0x72 } }, + { "sandybrown", { 0xF4, 0xA4, 0x60 } }, + { "seagreen", { 0x2E, 0x8B, 0x57 } }, + { "seashell", { 0xFF, 0xF5, 0xEE } }, + { "sienna", { 0xA0, 0x52, 0x2D } }, + { "silver", { 0xC0, 0xC0, 0xC0 } }, + { "skyblue", { 0x87, 0xCE, 0xEB } }, + { "slateblue", { 0x6A, 0x5A, 0xCD } }, + { "slategray", { 0x70, 0x80, 0x90 } }, + { "snow", { 0xFF, 0xFA, 0xFA } }, + { "springgreen", { 0x00, 0xFF, 0x7F } }, + { "steelblue", { 0x46, 0x82, 0xB4 } }, + { "tan", { 0xD2, 0xB4, 0x8C } }, + { "teal", { 0x00, 0x80, 0x80 } }, + { "thistle", { 0xD8, 0xBF, 0xD8 } }, + { "tomato", { 0xFF, 0x63, 0x47 } }, + { "turquoise", { 0x40, 0xE0, 0xD0 } }, + { "violet", { 0xEE, 0x82, 0xEE } }, + { "wheat", { 0xF5, 0xDE, 0xB3 } }, + { "white", { 0xFF, 0xFF, 0xFF } }, + { "whitesmoke", { 0xF5, 0xF5, 0xF5 } }, + { "yellow", { 0xFF, 0xFF, 0x00 } }, + { "yellowgreen", { 0x9A, 0xCD, 0x32 } }, +}; + +const map_type& get() +{ + static map_type mt(entries, std::size(entries), { 0x00, 0x00, 0x00 }); + return mt; +} + +} // namespace named_color + +namespace formula_error_policy { + +using map_type = mdds::sorted_string_map<formula_error_policy_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "fail", formula_error_policy_t::fail }, + { "skip", formula_error_policy_t::skip }, +}; + +const map_type& get() +{ + static map_type mt(entries, std::size(entries), formula_error_policy_t::unknown); + return mt; +} + +} + +class to_size_t +{ + std::size_t m_value; + +public: + template<typename T> + to_size_t(T v) : m_value(static_cast<std::size_t>(v)) + { + static_assert(std::is_enum_v<T>, "source value type must be enum!"); + } + + operator std::size_t() const + { + return m_value; + } +}; + +std::ostream& write_name_for_pos( + std::ostream& os, const std::string_view* names, std::size_t n_names, to_size_t pos) +{ + if (pos < n_names) + os << names[pos]; + else + os << "???"; + + return os; +} + +} // anonymous namespace + +address_t to_rc_address(const src_address_t& r) +{ + address_t ret; + ret.row = r.row; + ret.column = r.column; + return ret; +} + +range_t to_rc_range(const src_range_t& r) +{ + range_t ret; + ret.first.row = r.first.row; + ret.first.column = r.first.column; + ret.last.row = r.last.row; + ret.last.column = r.last.column; + return ret; +} + +bool operator== (const address_t& left, const address_t& right) +{ + return left.column == right.column && left.row == right.row; +} + +bool operator!= (const address_t& left, const address_t& right) +{ + return !operator== (left, right); +} + +bool operator== (const src_address_t& left, const src_address_t& right) +{ + return left.column == right.column && left.row == right.row; +} + +bool operator!= (const src_address_t& left, const src_address_t& right) +{ + return !operator== (left, right); +} + +bool operator== (const range_t& left, const range_t& right) +{ + return left.first == right.first && left.last == right.last; +} + +bool operator!= (const range_t& left, const range_t& right) +{ + return !operator== (left, right); +} + +bool operator== (const src_range_t& left, const src_range_t& right) +{ + return left.first == right.first && left.last == right.last; +} + +bool operator!= (const src_range_t& left, const src_range_t& right) +{ + return !operator== (left, right); +} + +bool operator< (const range_t& left, const range_t& right) +{ + if (left.first.row != right.first.row) + return left.first.row < right.first.row; + + if (left.first.column != right.first.column) + return left.first.column < right.first.column; + + if (left.last.row != right.last.row) + return left.last.row < right.last.row; + + return left.last.column < right.last.column; +} + +bool operator> (const range_t& left, const range_t& right) +{ + if (left.first.row != right.first.row) + return left.first.row > right.first.row; + + if (left.first.column != right.first.column) + return left.first.column > right.first.column; + + if (left.last.row != right.last.row) + return left.last.row > right.last.row; + + return left.last.column > right.last.column; +} + +range_t& operator+= (range_t& left, const address_t& right) +{ + left.first.column += right.column; + left.first.row += right.row; + left.last.column += right.column; + left.last.row += right.row; + + return left; +} + +range_t& operator-= (range_t& left, const address_t& right) +{ + left.first.column -= right.column; + left.first.row -= right.row; + left.last.column -= right.column; + left.last.row -= right.row; + + return left; +} + +std::ostream& operator<< (std::ostream& os, const address_t& v) +{ + os << "(column=" << v.column << ",row=" << v.row << ")"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const src_address_t& v) +{ + os << "(sheet=" << v.sheet << ",column=" << v.column << ",row=" << v.row << ")"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const range_t& v) +{ + os << v.first << "-" << v.last; + return os; +} + +col_width_t get_default_column_width() +{ + return std::numeric_limits<col_width_t>::max(); +} + +row_height_t get_default_row_height() +{ + return std::numeric_limits<row_height_t>::max(); +} + +totals_row_function_t to_totals_row_function_enum(std::string_view s) +{ + return trf::get().find(s); +} + +pivot_cache_group_by_t to_pivot_cache_group_by_enum(std::string_view s) +{ + return pc_group_by::get().find(s); +} + +error_value_t to_error_value_enum(std::string_view s) +{ + return error_value::get().find(s); +} + +color_rgb_t to_color_rgb(std::string_view s) +{ + const char* p = s.data(); + std::size_t n = s.size(); + + // RGB string is a 6-character string representing 24-bit hexadecimal + // number e.g. '004A12' (red - green - blue) + + // store the original head position and size. + const char* p0 = p; + size_t n0 = n; + + if (n == 7 && *p == '#') + { + // Skip the leading '#' character. + --n; + ++p; + } + + if (n != 6) + { + std::ostringstream os; + os << "'" << std::string_view(p0, n0) << "' is not a valid RGB color string."; + throw value_error(os.str()); + } + + color_rgb_t ret; + long converted = 0; + const char* p_end = p + n; + + for (; p != p_end; ++p) + { + converted <<= 4; + + char c = *p; + long this_val = 0; + + if ('0' <= c && c <= '9') + this_val = c - '0'; + else if ('a' <= c && c <= 'f') + this_val = 10 + c - 'a'; + else if ('A' <= c && c <= 'F') + this_val = 10 + c - 'A'; + else + { + std::ostringstream os; + os << "'" << std::string_view(p0, n0) << "' is not a valid RGB color string."; + throw value_error(os.str()); + } + + converted += this_val; + } + + ret.blue = (0x000000FF & converted); + converted >>= 8; + ret.green = (0x000000FF & converted); + converted >>= 8; + ret.red = (0x000000FF & converted); + + return ret; +} + +color_rgb_t to_color_rgb_from_name(std::string_view s) +{ + return named_colors::get().find(s); +} + +formula_error_policy_t to_formula_error_policy(std::string_view s) +{ + return formula_error_policy::get().find(s); +} + +std::ostream& operator<< (std::ostream& os, error_value_t ev) +{ + switch (ev) + { + case error_value_t::div0: + os << error_value::entries[0].key; + break; + case error_value_t::na: + os << error_value::entries[1].key; + break; + case error_value_t::name: + os << error_value::entries[2].key; + break; + case error_value_t::null: + os << error_value::entries[3].key; + break; + case error_value_t::num: + os << error_value::entries[4].key; + break; + case error_value_t::ref: + os << error_value::entries[5].key; + break; + case error_value_t::value: + os << error_value::entries[6].key; + break; + case error_value_t::unknown: + default: + ; + } + return os; +} + +std::ostream& operator<< (std::ostream& os, border_style_t border) +{ + static constexpr std::string_view names[] = { + "unknown", + "none", + "solid", + "dash_dot", + "dash_dot_dot", + "dashed", + "dotted", + "double_border", + "hair", + "medium", + "medium_dash_dot", + "medium_dash_dot_dot", + "medium_dashed", + "slant_dash_dot", + "thick", + "thin", + "double_thin", + "fine_dashed", + }; + + return write_name_for_pos(os, names, std::size(names), border); +} + +std::ostream& operator<< (std::ostream& os, formula_grammar_t grammar) +{ + static constexpr std::string_view names[] = { + "unknown", + "xls_xml", + "xlsx", + "ods", + "gnumeric" + }; + + return write_name_for_pos(os, names, std::size(names), grammar); +} + +std::ostream& operator<< (std::ostream& os, underline_t uline) +{ + static constexpr std::string_view names[] = { + "none", + "single_line", + "single_accounting", + "double_line", + "double_accounting", + "dotted", + "dash", + "long_dash", + "dot_dash", + "dot_dot_dash", + "wave", + }; + + return write_name_for_pos(os, names, std::size(names), uline); +} + +std::ostream& operator<< (std::ostream& os, underline_width_t ulwidth) +{ + static constexpr std::string_view names[] = { + "none", + "automatic", + "bold", + "dash", + "medium", + "thick", + "thin", + "percent", + "positive_integer", + "positive_length", + }; + + return write_name_for_pos(os, names, std::size(names), ulwidth); +} + +std::ostream& operator<< (std::ostream& os, underline_mode_t ulmode) +{ + static constexpr std::string_view names[] = { + "continuous", + "skip_white_space", + }; + + return write_name_for_pos(os, names, std::size(names), ulmode); +} + +std::ostream& operator<< (std::ostream& os, underline_type_t ultype) +{ + static constexpr std::string_view names[] = { + "none", + "single_type", + "double_type", + }; + + return write_name_for_pos(os, names, std::size(names), ultype); +} + +std::ostream& operator<< (std::ostream& os, hor_alignment_t halign) +{ + static constexpr std::string_view names[] = { + "unknown", + "left", + "center", + "right", + "justified", + "distributed", + "filled", + }; + + return write_name_for_pos(os, names, std::size(names), halign); +} + +std::ostream& operator<< (std::ostream& os, ver_alignment_t valign) +{ + static constexpr std::string_view names[] = { + "unknown", + "top", + "middle", + "bottom", + "justified", + "distributed", + }; + + return write_name_for_pos(os, names, std::size(names), valign); +} + +std::ostream& operator<< (std::ostream& os, const color_rgb_t& color) +{ + os << "(r=" << (int)color.red << ",g=" << (int)color.green << ",b=" << (int)color.blue << ")"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const fill_pattern_t& fill) +{ + static constexpr std::string_view names[] = { + "none", + "solid", + "dark_down", + "dark_gray", + "dark_grid", + "dark_horizontal", + "dark_trellis", + "dark_up", + "dark_vertical", + "gray_0625", + "gray_125", + "light_down", + "light_gray", + "light_grid", + "light_horizontal", + "light_trellis", + "light_up", + "light_vertical", + "medium_gray", + }; + + return write_name_for_pos(os, names, std::size(names), fill); +} + +std::ostream& operator<< (std::ostream& os, const strikethrough_style_t& ss) +{ + static constexpr std::string_view names[] = { + "none", + "solid", + "dash", + "dot_dash", + "dot_dot_dash", + "dotted", + "long_dash", + "wave", + }; + + return write_name_for_pos(os, names, std::size(names), ss); +} + +std::ostream& operator<< (std::ostream& os, const strikethrough_type_t& st) +{ + static constexpr std::string_view names[] = { + "unknown", + "none", + "single_type", + "double_type", + }; + + return write_name_for_pos(os, names, std::size(names), st); +} + +std::ostream& operator<< (std::ostream& os, const strikethrough_width_t& sw) +{ + static constexpr std::string_view names[] = { + "unknown", + "width_auto", + "thin", + "medium", + "thick", + "bold", + }; + + return write_name_for_pos(os, names, std::size(names), sw); +} + +std::ostream& operator<< (std::ostream& os, const strikethrough_text_t& st) +{ + static constexpr std::string_view names[] = { + "unknown", + "slash", + "cross", + }; + + return write_name_for_pos(os, names, std::size(names), st); +} + +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/string_helper.cpp b/src/liborcus/string_helper.cpp new file mode 100644 index 0000000..3bf9c63 --- /dev/null +++ b/src/liborcus/string_helper.cpp @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "string_helper.hpp" + +namespace orcus { + +std::vector<std::string_view> string_helper::split_string(std::string_view str, const char sep) +{ + std::vector<std::string_view> ret; + + std::size_t len = 0; + const char* start = str.data(); + for (size_t i = 0, n = str.size(); i < n; ++i) + { + if (str[i] == sep) + { + ret.emplace_back(start, len); + + // if not at the end move the start string + if (i < n-1) + start = start + len + 1; + + len = 0; + } + else + ++len; + } + ret.emplace_back(start, len); + + return ret; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/string_helper.hpp b/src/liborcus/string_helper.hpp new file mode 100644 index 0000000..1885a33 --- /dev/null +++ b/src/liborcus/string_helper.hpp @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <vector> +#include <string_view> + +namespace orcus { + +class string_helper +{ +public: + static std::vector<std::string_view> split_string(std::string_view str, const char sep); +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xls_xml_context.cpp b/src/liborcus/xls_xml_context.cpp new file mode 100644 index 0000000..ed30616 --- /dev/null +++ b/src/liborcus/xls_xml_context.cpp @@ -0,0 +1,2396 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xls_xml_context.hpp" +#include "xls_xml_namespace_types.hpp" +#include "xls_xml_token_constants.hpp" +#include "spreadsheet_iface_util.hpp" +#include "impl_utils.hpp" + +#include <orcus/spreadsheet/import_interface.hpp> +#include <orcus/spreadsheet/import_interface_styles.hpp> +#include <orcus/spreadsheet/import_interface_view.hpp> +#include <orcus/measurement.hpp> + +#include <mdds/sorted_string_map.hpp> + +#include <iostream> +#include <sstream> +#include <limits> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace { + +ss::color_rgb_t to_rgb(std::string_view s) +{ + if (!s.empty() && s[0] == '#') + return ss::to_color_rgb(s); + else + { + // This may be a color name. Lower-case it before sending it to the + // function. + std::string s_lower(s.size(), '\0'); + const char* p = s.data(); + std::transform(p, p + s.size(), s_lower.begin(), + [](char c) -> char + { + if ('A' <= c && c <= 'Z') + c += 'a' - 'A'; + return c; + } + ); + + return ss::to_color_rgb_from_name(s_lower); + } +} + +namespace border_dir { + +using map_type = mdds::sorted_string_map<ss::border_direction_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "Bottom", ss::border_direction_t::bottom }, + { "DiagonalLeft", ss::border_direction_t::diagonal_tl_br }, + { "DiagonalRight", ss::border_direction_t::diagonal_bl_tr }, + { "Left", ss::border_direction_t::left }, + { "Right", ss::border_direction_t::right }, + { "Top", ss::border_direction_t::top }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::border_direction_t::unknown); + return mt; +} + +} // namespace border_dir + +namespace border_style { + +using map_type = mdds::sorted_string_map<ss::border_style_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "Continuous", ss::border_style_t::solid }, + { "Dash", ss::border_style_t::dashed }, + { "DashDot", ss::border_style_t::dash_dot }, + { "DashDotDot", ss::border_style_t::dash_dot_dot }, + { "Dot", ss::border_style_t::dotted }, + { "Double", ss::border_style_t::double_border }, + { "SlantDashDot", ss::border_style_t::slant_dash_dot }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::border_style_t::unknown); + return mt; +} + +} + +namespace hor_align { + +using map_type = mdds::sorted_string_map<ss::hor_alignment_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "Center", ss::hor_alignment_t::center }, + { "Distributed", ss::hor_alignment_t::distributed }, + { "Justify", ss::hor_alignment_t::justified }, + { "Left", ss::hor_alignment_t::left }, + { "Right", ss::hor_alignment_t::right }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::hor_alignment_t::unknown); + return mt; +} + +} + +namespace ver_align { + +using map_type = mdds::sorted_string_map<ss::ver_alignment_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "Bottom", ss::ver_alignment_t::bottom }, + { "Center", ss::ver_alignment_t::middle }, + { "Distributed", ss::ver_alignment_t::distributed }, + { "Justify", ss::ver_alignment_t::justified }, + { "Top", ss::ver_alignment_t::top }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::ver_alignment_t::unknown); + return mt; +} + +} + +namespace num_format { + +using map_type = mdds::sorted_string_map<std::string_view, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "Currency", "$#,##0.00_);[Red]($#,##0.00)" }, + { "Euro Currency", "[$\xe2\x82\xac-x-euro2] #,##0.00_);[Red]([$\xe2\x82\xac-x-euro2] #,##0.00)" }, + { "Fixed", "0.00" }, + { "General Date", "m/d/yyyy h:mm" }, + { "General Number", "General" }, + { "Long Date", "d-mmm-yy" }, + { "Long Time", "h:mm:ss AM/PM" }, + { "Medium Date", "d-mmm-yy" }, + { "Medium Time", "h:mm AM/PM" }, + { "On/Off", "\"On\";\"On\";\"Off\"" }, + { "Percent", "0.00%" }, + { "Scientific", "0.00E+00" }, + { "Short Date", "m/d/yyyy" }, + { "Short Time", "h:mm" }, + { "Standard", "#,##0.00" }, + { "True/False", "\"True\";\"True\";\"False\"" }, + { "Yes/No", "\"Yes\";\"Yes\";\"No\"" }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), std::string_view{}); + return mt; +} + +} // namespace num_format + +namespace underline { + +using map_type = mdds::sorted_string_map<ss::underline_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "Double", ss::underline_t::double_line }, + { "DoubleAccounting", ss::underline_t::double_accounting }, + { "None", ss::underline_t::none }, + { "Single", ss::underline_t::single_line }, + { "SingleAccounting", ss::underline_t::single_accounting }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::underline_t::none); + return mt; +} + +} // namespace underline + +} // anonymous namespace + +void xls_xml_data_context::format_type::merge(const format_type& fmt) +{ + if (fmt.bold) + bold = fmt.bold; + + if (fmt.italic) + italic = fmt.italic; + + if (fmt.underline) + underline = fmt.underline; + + if (fmt.strikethrough) + strikethrough = fmt.strikethrough; + + if (fmt.subscript) + subscript = fmt.subscript; + + if (fmt.superscript) + superscript = fmt.superscript; + + if (fmt.font_face) + font_face = fmt.font_face; + + if (fmt.font_size) + font_size = fmt.font_size; + + if (fmt.color) + color = fmt.color; +} + +bool xls_xml_data_context::format_type::formatted() const +{ + return bold || italic || underline || strikethrough + || subscript || superscript || font_face || font_size + || color; +} + +xls_xml_data_context::string_segment_type::string_segment_type(std::string_view _str) : + str(_str) {} + +xls_xml_data_context::xls_xml_data_context( + session_context& session_cxt, const tokens& tokens, xls_xml_context& parent_cxt) : + xml_context_base(session_cxt, tokens), + m_parent_cxt(parent_cxt), + m_cell_type(ct_unknown), + m_cell_value(std::numeric_limits<double>::quiet_NaN()) +{ + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_xls_xml_ss, XML_Data }, // root element + { NS_xls_xml_html, XML_B, NS_xls_xml_html, XML_Font }, + { NS_xls_xml_html, XML_Font, NS_xls_xml_html, XML_B }, + { NS_xls_xml_html, XML_Font, NS_xls_xml_html, XML_I }, + { NS_xls_xml_html, XML_Font, NS_xls_xml_html, XML_S }, + { NS_xls_xml_html, XML_Font, NS_xls_xml_html, XML_Sub }, + { NS_xls_xml_html, XML_Font, NS_xls_xml_html, XML_Sup }, + { NS_xls_xml_html, XML_Font, NS_xls_xml_html, XML_U }, + { NS_xls_xml_html, XML_I, NS_xls_xml_html, XML_Font }, + { NS_xls_xml_html, XML_S, NS_xls_xml_html, XML_Font }, + { NS_xls_xml_html, XML_Sub, NS_xls_xml_html, XML_Font }, + { NS_xls_xml_html, XML_Sup, NS_xls_xml_html, XML_Font }, + { NS_xls_xml_html, XML_U, NS_xls_xml_html, XML_Font }, + { NS_xls_xml_ss, XML_Data, NS_xls_xml_html, XML_B }, + { NS_xls_xml_ss, XML_Data, NS_xls_xml_html, XML_Font }, + { NS_xls_xml_ss, XML_Data, NS_xls_xml_html, XML_I }, + { NS_xls_xml_ss, XML_Data, NS_xls_xml_html, XML_S }, + { NS_xls_xml_ss, XML_Data, NS_xls_xml_html, XML_Sub }, + { NS_xls_xml_ss, XML_Data, NS_xls_xml_html, XML_Sup }, + { NS_xls_xml_ss, XML_Data, NS_xls_xml_html, XML_U }, + }; + + init_element_validator(rules, std::size(rules)); +} + +xls_xml_data_context::~xls_xml_data_context() {} + +xml_context_base* xls_xml_data_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void xls_xml_data_context::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void xls_xml_data_context::start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + + if (ns == NS_xls_xml_ss) + { + switch (name) + { + case XML_Data: + start_element_data(parent, attrs); + break; + default: + warn_unhandled(); + } + } + else if (ns == NS_xls_xml_html) + { + switch (name) + { + case XML_B: + m_format_stack.emplace_back(); + m_format_stack.back().bold = true; + update_current_format(); + break; + case XML_I: + m_format_stack.emplace_back(); + m_format_stack.back().italic = true; + update_current_format(); + break; + case XML_U: + m_format_stack.emplace_back(); + m_format_stack.back().underline = true; + update_current_format(); + break; + case XML_S: + m_format_stack.emplace_back(); + m_format_stack.back().strikethrough = true; + update_current_format(); + break; + case XML_Sub: + m_format_stack.emplace_back(); + m_format_stack.back().subscript = true; + update_current_format(); + break; + case XML_Sup: + m_format_stack.emplace_back(); + m_format_stack.back().superscript = true; + update_current_format(); + break; + case XML_Font: + { + m_format_stack.emplace_back(); + format_type& fmt = m_format_stack.back(); + + for (const xml_token_attr_t& attr : attrs) + { + if (ns == NS_xls_xml_html) + { + switch (attr.name) + { + case XML_Color: + fmt.color = to_rgb(attr.value); + break; + case XML_Face: + fmt.font_face = attr.transient ? intern(attr.value) : attr.value; + break; + case XML_Size: + { + const char* p_end = nullptr; + double v = to_double(attr.value, &p_end); + if (attr.value.data() < p_end) + fmt.font_size = v; + break; + } + } + } + } + + update_current_format(); + break; + } + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +void xls_xml_data_context::characters(std::string_view str, bool transient) +{ + if (str.empty()) + return; + + switch (m_cell_type) + { + case ct_unknown: + break; + case ct_string: + { + if (transient) + m_cell_string.emplace_back(intern(str)); + else + m_cell_string.emplace_back(str); + + if (m_current_format.formatted()) + { + // Apply the current format to this string segment. + string_segment_type& ss = m_cell_string.back(); + ss.format = m_current_format; + ss.formatted = true; + } + + break; + } + case ct_number: + { + m_cell_value = to_double(str); + break; + } + case ct_datetime: + m_cell_datetime = date_time_t::from_chars(str); + break; + default: + { + std::ostringstream os; + os << "unknown cell type '" << m_cell_type << "': characters='" << str << "'"; + warn(os.str()); + } + } +} + +bool xls_xml_data_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_xls_xml_ss) + { + switch (name) + { + case XML_Data: + end_element_data(); + break; + default: + ; + } + } + else if (ns == NS_xls_xml_html) + { + switch (name) + { + case XML_B: + case XML_I: + case XML_U: + case XML_S: + case XML_Sub: + case XML_Sup: + case XML_Font: + assert(!m_format_stack.empty()); + m_format_stack.pop_back(); + update_current_format(); + break; + default: + ; + } + } + + return pop_stack(ns, name); +} + +void xls_xml_data_context::reset() +{ + m_format_stack.clear(); + m_format_stack.emplace_back(); // set default format. + update_current_format(); + + m_cell_type = ct_unknown; + m_cell_string.clear(); + + m_cell_value = std::numeric_limits<double>::quiet_NaN(); + m_cell_datetime = date_time_t(); +} + +void xls_xml_data_context::start_element_data( + const xml_token_pair_t& /*parent*/, const xml_token_attrs_t& attrs) +{ + m_cell_type = ct_unknown; + m_cell_string.clear(); + m_cell_datetime = date_time_t(); + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns != NS_xls_xml_ss) + continue; + + switch (attr.name) + { + case XML_Type: + { + if (attr.value == "String") + m_cell_type = ct_string; + else if (attr.value == "Number") + m_cell_type = ct_number; + else if (attr.value == "DateTime") + m_cell_type = ct_datetime; + break; + } + default: + ; + } + } +} + +void xls_xml_data_context::end_element_data() +{ + auto formula = m_parent_cxt.pop_and_clear_formula(); + + if (!formula.empty()) + { + if (m_parent_cxt.is_array_formula()) + store_array_formula_parent_cell(formula); + else + push_formula_cell(formula); + m_cell_type = ct_unknown; + return; + } + + if (handle_array_formula_result()) + { + m_cell_type = ct_unknown; + return; + } + + ss::iface::import_sheet* sheet = m_parent_cxt.get_import_sheet(); + ss::address_t pos = m_parent_cxt.get_current_pos(); + + switch (m_cell_type) + { + case ct_unknown: + break; + case ct_number: + sheet->set_value(pos.row, pos.column, m_cell_value); + break; + case ct_string: + { + ss::iface::import_shared_strings* ss = + m_parent_cxt.get_import_factory()->get_shared_strings(); + + if (!ss) + break; + + if (m_cell_string.empty()) + break; + + if (m_cell_string.size() == 1 && !m_cell_string[0].formatted) + { + // Unformatted string. + std::string_view s = m_cell_string.back().str; + sheet->set_string(pos.row, pos.column, ss->append(s)); + } + else + { + // Formatted string. Note that an absence of a format type + // appears to mean its negative value is implied. + + for (const string_segment_type& sstr : m_cell_string) + { + if (sstr.format.bold) + ss->set_segment_bold(*sstr.format.bold); + else + ss->set_segment_bold(false); // implied + + if (sstr.format.italic) + ss->set_segment_italic(*sstr.format.italic); + else + ss->set_segment_italic(false); // implied + + if (sstr.format.font_face) + ss->set_segment_font_name(*sstr.format.font_face); + + if (sstr.format.font_size) + ss->set_segment_font_size(*sstr.format.font_size); + + if (sstr.format.color) + ss->set_segment_font_color( + 255, + sstr.format.color->red, + sstr.format.color->green, + sstr.format.color->blue); + + ss->append_segment(sstr.str); + } + + size_t si = ss->commit_segments(); + sheet->set_string(pos.row, pos.column, si); + } + + m_cell_string.clear(); + + break; + } + case ct_datetime: + { + sheet->set_date_time( + pos.row, pos.column, + m_cell_datetime.year, m_cell_datetime.month, m_cell_datetime.day, + m_cell_datetime.hour, m_cell_datetime.minute, m_cell_datetime.second); + break; + } + default: + { + std::ostringstream os; + os <<"unknown cell type '" << m_cell_type << "': value not pushed."; + warn(os.str()); + } + } + + m_cell_type = ct_unknown; +} + +bool xls_xml_data_context::handle_array_formula_result() +{ + xls_xml_context::array_formulas_type& store = m_parent_cxt.get_array_formula_store(); + ss::address_t cur_pos = m_parent_cxt.get_current_pos(); + + // See if the current cell is within an array formula range. + auto it = store.begin(), ite = store.end(); + + while (it != ite) + { + const ss::range_t& ref = it->first; + xls_xml_context::array_formula_type& af = *it->second; + + if (ref.last.row < cur_pos.row) + { + // If this result range lies above the current row, push the array + // and delete it from the list. + + ss::iface::import_sheet* sheet = m_parent_cxt.get_import_sheet(); + ss::iface::import_array_formula* array = nullptr; + + if (sheet) + array = sheet->get_array_formula(); + + if (array) + { + push_array_formula( + array, ref, af.formula, ss::formula_grammar_t::xls_xml, af.results); + } + + store.erase(it++); + continue; + } + + if (cur_pos.column < ref.first.column || ref.last.column < cur_pos.column || + cur_pos.row < ref.first.row || ref.last.row < cur_pos.row) + { + // This cell is not within this array formula range. Move on to + // the next one. + ++it; + continue; + } + + size_t row_offset = cur_pos.row - ref.first.row; + size_t col_offset = cur_pos.column - ref.first.column; + range_formula_results& res = af.results; + push_array_result(res, row_offset, col_offset); + + return true; + } + + return false; +} + +void xls_xml_data_context::push_array_result( + range_formula_results& res, size_t row_offset, size_t col_offset) +{ + switch (m_cell_type) + { + case ct_number: + { + res.set(row_offset, col_offset, m_cell_value); + break; + } + case ct_unknown: + case ct_datetime: + case ct_string: + default: + { + std::ostringstream os; + os << "unknown cell type '" << m_cell_type << "': value not pushed."; + warn(os.str()); + } + } +} + +void xls_xml_data_context::push_formula_cell(std::string_view formula) +{ + switch (m_cell_type) + { + case ct_number: + m_parent_cxt.store_cell_formula(formula, m_cell_value); + break; + default: + { + formula_result res; + m_parent_cxt.store_cell_formula(formula, res); + } + } +} + +void xls_xml_data_context::store_array_formula_parent_cell(std::string_view formula) +{ + ss::address_t pos = m_parent_cxt.get_current_pos(); + ss::range_t range = m_parent_cxt.get_array_range(); + xls_xml_context::array_formulas_type& store = m_parent_cxt.get_array_formula_store(); + + range += pos; + + store.push_back( + std::make_pair( + range, + std::make_unique<xls_xml_context::array_formula_type>(range, formula))); + + xls_xml_context::array_formula_type& af = *store.back().second; + + switch (m_cell_type) + { + case ct_number: + af.results.set(0, 0, m_cell_value); + break; + default: + ; + } +} + +void xls_xml_data_context::update_current_format() +{ + // format stack should have at least one entry at any given moment. + assert(!m_format_stack.empty()); + + // Grab the bottom format. + auto it = m_format_stack.begin(); + m_current_format = *it; + ++it; + + // Merge in the rest of the format data. + std::for_each(it, m_format_stack.end(), + [&](const format_type& fmt) + { + m_current_format.merge(fmt); + } + ); +} + +xls_xml_context::array_formula_type::array_formula_type( + const ss::range_t& _range, std::string_view _formula) : + formula(_formula), + results(_range.last.row-_range.first.row+1, _range.last.column-_range.first.column+1) {} + +xls_xml_context::named_exp::named_exp(std::string_view _name, std::string_view _expression, ss::sheet_t _scope) : + name(_name), expression(_expression), scope(_scope) {} + +xls_xml_context::selection::selection() : pane(ss::sheet_pane_t::unspecified), col(-1), row(-1) +{ + range.first.column = -1; + range.first.row = -1; + range.last.column = -1; + range.last.row = -1; +} + +void xls_xml_context::selection::reset() +{ + pane = ss::sheet_pane_t::unspecified; + col = 0; + row = 0; + + range.first.column = -1; + range.first.row = -1; + range.last.column = -1; + range.last.row = -1; +} + +bool xls_xml_context::selection::valid_cursor() const +{ + return col >= 0 && row >= 0; +} + +bool xls_xml_context::selection::valid_range() const +{ + return range.first.column >= 0 && range.first.row >= 0 && range.last.column >= 0 && range.last.row >= 0; +} + +xls_xml_context::split_pane::split_pane() : + pane_state(ss::pane_state_t::split), + active_pane(ss::sheet_pane_t::top_left), + split_horizontal(0.0), split_vertical(0.0), + top_row_bottom_pane(0), left_col_right_pane(0) {} + +void xls_xml_context::split_pane::reset() +{ + pane_state = ss::pane_state_t::split; + active_pane = ss::sheet_pane_t::top_left; + split_horizontal = 0.0; + split_vertical = 0.0; + top_row_bottom_pane = 0; + left_col_right_pane = 0; +} + +bool xls_xml_context::split_pane::split() const +{ + return (split_horizontal || split_vertical) && (top_row_bottom_pane || left_col_right_pane); +} + +ss::address_t xls_xml_context::split_pane::get_top_left_cell() const +{ + ss::address_t pos; + pos.column = left_col_right_pane; + pos.row = top_row_bottom_pane; + return pos; +} + +xls_xml_context::table_properties::table_properties() +{ + reset(); +} + +void xls_xml_context::table_properties::reset() +{ + pos.row = 0; + pos.column = 0; +} + +xls_xml_context::xls_xml_context(session_context& session_cxt, const tokens& tokens, ss::iface::import_factory* factory) : + xml_context_base(session_cxt, tokens), + mp_factory(factory), + mp_cur_sheet(nullptr), + mp_sheet_props(nullptr), + m_cur_sheet(-1), + m_cur_row(0), m_cur_col(0), + m_cur_prop_col(0), + m_cur_merge_down(0), m_cur_merge_across(0), + m_cc_data(session_cxt, tokens, *this) +{ + register_child(&m_cc_data); + + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_xls_xml_ss, XML_Workbook }, // root element + { NS_xls_xml_o, XML_DocumentProperties, NS_xls_xml_o, XML_Author }, + { NS_xls_xml_o, XML_DocumentProperties, NS_xls_xml_o, XML_Company }, + { NS_xls_xml_o, XML_DocumentProperties, NS_xls_xml_o, XML_Created }, + { NS_xls_xml_o, XML_DocumentProperties, NS_xls_xml_o, XML_LastAuthor }, + { NS_xls_xml_o, XML_DocumentProperties, NS_xls_xml_o, XML_LastSaved }, + { NS_xls_xml_o, XML_DocumentProperties, NS_xls_xml_o, XML_Version }, + { NS_xls_xml_o, XML_OfficeDocumentSettings, NS_xls_xml_o, XML_AllowPNG }, + { NS_xls_xml_o, XML_OfficeDocumentSettings, NS_xls_xml_o, XML_DownloadComponents }, + { NS_xls_xml_o, XML_OfficeDocumentSettings, NS_xls_xml_o, XML_LocationOfComponents }, + { NS_xls_xml_ss, XML_Borders, NS_xls_xml_ss, XML_Border }, + { NS_xls_xml_ss, XML_Cell, NS_xls_xml_ss, XML_Data }, + { NS_xls_xml_ss, XML_Cell, NS_xls_xml_ss, XML_NamedCell }, + { NS_xls_xml_ss, XML_Names, NS_xls_xml_ss, XML_NamedRange }, + { NS_xls_xml_ss, XML_Row, NS_xls_xml_ss, XML_Cell }, + { NS_xls_xml_ss, XML_Style, NS_xls_xml_ss, XML_Alignment }, + { NS_xls_xml_ss, XML_Style, NS_xls_xml_ss, XML_Borders }, + { NS_xls_xml_ss, XML_Style, NS_xls_xml_ss, XML_Font }, + { NS_xls_xml_ss, XML_Style, NS_xls_xml_ss, XML_Interior }, + { NS_xls_xml_ss, XML_Style, NS_xls_xml_ss, XML_NumberFormat }, + { NS_xls_xml_ss, XML_Style, NS_xls_xml_ss, XML_Protection }, + { NS_xls_xml_ss, XML_Styles, NS_xls_xml_ss, XML_Style }, + { NS_xls_xml_ss, XML_Table, NS_xls_xml_ss, XML_Column }, + { NS_xls_xml_ss, XML_Table, NS_xls_xml_ss, XML_Row }, + { NS_xls_xml_ss, XML_Workbook, NS_xls_xml_o, XML_DocumentProperties }, + { NS_xls_xml_ss, XML_Workbook, NS_xls_xml_o, XML_OfficeDocumentSettings }, + { NS_xls_xml_ss, XML_Workbook, NS_xls_xml_ss, XML_Names }, + { NS_xls_xml_ss, XML_Workbook, NS_xls_xml_ss, XML_Styles }, + { NS_xls_xml_ss, XML_Workbook, NS_xls_xml_ss, XML_Worksheet }, + { NS_xls_xml_ss, XML_Workbook, NS_xls_xml_x, XML_ExcelWorkbook }, + { NS_xls_xml_ss, XML_Worksheet, NS_xls_xml_ss, XML_Names }, + { NS_xls_xml_ss, XML_Worksheet, NS_xls_xml_ss, XML_Table }, + { NS_xls_xml_ss, XML_Worksheet, NS_xls_xml_x, XML_AutoFilter }, + { NS_xls_xml_ss, XML_Worksheet, NS_xls_xml_x, XML_WorksheetOptions }, + { NS_xls_xml_x, XML_AutoFilter, NS_xls_xml_x, XML_AutoFilterColumn }, + { NS_xls_xml_x, XML_AutoFilterColumn, NS_xls_xml_x, XML_AutoFilterCondition }, + { NS_xls_xml_x, XML_AutoFilterColumn, NS_xls_xml_x, XML_AutoFilterOr }, + { NS_xls_xml_x, XML_AutoFilterOr, NS_xls_xml_x, XML_AutoFilterCondition }, + { NS_xls_xml_x, XML_ExcelWorkbook, NS_xls_xml_x, XML_ActiveSheet }, + { NS_xls_xml_x, XML_ExcelWorkbook, NS_xls_xml_x, XML_FirstVisibleSheet }, + { NS_xls_xml_x, XML_ExcelWorkbook, NS_xls_xml_x, XML_ProtectStructure }, + { NS_xls_xml_x, XML_ExcelWorkbook, NS_xls_xml_x, XML_ProtectWindows }, + { NS_xls_xml_x, XML_ExcelWorkbook, NS_xls_xml_x, XML_RefModeR1C1 }, + { NS_xls_xml_x, XML_ExcelWorkbook, NS_xls_xml_x, XML_TabRatio }, + { NS_xls_xml_x, XML_ExcelWorkbook, NS_xls_xml_x, XML_WindowHeight }, + { NS_xls_xml_x, XML_ExcelWorkbook, NS_xls_xml_x, XML_WindowTopX }, + { NS_xls_xml_x, XML_ExcelWorkbook, NS_xls_xml_x, XML_WindowTopY }, + { NS_xls_xml_x, XML_ExcelWorkbook, NS_xls_xml_x, XML_WindowWidth }, + { NS_xls_xml_x, XML_PageSetup, NS_xls_xml_x, XML_Footer }, + { NS_xls_xml_x, XML_PageSetup, NS_xls_xml_x, XML_Header }, + { NS_xls_xml_x, XML_PageSetup, NS_xls_xml_x, XML_PageMargins }, + { NS_xls_xml_x, XML_Pane, NS_xls_xml_x, XML_ActiveCol }, + { NS_xls_xml_x, XML_Pane, NS_xls_xml_x, XML_ActiveRow }, + { NS_xls_xml_x, XML_Pane, NS_xls_xml_x, XML_Number }, + { NS_xls_xml_x, XML_Pane, NS_xls_xml_x, XML_RangeSelection }, + { NS_xls_xml_x, XML_Panes, NS_xls_xml_x, XML_Pane }, + { NS_xls_xml_x, XML_Print, NS_xls_xml_x, XML_HorizontalResolution }, + { NS_xls_xml_x, XML_Print, NS_xls_xml_x, XML_ValidPrinterInfo }, + { NS_xls_xml_x, XML_Print, NS_xls_xml_x, XML_VerticalResolution }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_ActivePane }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_FilterOn }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_FreezePanes }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_FrozenNoSplit }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_LeftColumnRightPane }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_PageSetup }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_Panes }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_Print }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_ProtectObjects }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_ProtectScenarios }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_Selected }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_SplitHorizontal }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_SplitVertical }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_TopRowBottomPane }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_TopRowVisible }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_Unsynced }, + { NS_xls_xml_x, XML_WorksheetOptions, NS_xls_xml_x, XML_Zoom }, + }; + + init_element_validator(rules, std::size(rules)); + + m_cur_array_range.first.column = -1; + m_cur_array_range.first.row = -1; + m_cur_array_range.last = m_cur_array_range.first; +} + +xls_xml_context::~xls_xml_context() +{ +} + +void xls_xml_context::declaration(const xml_declaration_t& decl) +{ + ss::iface::import_global_settings* gs = mp_factory->get_global_settings(); + if (!gs) + return; + + gs->set_character_set(decl.encoding); +} + +xml_context_base* xls_xml_context::create_child_context(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_xls_xml_ss) + { + switch (name) + { + case XML_Data: + { + // Move the cell formula string to the Data element context. + m_cc_data.reset(); + return &m_cc_data; + } + default: + ; + } + } + return nullptr; +} + +void xls_xml_context::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void xls_xml_context::start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) +{ + push_stack(ns, name); + + if (ns == NS_xls_xml_ss) + { + switch (name) + { + case XML_Workbook: + // Do nothing. + break; + case XML_Worksheet: + { + start_element_worksheet(attrs); + break; + } + case XML_Table: + start_element_table(attrs); + break; + case XML_Row: + start_element_row(attrs); + break; + case XML_Cell: + start_element_cell(attrs); + break; + case XML_Column: + start_element_column(attrs); + break; + case XML_Names: + break; + case XML_NamedRange: + { + std::string_view name_s, exp; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns != NS_xls_xml_ss) + continue; + + switch (attr.name) + { + case XML_Name: + name_s = intern(attr); + break; + case XML_RefersTo: + { + exp = attr.value; + if (exp.size() > 1 && exp[0] == '=') + exp = std::string_view{exp.data()+1, exp.size()-1}; + if (!exp.empty() && attr.transient) + exp = intern(exp); + break; + } + default: + ; + } + } + + if (!name_s.empty() && !exp.empty()) + { + if (m_cur_sheet >= 0) + m_named_exps_sheet.emplace_back(name_s, exp, m_cur_sheet); + else + m_named_exps_global.emplace_back(name_s, exp, -1); + } + + break; + } + case XML_Styles: + break; + case XML_Style: + { + m_current_style = std::make_unique<style_type>(); + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns != NS_xls_xml_ss) + continue; + + switch (attr.name) + { + case XML_ID: + m_current_style->id = intern(attr); + break; + case XML_Name: + m_current_style->name = intern(attr); + break; + case XML_Parent: + m_current_style->parent_id = intern(attr); + break; + default: + ; + } + } + + break; + } + case XML_Borders: + start_element_borders(attrs); + break; + case XML_Border: + start_element_border(attrs); + break; + case XML_NumberFormat: + start_element_number_format(attrs); + break; + case XML_Font: + { + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns != NS_xls_xml_ss) + continue; + + switch (attr.name) + { + case XML_FontName: + { + m_current_style->font.name = intern(attr); + break; + } + case XML_Bold: + { + m_current_style->font.bold = to_bool(attr.value); + break; + } + case XML_Italic: + { + m_current_style->font.italic = to_bool(attr.value); + break; + } + case XML_Color: + { + m_current_style->font.color = to_rgb(attr.value); + break; + } + case XML_Size: + { + m_current_style->font.size = to_double(attr.value); + break; + } + case XML_Underline: + { + m_current_style->font.underline = underline::get().find(attr.value); + break; + } + } + } + break; + } + case XML_Interior: + { + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns != NS_xls_xml_ss) + continue; + + switch (attr.name) + { + case XML_Color: + { + m_current_style->fill.color = to_rgb(attr.value); + break; + } + case XML_Pattern: + { + // TODO : support fill types other than 'solid'. + m_current_style->fill.solid = (attr.value == "Solid"); + break; + } + default: + ; + } + } + break; + } + case XML_Alignment: + { + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns != NS_xls_xml_ss) + continue; + + switch (attr.name) + { + case XML_Horizontal: + { + m_current_style->text_alignment.hor = hor_align::get().find(attr.value); + break; + } + case XML_Vertical: + { + m_current_style->text_alignment.ver = ver_align::get().find(attr.value); + break; + } + case XML_Indent: + { + m_current_style->text_alignment.indent = to_long(attr.value); + break; + } + case XML_WrapText: + { + m_current_style->text_alignment.wrap_text = to_bool(attr.value); + break; + } + case XML_ShrinkToFit: + { + m_current_style->text_alignment.shrink_to_fit = to_bool(attr.value); + break; + } + default: + ; + } + } + break; + } + case XML_Protection: + { + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns == NS_xls_xml_x && attr.name == XML_HideFormula) + { + m_current_style->cell_protection.hide_formula = to_bool(attr.value); + } + else if (attr.ns == NS_xls_xml_ss && attr.name == XML_Protected) + { + m_current_style->cell_protection.locked = to_bool(attr.value); + } + } + } + default: + warn_unhandled(); + } + } + else if (ns == NS_xls_xml_x) + { + switch (name) + { + case XML_WorksheetOptions: + m_split_pane.reset(); + break; + case XML_FreezePanes: + // TODO : check if this is correct. + m_split_pane.pane_state = ss::pane_state_t::frozen_split; + break; + case XML_FrozenNoSplit: + m_split_pane.pane_state = ss::pane_state_t::frozen; + break; + case XML_ActivePane: + m_split_pane.active_pane = ss::sheet_pane_t::unspecified; + break; + case XML_SplitHorizontal: + m_split_pane.split_horizontal = 0.0; + break; + case XML_SplitVertical: + m_split_pane.split_vertical = 0.0; + break; + case XML_TopRowBottomPane: + m_split_pane.top_row_bottom_pane = 0; + break; + case XML_LeftColumnRightPane: + m_split_pane.left_col_right_pane = 0; + break; + case XML_Panes: + break; + case XML_Pane: + m_cursor_selection.reset(); + break; + case XML_Number: + break; + case XML_ActiveCol: + break; + case XML_ActiveRow: + break; + case XML_RangeSelection: + break; + case XML_Selected: + { + if (mp_cur_sheet) + { + ss::iface::import_sheet_view* sv = mp_cur_sheet->get_sheet_view(); + if (sv) + sv->set_sheet_active(); + } + break; + } + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool xls_xml_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_xls_xml_ss) + { + switch (name) + { + case XML_Borders: + end_element_borders(); + break; + case XML_Border: + end_element_border(); + break; + case XML_NumberFormat: + end_element_number_format(); + break; + case XML_Row: + end_element_row(); + break; + case XML_Cell: + end_element_cell(); + break; + case XML_Column: + end_element_column(); + break; + case XML_Table: + end_element_table(); + break; + case XML_Workbook: + end_element_workbook(); + break; + case XML_Worksheet: + end_element_worksheet(); + break; + case XML_Style: + { + if (m_current_style) + { + if (m_current_style->id == "Default") + m_default_style = std::move(m_current_style); + else + m_styles.push_back(std::move(m_current_style)); + } + break; + } + case XML_Styles: + { + end_element_styles(); + break; + } + default: + ; + } + } + else if (ns == NS_xls_xml_x) + { + switch (name) + { + case XML_Pane: + end_element_pane(); + break; + case XML_WorksheetOptions: + end_element_worksheet_options(); + break; + default: + ; + } + } + return pop_stack(ns, name); +} + +namespace { + +ss::sheet_pane_t to_sheet_pane(long v) +{ + static const std::vector<ss::sheet_pane_t> mapping = { + ss::sheet_pane_t::bottom_right, // 0 + ss::sheet_pane_t::top_right, // 1 + ss::sheet_pane_t::bottom_left, // 2 + ss::sheet_pane_t::top_left, // 3 + }; + + if (v < 0 || size_t(v) >= mapping.size()) + return ss::sheet_pane_t::unspecified; + + return mapping[v]; +} + +} + +void xls_xml_context::characters(std::string_view str, bool /*transient*/) +{ + if (str.empty()) + return; + + xml_token_pair_t ce = get_current_element(); + + if (ce.first == NS_xls_xml_x) + { + switch (ce.second) + { + case XML_Number: + // sheet pane position. + // 3 | 1 + //---+--- + // 2 | 0 + m_cursor_selection.pane = to_sheet_pane(to_long(str)); + break; + case XML_ActiveCol: + m_cursor_selection.col = to_long(str); + break; + case XML_ActiveRow: + m_cursor_selection.row = to_long(str); + break; + case XML_ActivePane: + m_split_pane.active_pane = to_sheet_pane(to_long(str)); + break; + case XML_SplitHorizontal: + m_split_pane.split_horizontal = to_double(str); + break; + case XML_SplitVertical: + m_split_pane.split_vertical = to_double(str); + break; + case XML_TopRowBottomPane: + m_split_pane.top_row_bottom_pane = to_long(str); + break; + case XML_LeftColumnRightPane: + m_split_pane.left_col_right_pane = to_long(str); + break; + case XML_RangeSelection: + { + ss::iface::import_reference_resolver* resolver = + mp_factory->get_reference_resolver(ss::formula_ref_context_t::global); + + if (resolver) + m_cursor_selection.range = to_rc_range(resolver->resolve_range(str)); + + break; + } + default: + ; + } + } +} + +void xls_xml_context::start_element_borders(const xml_token_attrs_t& /*attrs*/) +{ + m_current_style->borders.clear(); +} + +void xls_xml_context::start_element_border(const xml_token_attrs_t& attrs) +{ + ss::border_direction_t dir = ss::border_direction_t::unknown; + ss::border_style_t style = ss::border_style_t::unknown; + std::optional<ss::color_rgb_t> color; + long weight = 0; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns != NS_xls_xml_ss) + continue; + + switch (attr.name) + { + case XML_Position: + { + dir = border_dir::get().find(attr.value); + break; + } + case XML_LineStyle: + { + style = border_style::get().find(attr.value); + break; + } + case XML_Weight: + { + weight = to_long(attr.value); + break; + } + case XML_Color: + { + color = to_rgb(attr.value); + break; + } + default: + ; + } + } + + if (dir == ss::border_direction_t::unknown || style == ss::border_style_t::unknown) + return; + + m_current_style->borders.emplace_back(); + border_style_type& bs = m_current_style->borders.back(); + bs.dir = dir; + bs.style = style; + bs.color = color; + + switch (bs.style) + { + case ss::border_style_t::solid: + { + switch (weight) + { + case 0: + bs.style = ss::border_style_t::hair; + break; + case 1: + bs.style = ss::border_style_t::thin; + break; + case 2: + bs.style = ss::border_style_t::medium; + break; + case 3: + bs.style = ss::border_style_t::thick; + break; + default: + ; + } + break; + } + case ss::border_style_t::dashed: + if (weight > 1) + bs.style = ss::border_style_t::medium_dashed; + break; + case ss::border_style_t::dash_dot: + if (weight > 1) + bs.style = ss::border_style_t::medium_dash_dot; + break; + case ss::border_style_t::dash_dot_dot: + if (weight > 1) + bs.style = ss::border_style_t::medium_dash_dot_dot; + break; + default: + ; + } +} + +void xls_xml_context::start_element_number_format(const xml_token_attrs_t& attrs) +{ + m_current_style->number_format = std::string_view{}; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns != NS_xls_xml_ss) + continue; + + switch (attr.name) + { + case XML_Format: + { + std::string_view code = num_format::get().find(attr.value); + m_current_style->number_format = code.empty() ? intern(attr) : code; + break; + } + default: + ; + } + } +} + +void xls_xml_context::start_element_cell(const xml_token_attrs_t& attrs) +{ + long col_index = 0; + std::string_view formula; + m_cur_cell_style_id = std::string_view{}; + + m_cur_merge_across = 0; // extra column(s) that are part of the merged cell. + m_cur_merge_down = 0; // extra row(s) that are part of the merged cell. + + m_cur_array_range.first.column = -1; + m_cur_array_range.first.row = -1; + m_cur_array_range.last = m_cur_array_range.first; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.value.empty()) + return; + + if (attr.ns != NS_xls_xml_ss) + return; + + switch (attr.name) + { + case XML_Index: + col_index = to_long(attr.value); + break; + case XML_Formula: + if (attr.value[0] == '=' && attr.value.size() > 1) + { + std::string_view s{attr.value.data()+1, attr.value.size()-1}; + formula = s; + if (attr.transient) + formula = intern(s); + } + break; + case XML_MergeAcross: + m_cur_merge_across = to_long(attr.value); + break; + case XML_MergeDown: + m_cur_merge_down = to_long(attr.value); + break; + case XML_StyleID: + m_cur_cell_style_id = intern(attr); + break; + case XML_ArrayRange: + { + ss::iface::import_reference_resolver* resolver = + mp_factory->get_reference_resolver(ss::formula_ref_context_t::global); + if (resolver) + m_cur_array_range = to_rc_range(resolver->resolve_range(attr.value)); + + break; + } + default: + ; + } + } + + if (!formula.empty()) + m_cur_cell_formula = formula; + + if (col_index > 0) + { + // 1-based column index. Convert it to a 0-based one. + m_cur_col = m_table_props.pos.column + col_index - 1; + } +} + +void xls_xml_context::start_element_column(const xml_token_attrs_t& attrs) +{ + if (!mp_sheet_props && !mp_cur_sheet) + return; + + ss::col_t col_index = m_cur_prop_col; + ss::col_t span = 0; + double width = 0.0; + bool hidden = false; + std::optional<std::string_view> style_id; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.value.empty()) + continue; + + if (attr.ns != NS_xls_xml_ss) + continue; + + switch (attr.name) + { + case XML_Index: + { + // Convert from 1-based to 0-based. + const char* p_end = nullptr; + long v = to_long(attr.value, &p_end); + if (attr.value.data() < p_end) + col_index = m_table_props.pos.column + v - 1; + break; + } + case XML_Width: + width = to_double(attr.value); + break; + case XML_Span: + // Span is the number of extra columns after the first one i.e. + // if the span is 1, the properties get applied to two + // consecutive columns. Not very intuitive, but this is how it + // appears to work. + span = to_long(attr.value); + break; + case XML_Hidden: + hidden = to_long(attr.value) != 0; + break; + case XML_StyleID: + style_id = attr.value; // no need to intern since it gets used in the same function scope + break; + } + } + + if (mp_sheet_props) + { + // Column widths are stored as points. + mp_sheet_props->set_column_width(col_index, span + 1, width, orcus::length_unit_t::point); + mp_sheet_props->set_column_hidden(col_index, span + 1, hidden); + } + + if (mp_cur_sheet && style_id) + { + auto it = m_style_map_cell.find(*style_id); + if (it != m_style_map_cell.end()) + { + std::size_t xfid = it->second; + mp_cur_sheet->set_column_format(col_index, span + 1, xfid); + } + else + { + std::ostringstream os; + os << "xfid for the style ID of '" << *style_id << "' not found in the cache"; + warn(os.str()); + } + } + + m_cur_prop_col = col_index + span + 1; +} + +void xls_xml_context::start_element_row(const xml_token_attrs_t& attrs) +{ + m_cur_col = m_table_props.pos.column; + ss::row_t row_index = -1; + bool has_height = false; + bool hidden = false; + double height = 0.0; + std::optional<std::string_view> style_id; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.value.empty()) + return; + + if (attr.ns == NS_xls_xml_ss) + { + switch (attr.name) + { + case XML_Index: + row_index = to_long(attr.value); + break; + case XML_Height: + has_height = true; + height = to_double(attr.value); + break; + case XML_Hidden: + hidden = to_long(attr.value) != 0; + break; + case XML_StyleID: + style_id = attr.value; // no need to intern since it gets used in the same function scope + break; + } + } + } + + if (row_index > 0) + { + // 1-based row index. Convert it to a 0-based one. + m_cur_row = row_index - 1; + } + + if (mp_cur_sheet && style_id) + { + auto it = m_style_map_cell.find(*style_id); + if (it != m_style_map_cell.end()) + { + std::size_t xfid = it->second; + mp_cur_sheet->set_row_format(m_cur_row, xfid); + } + else + { + std::ostringstream os; + os << "xfid for the style ID of '" << *style_id << "' not found in the cache"; + warn(os.str()); + } + } + + if (mp_sheet_props) + { + if (has_height) + mp_sheet_props->set_row_height(m_cur_row, height, length_unit_t::point); + + if (hidden) + mp_sheet_props->set_row_hidden(m_cur_row, true); + } +} + +void xls_xml_context::start_element_table(const xml_token_attrs_t& attrs) +{ + ss::row_t row_index = -1; + ss::col_t col_index = -1; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.value.empty()) + return; + + if (attr.ns == NS_xls_xml_ss) + { + switch (attr.name) + { + case XML_TopCell: + col_index = to_long(attr.value); + break; + case XML_LeftCell: + row_index = to_long(attr.value); + break; + default: + ; + } + } + } + + // Convert 1-based indices to 0-based. + + if (row_index > 0) + m_table_props.pos.row = row_index - 1; + + if (col_index > 0) + m_table_props.pos.column = col_index - 1; + + m_cur_row = m_table_props.pos.row; + m_cur_prop_col = m_table_props.pos.column; +} + +void xls_xml_context::start_element_worksheet(const xml_token_attrs_t& attrs) +{ + ++m_cur_sheet; + std::string_view sheet_name; + m_cell_formulas.emplace_back(); + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns == NS_xls_xml_ss) + { + switch (attr.name) + { + case XML_Name: + sheet_name = attr.value; + break; + default: + ; + } + } + } + + mp_cur_sheet = mp_factory->append_sheet(m_cur_sheet, sheet_name); + ss::iface::import_named_expression* sheet_named_exp = nullptr; + if (mp_cur_sheet) + { + mp_sheet_props = mp_cur_sheet->get_sheet_properties(); + sheet_named_exp = mp_cur_sheet->get_named_expression(); + } + + m_sheet_named_exps.push_back(sheet_named_exp); + + m_cur_row = 0; + m_cur_col = 0; + + if (get_config().debug) + std::cout << "worksheet: name: '" << sheet_name << "'" << std::endl; +} + +void xls_xml_context::end_element_borders() +{ +} + +void xls_xml_context::end_element_border() +{ +} + +void xls_xml_context::end_element_number_format() +{ +} + +void xls_xml_context::end_element_cell() +{ + if (mp_sheet_props && (m_cur_merge_across > 0 || m_cur_merge_down > 0)) + { + ss::range_t merge_range; + merge_range.first.column = m_cur_col; + merge_range.first.row = m_cur_row; + merge_range.last.column = m_cur_col + m_cur_merge_across; + merge_range.last.row = m_cur_row + m_cur_merge_down; + + mp_sheet_props->set_merge_cell_range(merge_range); + } + + if (mp_cur_sheet && !m_cur_cell_style_id.empty()) + { + auto it = m_style_map_cell.find(m_cur_cell_style_id); + if (it != m_style_map_cell.end()) + { + auto xf_id = it->second; + mp_cur_sheet->set_format(m_cur_row, m_cur_col, xf_id); + } + } + + if (mp_cur_sheet && !m_cur_cell_formula.empty()) + { + // Likely a Cell element without a child Data element. + store_cell_formula(m_cur_cell_formula, formula_result()); + } + + m_cur_cell_formula = std::string_view{}; + + ++m_cur_col; + if (m_cur_merge_across > 0) + m_cur_col += m_cur_merge_across; +} + +void xls_xml_context::end_element_column() +{ +} + +void xls_xml_context::end_element_row() +{ + ++m_cur_row; +} + +void xls_xml_context::end_element_table() +{ + push_all_array_formulas(); + m_array_formulas.clear(); + m_table_props.reset(); + m_cur_row = 0; + m_cur_prop_col = 0; +} + +void xls_xml_context::end_element_worksheet() +{ + mp_cur_sheet = nullptr; +} + +void xls_xml_context::end_element_workbook() +{ + if (!mp_factory) + return; + + ss::iface::import_named_expression* ne_global = mp_factory->get_named_expression(); + if (ne_global) + { + // global scope named expressions. + + for (const named_exp& ne : m_named_exps_global) + { + ne_global->set_named_expression(ne.name, ne.expression); + ne_global->commit(); + } + } + + // sheet-local named expressions follow. + + for (const named_exp& ne : m_named_exps_sheet) + { + ss::iface::import_named_expression* p = nullptr; + if (ne.scope >= 0 && size_t(ne.scope) < m_sheet_named_exps.size()) + p = m_sheet_named_exps[ne.scope]; // it may be nullptr. + + if (p) + { + p->set_named_expression(ne.name, ne.expression); + p->commit(); + } + } + + // push all cell formulas + for (size_t sheet_pos = 0; sheet_pos < m_cell_formulas.size(); ++sheet_pos) + { + ss::iface::import_sheet* sheet = mp_factory->get_sheet(sheet_pos); + if (!sheet) + continue; + + ss::iface::import_formula* xformula = sheet->get_formula(); + if (!xformula) + continue; + + const std::deque<cell_formula_type>& store = m_cell_formulas[sheet_pos]; + for (const cell_formula_type& cf : store) + { + xformula->set_position(cf.pos.row, cf.pos.column); + xformula->set_formula(ss::formula_grammar_t::xls_xml, cf.formula); + + switch (cf.result.type) + { + case formula_result::result_type::numeric: + xformula->set_result_value(cf.result.value_numeric); + break; + case formula_result::result_type::string: + case formula_result::result_type::boolean: + case formula_result::result_type::empty: + ; + } + + xformula->commit(); + } + } +} + +void xls_xml_context::end_element_styles() +{ + commit_default_style(); // Commit the default style first. + commit_styles(); +} + +void xls_xml_context::end_element_pane() +{ + ss::iface::import_sheet_view* sv = mp_cur_sheet->get_sheet_view(); + if (!sv) + return; + + if (m_cursor_selection.pane == ss::sheet_pane_t::unspecified) + return; + + if (m_cursor_selection.valid_range()) + { + sv->set_selected_range(m_cursor_selection.pane, m_cursor_selection.range); + } + else if (m_cursor_selection.valid_cursor()) + { + ss::range_t sel; + sel.first.column = m_cursor_selection.col; + sel.first.row = m_cursor_selection.row; + sel.last = sel.first; + + sv->set_selected_range(m_cursor_selection.pane, sel); + } +} + +void xls_xml_context::end_element_worksheet_options() +{ + commit_split_pane(); +} + +void xls_xml_context::commit_split_pane() +{ + ss::iface::import_sheet_view* sv = mp_cur_sheet->get_sheet_view(); + if (!sv) + return; + + if (!m_split_pane.split()) + return; + + switch (m_split_pane.pane_state) + { + case ss::pane_state_t::split: + { + ss::address_t top_left_cell = m_split_pane.get_top_left_cell(); + + // NB: The term "split vertical" in Excel 2003 XML refers to the + // vertical split bar position which in this case corresponds with + // the "horizontal split" position of the set_split_pane() call, + // and vice versa. + sv->set_split_pane( + m_split_pane.split_vertical, m_split_pane.split_horizontal, + top_left_cell, m_split_pane.active_pane); + break; + } + case ss::pane_state_t::frozen: + { + ss::address_t top_left_cell = m_split_pane.get_top_left_cell(); + + // NB: Note for the split pane above also applies here. + ss::col_t visible_cols = m_split_pane.split_vertical; + ss::row_t visible_rows = m_split_pane.split_horizontal; + + sv->set_frozen_pane( + visible_cols, visible_rows, + top_left_cell, m_split_pane.active_pane); + break; + } + case ss::pane_state_t::frozen_split: + // not handled yet. + break; + case ss::pane_state_t::unspecified: + default: + ; + } + + m_split_pane.reset(); +} + +void xls_xml_context::commit_default_style() +{ + ss::iface::import_styles* styles = mp_factory->get_styles(); + if (!styles) + return; + + ss::iface::import_font_style* font_style = styles->start_font_style(); + ENSURE_INTERFACE(font_style, import_font_style); + + if (m_default_style) + { + const auto& font = m_default_style->font; + + if (!font.name.empty()) + font_style->set_name(font.name); + + if (font.size) + font_style->set_size(*font.size); + + if (font.underline) + font_style->set_underline(*font.underline); + + font_style->set_bold(font.bold); + font_style->set_italic(font.italic); + font_style->set_color(255, font.color.red, font.color.green, font.color.blue); + } + + std::size_t id = font_style->commit(); + assert(id == 0); + + ss::iface::import_fill_style* fill_style = styles->start_fill_style(); + ENSURE_INTERFACE(fill_style, import_fill_style); + + if (m_default_style) + { + if (m_default_style->fill.solid) + fill_style->set_pattern_type(ss::fill_pattern_t::solid); + + fill_style->set_fg_color( + 255, + m_default_style->fill.color.red, + m_default_style->fill.color.green, + m_default_style->fill.color.blue + ); + } + + id = fill_style->commit(); + assert(id == 0); + + auto* border_style = styles->start_border_style(); + ENSURE_INTERFACE(border_style, import_border_style); + + if (m_default_style && !m_default_style->borders.empty()) + { + for (const border_style_type& b : m_default_style->borders) + { + if (b.dir == ss::border_direction_t::unknown) + continue; + + if (b.style != ss::border_style_t::unknown) + border_style->set_style(b.dir, b.style); + + if (b.color) + border_style->set_color(b.dir, 255, b.color->red, b.color->green, b.color->blue); + } + } + + id = border_style->commit(); + assert(id == 0); + + auto* cell_protection = styles->start_cell_protection(); + ENSURE_INTERFACE(cell_protection, import_cell_protection); + + if (m_default_style) + { + const auto& cp = m_default_style->cell_protection; + cell_protection->set_locked(cp.locked); + cell_protection->set_formula_hidden(cp.hide_formula); + } + + id = cell_protection->commit(); + assert(id == 0); + + auto* number_format = styles->start_number_format(); + ENSURE_INTERFACE(number_format, import_number_format); + + if (m_default_style) + number_format->set_code(m_default_style->number_format); + + id = number_format->commit(); + assert(id == 0); + + auto* xf = styles->start_xf(ss::xf_category_t::cell); + ENSURE_INTERFACE(xf, import_xf); + + auto set_default_style = [this](ss::iface::import_xf* ixf) + { + bool apply_alignment = + m_default_style->text_alignment.hor != ss::hor_alignment_t::unknown || + m_default_style->text_alignment.ver != ss::ver_alignment_t::unknown || + m_default_style->text_alignment.wrap_text || m_default_style->text_alignment.shrink_to_fit; + + ixf->set_apply_alignment(apply_alignment); + ixf->set_horizontal_alignment(m_default_style->text_alignment.hor); + ixf->set_vertical_alignment(m_default_style->text_alignment.ver); + ixf->set_wrap_text(m_default_style->text_alignment.wrap_text); + ixf->set_shrink_to_fit(m_default_style->text_alignment.shrink_to_fit); + }; + + if (m_default_style) + set_default_style(xf); + + id = xf->commit(); + assert(id == 0); + + xf = styles->start_xf(ss::xf_category_t::cell_style); + ENSURE_INTERFACE(xf, import_xf); + + if (m_default_style && m_default_style->name == "Normal") + set_default_style(xf); + + id = xf->commit(); + assert(id == 0); + + auto* cell_style = styles->start_cell_style(); + ENSURE_INTERFACE(cell_style, import_cell_style); + + if (m_default_style && m_default_style->name == "Normal") + { + if (!m_default_style->name.empty()) + cell_style->set_name(m_default_style->name); + } + + cell_style->commit(); +} + +void xls_xml_context::commit_styles() +{ + if (m_styles.empty()) + return; + + ss::iface::import_styles* styles = mp_factory->get_styles(); + if (!styles) + return; + + // Build a map of cell style textural ID's to cell format (xf) numeric ID's. + + for (const std::unique_ptr<style_type>& style : m_styles) + { + auto category = style->name.empty() ? ss::xf_category_t::cell : ss::xf_category_t::cell_style; + + auto* xf = styles->start_xf(category); + ENSURE_INTERFACE(xf, import_xf); + + if (!style->parent_id.empty()) + { + auto it = m_style_map_named_style.find(style->parent_id); + if (it == m_style_map_named_style.end()) + { + std::ostringstream os; + os << "style '" << style->id << "' inherits from a parent style of '" << style->parent_id << "' but no record for the parent style exists"; + warn(os.str()); + } + else + xf->set_style_xf(it->second); + } + + auto* font_style = styles->start_font_style(); + ENSURE_INTERFACE(font_style, import_font_style); + + if (!style->font.name.empty()) + font_style->set_name(style->font.name); + + if (style->font.size) + font_style->set_size(*style->font.size); + + if (style->font.underline) + font_style->set_underline(*style->font.underline); + + font_style->set_bold(style->font.bold); + font_style->set_italic(style->font.italic); + font_style->set_color(255, + style->font.color.red, + style->font.color.green, + style->font.color.blue); + + size_t font_id = font_style->commit(); + + xf->set_font(font_id); + + auto* fill_style = styles->start_fill_style(); + ENSURE_INTERFACE(fill_style, import_fill_style); + + if (style->fill.solid) + { + // TODO : add support for fill types other than 'solid'. + fill_style->set_pattern_type(ss::fill_pattern_t::solid); + fill_style->set_fg_color(255, + style->fill.color.red, + style->fill.color.green, + style->fill.color.blue); + + size_t fill_id = fill_style->commit(); + xf->set_fill(fill_id); + } + + auto* protect = styles->start_cell_protection(); + ENSURE_INTERFACE(protect, import_cell_protection); + + protect->set_locked(style->cell_protection.locked); + protect->set_formula_hidden(style->cell_protection.hide_formula); + + std::size_t protect_id = protect->commit(); + xf->set_protection(protect_id); + + if (!style->borders.empty()) + { + styles->set_border_count(style->borders.size()); + + auto* border_style = styles->start_border_style(); + ENSURE_INTERFACE(border_style, import_border_style); + + for (const border_style_type& b : style->borders) + { + if (b.dir == ss::border_direction_t::unknown) + continue; + + if (b.style != ss::border_style_t::unknown) + border_style->set_style(b.dir, b.style); + + if (b.color) + border_style->set_color(b.dir, 255, b.color->red, b.color->green, b.color->blue); + } + + size_t border_id = border_style->commit(); + xf->set_border(border_id); + } + + bool apply_alignment = + style->text_alignment.hor != ss::hor_alignment_t::unknown || + style->text_alignment.ver != ss::ver_alignment_t::unknown || + style->text_alignment.wrap_text || style->text_alignment.shrink_to_fit; + + xf->set_apply_alignment(apply_alignment); + xf->set_horizontal_alignment(style->text_alignment.hor); + xf->set_vertical_alignment(style->text_alignment.ver); + xf->set_wrap_text(style->text_alignment.wrap_text); + xf->set_shrink_to_fit(style->text_alignment.shrink_to_fit); + + if (!style->number_format.empty()) + { + auto* number_format = styles->start_number_format(); + ENSURE_INTERFACE(number_format, import_number_format); + number_format->set_code(style->number_format); + size_t number_format_id = number_format->commit(); + xf->set_number_format(number_format_id); + } + + // TODO : handle text indent level. + + std::size_t xfid = xf->commit(); + + switch (category) + { + case ss::xf_category_t::cell: + { + m_style_map_cell.insert({style->id, xfid}); + break; + } + case ss::xf_category_t::cell_style: + { + m_style_map_named_style.insert({style->id, xfid}); + + // Push the named cell style record. + auto* cell_style = styles->start_cell_style(); + ENSURE_INTERFACE(cell_style, import_cell_style); + cell_style->set_name(style->name); + cell_style->set_xf(xfid); + cell_style->commit(); + + // Since we don't allow directly referencing a named cell style, + // we will create a regular cell style that references the named + // style instead. + auto* xf_cell = styles->start_xf(ss::xf_category_t::cell); + ENSURE_INTERFACE(xf_cell, import_xf); + xf_cell->set_style_xf(xfid); // reference the named style + xfid = xf_cell->commit(); + m_style_map_cell.insert({style->id, xfid}); + break; + } + case ss::xf_category_t::differential: + { + std::ostringstream os; + os << "differential cell format type is not supported"; + warn(os.str()); + break; + } + case ss::xf_category_t::unknown: + { + std::ostringstream os; + os << "cell format type is unknown"; + warn(os.str()); + break; + } + } + } +} + +void xls_xml_context::push_all_array_formulas() +{ + if (!mp_cur_sheet) + return; + + ss::iface::import_array_formula* array = mp_cur_sheet->get_array_formula(); + if (!array) + return; + + for (const array_formula_pair_type& pair : m_array_formulas) + { + const array_formula_type& af = *pair.second; + push_array_formula( + array, pair.first, af.formula, ss::formula_grammar_t::xls_xml, af.results); + } +} + +ss::iface::import_factory* xls_xml_context::get_import_factory() +{ + return mp_factory; +} + +ss::iface::import_sheet* xls_xml_context::get_import_sheet() +{ + return mp_cur_sheet; +} + +ss::address_t xls_xml_context::get_current_pos() const +{ + ss::address_t pos; + pos.row = m_cur_row; + pos.column = m_cur_col; + return pos; +} + +std::string_view xls_xml_context::pop_and_clear_formula() +{ + std::string_view f = m_cur_cell_formula; + m_cur_cell_formula = std::string_view{}; + return f; +} + +bool xls_xml_context::is_array_formula() const +{ + if (m_cur_array_range.first.column < 0 || m_cur_array_range.first.row < 0) + return false; + + if (m_cur_array_range.last.column < 0 || m_cur_array_range.last.row < 0) + return false; + + if (m_cur_array_range.first.column > m_cur_array_range.last.column || + m_cur_array_range.first.row > m_cur_array_range.last.row) + return false; + + return true; +} + +const ss::range_t& xls_xml_context::get_array_range() const +{ + return m_cur_array_range; +} + +xls_xml_context::array_formulas_type& xls_xml_context::get_array_formula_store() +{ + return m_array_formulas; +} + +void xls_xml_context::store_cell_formula(std::string_view formula, const formula_result& res) +{ + assert(m_cur_sheet < ss::sheet_t(m_cell_formulas.size())); + + cell_formula_type cf; + cf.pos = get_current_pos(); + cf.formula = formula; + cf.result = res; + std::deque<cell_formula_type>& store = m_cell_formulas[m_cur_sheet]; + store.push_back(std::move(cf)); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xls_xml_context.hpp b/src/liborcus/xls_xml_context.hpp new file mode 100644 index 0000000..24cb803 --- /dev/null +++ b/src/liborcus/xls_xml_context.hpp @@ -0,0 +1,334 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_XLS_XML_CONTEXT_HPP +#define INCLUDED_ORCUS_XLS_XML_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "orcus/spreadsheet/types.hpp" +#include "orcus/spreadsheet/view_types.hpp" +#include "orcus/string_pool.hpp" + +#include "formula_result.hpp" + +#include <string> +#include <unordered_map> +#include <list> +#include <deque> +#include <optional> + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_factory; +class import_sheet; +class import_sheet_properties; +class import_named_expression; +class import_array_formula; + +}} + +class xls_xml_context; + +/** + * Context for handling <Data> element scopes. + */ +class xls_xml_data_context : public xml_context_base +{ + struct format_type + { + std::optional<bool> bold; + std::optional<bool> italic; + std::optional<bool> underline; + std::optional<bool> strikethrough; + std::optional<bool> subscript; + std::optional<bool> superscript; + + std::optional<std::string_view> font_face; + std::optional<double> font_size; + std::optional<spreadsheet::color_rgb_t> color; + + void merge(const format_type& other); + bool formatted() const; + }; + + struct string_segment_type + { + std::string_view str; + format_type format; + bool formatted = false; + + string_segment_type(std::string_view _str); + }; + + enum cell_type { ct_unknown = 0, ct_string, ct_number, ct_datetime }; + + xls_xml_context& m_parent_cxt; + + cell_type m_cell_type; + std::vector<string_segment_type> m_cell_string; + std::vector<format_type> m_format_stack; + + format_type m_current_format; + + double m_cell_value; + date_time_t m_cell_datetime; + +public: + xls_xml_data_context(session_context& session_cxt, const tokens& tokens, xls_xml_context& parent_cxt); + virtual ~xls_xml_data_context() override; + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name) override; + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) override; + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& attrs) override; + virtual void characters(std::string_view str, bool transient) override; + virtual bool end_element(xmlns_id_t ns, xml_token_t name) override; + + /** + * Intendted to be called from the parent context instance, to reset its + * internal state before its use. + */ + void reset(); + +private: + + void start_element_data(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs); + void end_element_data(); + + bool handle_array_formula_result(); + void push_array_result( + range_formula_results& res, size_t row_offset, size_t col_offset); + + void push_formula_cell(std::string_view formula); + void store_array_formula_parent_cell(std::string_view formula); + void update_current_format(); +}; + +class xls_xml_context : public xml_context_base +{ + friend class xls_xml_data_context; + + struct cell_formula_type + { + spreadsheet::address_t pos; + std::string_view formula; + formula_result result; + }; + + struct array_formula_type + { + std::string_view formula; + range_formula_results results; + + array_formula_type(const spreadsheet::range_t& _range, std::string_view _formula); + }; + + struct border_style_type + { + spreadsheet::border_direction_t dir = spreadsheet::border_direction_t::unknown; + spreadsheet::border_style_t style = spreadsheet::border_style_t::unknown; + std::optional<spreadsheet::color_rgb_t> color; + }; + + struct font_style_type + { + std::string_view name; + std::string_view family; + std::optional<double> size; + std::optional<spreadsheet::underline_t> underline; + bool bold = false; + bool italic = false; + + spreadsheet::color_rgb_t color; + }; + + /** + * TODO: we only support solid fill for now. More fill types to be added + * later. + */ + struct fill_style_type + { + bool solid = false; + spreadsheet::color_rgb_t color; + }; + + struct text_alignment_type + { + spreadsheet::hor_alignment_t hor = spreadsheet::hor_alignment_t::unknown; + spreadsheet::ver_alignment_t ver = spreadsheet::ver_alignment_t::unknown; + int8_t indent = 0; + bool wrap_text = false; + bool shrink_to_fit = false; + }; + + struct cell_protection_type + { + bool locked = true; // NB: default is locked + bool hide_formula = false; + }; + + struct style_type + { + std::string_view id; + std::string_view parent_id; + std::string_view name; + + font_style_type font; + fill_style_type fill; + text_alignment_type text_alignment; + cell_protection_type cell_protection; + std::string_view number_format; + std::vector<border_style_type> borders; + }; + + struct named_exp + { + std::string_view name; + std::string_view expression; + spreadsheet::sheet_t scope; + + named_exp(std::string_view _name, std::string_view _expression, spreadsheet::sheet_t _scope); + }; + + struct selection + { + spreadsheet::sheet_pane_t pane; + spreadsheet::col_t col; + spreadsheet::row_t row; + spreadsheet::range_t range; + + selection(); + void reset(); + bool valid_cursor() const; + bool valid_range() const; + }; + + struct split_pane + { + spreadsheet::pane_state_t pane_state; + spreadsheet::sheet_pane_t active_pane; + double split_horizontal; + double split_vertical; + spreadsheet::row_t top_row_bottom_pane; + spreadsheet::col_t left_col_right_pane; + + split_pane(); + void reset(); + bool split() const; + spreadsheet::address_t get_top_left_cell() const; + }; + + struct table_properties + { + spreadsheet::address_t pos; // top-left position + + table_properties(); + void reset(); + }; + + using named_expressions_type = std::vector<named_exp>; + using styles_type = std::vector<std::unique_ptr<style_type>>; + using style_id_xf_map_type = std::unordered_map<std::string_view, std::size_t>; + using array_formula_pair_type = std::pair<spreadsheet::range_t, std::unique_ptr<array_formula_type>>; + using array_formulas_type = std::list<array_formula_pair_type>; + using cell_formulas_type = std::deque<std::deque<cell_formula_type>>; + +public: + xls_xml_context(session_context& session_cxt, const tokens& tokens, spreadsheet::iface::import_factory* factory); + virtual ~xls_xml_context(); + + virtual void declaration(const xml_declaration_t& decl) override; + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name) override; + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) override; + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) override; + virtual bool end_element(xmlns_id_t ns, xml_token_t name) override; + virtual void characters(std::string_view str, bool transient) override; + +private: + + void start_element_borders(const xml_token_attrs_t& attrs); + void start_element_border(const xml_token_attrs_t& attrs); + void start_element_number_format(const xml_token_attrs_t& attrs); + void start_element_cell(const xml_token_attrs_t& attrs); + void start_element_column(const xml_token_attrs_t& attrs); + void start_element_row(const xml_token_attrs_t& attrs); + void start_element_table(const xml_token_attrs_t& attrs); + void start_element_worksheet(const xml_token_attrs_t& attrs); + + void end_element_borders(); + void end_element_border(); + void end_element_number_format(); + void end_element_cell(); + void end_element_column(); + void end_element_row(); + void end_element_table(); + void end_element_worksheet(); + void end_element_workbook(); + void end_element_styles(); + void end_element_pane(); + void end_element_worksheet_options(); + + void commit_split_pane(); + void commit_default_style(); + void commit_styles(); + + void push_all_array_formulas(); + +private: + spreadsheet::iface::import_factory* get_import_factory(); + spreadsheet::iface::import_sheet* get_import_sheet(); + spreadsheet::address_t get_current_pos() const; + std::string_view pop_and_clear_formula(); + bool is_array_formula() const; + const spreadsheet::range_t& get_array_range() const; + array_formulas_type& get_array_formula_store(); + + void store_cell_formula(std::string_view formula, const formula_result& res); + +private: + spreadsheet::iface::import_factory* mp_factory; + spreadsheet::iface::import_sheet* mp_cur_sheet; + spreadsheet::iface::import_sheet_properties* mp_sheet_props; + + std::vector<spreadsheet::iface::import_named_expression*> m_sheet_named_exps; + + spreadsheet::sheet_t m_cur_sheet; + spreadsheet::row_t m_cur_row; + spreadsheet::col_t m_cur_col; + spreadsheet::col_t m_cur_prop_col; /// current column position for column properties. + spreadsheet::row_t m_cur_merge_down; + spreadsheet::col_t m_cur_merge_across; + spreadsheet::range_t m_cur_array_range; + std::string_view m_cur_cell_formula; + std::string_view m_cur_cell_style_id; + + cell_formulas_type m_cell_formulas; + array_formulas_type m_array_formulas; + named_expressions_type m_named_exps_global; + named_expressions_type m_named_exps_sheet; + selection m_cursor_selection; /// cursor selection in a single pane. + split_pane m_split_pane; + + std::unique_ptr<style_type> m_current_style; + std::unique_ptr<style_type> m_default_style; + styles_type m_styles; + table_properties m_table_props; + + style_id_xf_map_type m_style_map_cell; + style_id_xf_map_type m_style_map_named_style; + + xls_xml_data_context m_cc_data; +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xls_xml_detection_handler.cpp b/src/liborcus/xls_xml_detection_handler.cpp new file mode 100644 index 0000000..775cfb7 --- /dev/null +++ b/src/liborcus/xls_xml_detection_handler.cpp @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xls_xml_detection_handler.hpp" +#include "xls_xml_token_constants.hpp" +#include "xls_xml_namespace_types.hpp" +#include "xml_context_base.hpp" +#include "detection_result.hpp" + +namespace orcus { + +namespace { + +/** + * Try to parse the XML stream up to the 1st Worksheet element while + * checking its structure along the way. If the structure up to that element + * is correct, then we call it "detected". + */ +class xls_xml_detection_context : public xml_context_base +{ +public: + xls_xml_detection_context(session_context& session_cxt, const tokens& tokens) : + xml_context_base(session_cxt, tokens) {} + + virtual xml_context_base* create_child_context(xmlns_id_t, xml_token_t) + { + return nullptr; + } + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& /*attrs*/) + { + xml_token_pair_t parent = push_stack(ns, name); + if (ns == NS_xls_xml_ss) + { + switch (name) + { + case XML_Workbook: + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + break; + case XML_Styles: + case XML_Worksheet: + { + xml_element_expected(parent, NS_xls_xml_ss, XML_Workbook); + + // All good. Let's call it detected. + throw detection_result(true); + } + break; + case XML_Style: + xml_element_expected(parent, NS_xls_xml_ss, XML_Style); + break; + default: + ; + } + } + else if (ns == NS_xls_xml_o) + { + switch (name) + { + case XML_DocumentProperties: + case XML_OfficeDocumentSettings: + xml_element_expected(parent, NS_xls_xml_ss, XML_Workbook); + break; + default: + ; + } + } + else if (ns == NS_xls_xml_x) + { + switch (name) + { + case XML_ExcelWorkbook: + xml_element_expected(parent, NS_xls_xml_ss, XML_Workbook); + break; + default: + ; + } + } + } + + virtual bool end_element(xmlns_id_t ns, xml_token_t name) + { + return pop_stack(ns, name); + } + + virtual void characters(std::string_view, bool) + { + } + + virtual void end_child_context(xmlns_id_t, xml_token_t, xml_context_base*) + { + } +}; + +} + +xls_xml_detection_handler::xls_xml_detection_handler( + session_context& session_cxt, const tokens& t) : + xml_stream_handler(session_cxt, t, std::make_unique<xls_xml_detection_context>(session_cxt, t)) +{ +} + +xls_xml_detection_handler::~xls_xml_detection_handler() {} + +void xls_xml_detection_handler::start_document() {} +void xls_xml_detection_handler::end_document() {} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xls_xml_detection_handler.hpp b/src/liborcus/xls_xml_detection_handler.hpp new file mode 100644 index 0000000..e8fd57d --- /dev/null +++ b/src/liborcus/xls_xml_detection_handler.hpp @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_XLS_XML_DETECTION_HANDLER_HPP +#define ORCUS_XLS_XML_DETECTION_HANDLER_HPP + +#include "xml_stream_handler.hpp" + +namespace orcus { + +class tokens; +struct session_context; + +class xls_xml_detection_handler : public xml_stream_handler +{ +public: + xls_xml_detection_handler(session_context& session_cxt, const tokens& t); + virtual ~xls_xml_detection_handler(); + + virtual void start_document(); + virtual void end_document(); +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xls_xml_handler.cpp b/src/liborcus/xls_xml_handler.cpp new file mode 100644 index 0000000..5095b1e --- /dev/null +++ b/src/liborcus/xls_xml_handler.cpp @@ -0,0 +1,22 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xls_xml_handler.hpp" +#include "xls_xml_context.hpp" + +namespace orcus { + +xls_xml_handler::xls_xml_handler( + session_context& session_cxt, const tokens& t, spreadsheet::iface::import_factory* factory) : + xml_stream_handler(session_cxt, t, std::make_unique<xls_xml_context>(session_cxt, t, factory)) +{ +} + +xls_xml_handler::~xls_xml_handler() {} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xls_xml_handler.hpp b/src/liborcus/xls_xml_handler.hpp new file mode 100644 index 0000000..d9a454b --- /dev/null +++ b/src/liborcus/xls_xml_handler.hpp @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_XLS_XML_HANDLER_HPP +#define ORCUS_XLS_XML_HANDLER_HPP + +#include "xml_stream_handler.hpp" + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_factory; + +}} + +class tokens; +struct session_context; + +class xls_xml_handler : public xml_stream_handler +{ +public: + xls_xml_handler(session_context& session_cxt, const tokens& t, spreadsheet::iface::import_factory* factory); + virtual ~xls_xml_handler() override; +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xls_xml_namespace_types.cpp b/src/liborcus/xls_xml_namespace_types.cpp new file mode 100644 index 0000000..96ccf6d --- /dev/null +++ b/src/liborcus/xls_xml_namespace_types.cpp @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xls_xml_namespace_types.hpp" + +namespace orcus { + +const xmlns_id_t NS_xls_xml_ss = "urn:schemas-microsoft-com:office:spreadsheet"; +const xmlns_id_t NS_xls_xml_o ="urn:schemas-microsoft-com:office:office"; +const xmlns_id_t NS_xls_xml_x ="urn:schemas-microsoft-com:office:excel"; +const xmlns_id_t NS_xls_xml_html ="http://www.w3.org/TR/REC-html40"; + +namespace { + +xmlns_id_t xls_xml_ns[] = { + NS_xls_xml_ss, + NS_xls_xml_o, + NS_xls_xml_x, + NS_xls_xml_html, + nullptr +}; + +} + +const xmlns_id_t* NS_xls_xml_all = xls_xml_ns; + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xls_xml_namespace_types.hpp b/src/liborcus/xls_xml_namespace_types.hpp new file mode 100644 index 0000000..37de5b0 --- /dev/null +++ b/src/liborcus/xls_xml_namespace_types.hpp @@ -0,0 +1,28 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_XLS_XML_NAMESPACE_TYPES_HPP +#define ORCUS_XLS_XML_NAMESPACE_TYPES_HPP + +#include "orcus/types.hpp" + +namespace orcus { + +extern const xmlns_id_t NS_xls_xml_ss; +extern const xmlns_id_t NS_xls_xml_o; +extern const xmlns_id_t NS_xls_xml_x; +extern const xmlns_id_t NS_xls_xml_html; + +/** + * Null-terminated array of all xls xml namespaces. + */ +extern const xmlns_id_t* NS_xls_xml_all; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xls_xml_token_constants.hpp b/src/liborcus/xls_xml_token_constants.hpp new file mode 100644 index 0000000..9aca315 --- /dev/null +++ b/src/liborcus/xls_xml_token_constants.hpp @@ -0,0 +1,20 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_XLS_XML_TOKEN_CONSTANTS_HPP +#define ORCUS_XLS_XML_TOKEN_CONSTANTS_HPP + +#include "orcus/types.hpp" + +namespace orcus { + +#include "xls_xml_token_constants.inl" + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xls_xml_token_constants.inl b/src/liborcus/xls_xml_token_constants.inl new file mode 100644 index 0000000..902e2d5 --- /dev/null +++ b/src/liborcus/xls_xml_token_constants.inl @@ -0,0 +1,992 @@ +// This file has been auto-generated. Do not hand-edit this. + +const xml_token_t XML_AcceptLabelsInFormulas = 1; +const xml_token_t XML_Action = 2; +const xml_token_t XML_ActiveChart = 3; +const xml_token_t XML_ActiveCol = 4; +const xml_token_t XML_ActiveColumn = 5; +const xml_token_t XML_ActivePane = 6; +const xml_token_t XML_ActiveRow = 7; +const xml_token_t XML_ActiveRows = 8; +const xml_token_t XML_ActiveSheet = 9; +const xml_token_t XML_Aggregate = 10; +const xml_token_t XML_AlertVersion = 11; +const xml_token_t XML_Alignment = 12; +const xml_token_t XML_AllItemName = 13; +const xml_token_t XML_AllowDeleteCols = 14; +const xml_token_t XML_AllowDeleteRows = 15; +const xml_token_t XML_AllowFilter = 16; +const xml_token_t XML_AllowFormatCells = 17; +const xml_token_t XML_AllowInsertCols = 18; +const xml_token_t XML_AllowInsertHyperlinks = 19; +const xml_token_t XML_AllowInsertRows = 20; +const xml_token_t XML_AllowPNG = 21; +const xml_token_t XML_AllowSizeCols = 22; +const xml_token_t XML_AllowSizeRows = 23; +const xml_token_t XML_AllowSort = 24; +const xml_token_t XML_AllowUsePivotTables = 25; +const xml_token_t XML_AlternateMethod = 26; +const xml_token_t XML_AppName = 27; +const xml_token_t XML_Append = 28; +const xml_token_t XML_ApplyAutomaticOutlineStyles = 29; +const xml_token_t XML_Area = 30; +const xml_token_t XML_ArrayRange = 31; +const xml_token_t XML_Async = 32; +const xml_token_t XML_Attribute = 33; +const xml_token_t XML_AttributeType = 34; +const xml_token_t XML_Authentication = 35; +const xml_token_t XML_Author = 36; +const xml_token_t XML_AutoFilter = 37; +const xml_token_t XML_AutoFilterAnd = 38; +const xml_token_t XML_AutoFilterColumn = 39; +const xml_token_t XML_AutoFilterCondition = 40; +const xml_token_t XML_AutoFilterOr = 41; +const xml_token_t XML_AutoFitHeight = 42; +const xml_token_t XML_AutoFitWidth = 43; +const xml_token_t XML_AutoFormatAlignment = 44; +const xml_token_t XML_AutoFormatBorder = 45; +const xml_token_t XML_AutoFormatFont = 46; +const xml_token_t XML_AutoFormatName = 47; +const xml_token_t XML_AutoFormatNumber = 48; +const xml_token_t XML_AutoFormatPattern = 49; +const xml_token_t XML_AutoFormatWidth = 50; +const xml_token_t XML_AutoRepublish = 51; +const xml_token_t XML_AutoShowCount = 52; +const xml_token_t XML_AutoShowField = 53; +const xml_token_t XML_AutoShowRange = 54; +const xml_token_t XML_AutoShowType = 55; +const xml_token_t XML_AutoSortField = 56; +const xml_token_t XML_AutoSortOrder = 57; +const xml_token_t XML_B = 58; +const xml_token_t XML_BackgroundQuery = 59; +const xml_token_t XML_BaseField = 60; +const xml_token_t XML_BaseItem = 61; +const xml_token_t XML_Basic = 62; +const xml_token_t XML_Behavior = 63; +const xml_token_t XML_Binding = 64; +const xml_token_t XML_BlackAndWhite = 65; +const xml_token_t XML_BlankLineAfterItems = 66; +const xml_token_t XML_BlockTotal = 67; +const xml_token_t XML_Bold = 68; +const xml_token_t XML_Boolean = 69; +const xml_token_t XML_Border = 70; +const xml_token_t XML_Borders = 71; +const xml_token_t XML_Bottom = 72; +const xml_token_t XML_BoundField = 73; +const xml_token_t XML_Bytes = 74; +const xml_token_t XML_CacheDetails = 75; +const xml_token_t XML_CacheFile = 76; +const xml_token_t XML_CacheIndex = 77; +const xml_token_t XML_CachePosition = 78; +const xml_token_t XML_CalculatedMember = 79; +const xml_token_t XML_Calculation = 80; +const xml_token_t XML_CantGetUniqueItems = 81; +const xml_token_t XML_Caption = 82; +const xml_token_t XML_CaptionAlignment = 83; +const xml_token_t XML_CaseSensitive = 84; +const xml_token_t XML_Category = 85; +const xml_token_t XML_Cell = 86; +const xml_token_t XML_CellRangeList = 87; +const xml_token_t XML_CellsExpanded = 88; +const xml_token_t XML_CellsExpandedSeqNum = 89; +const xml_token_t XML_CellsNotExpanded = 90; +const xml_token_t XML_CenterHorizontal = 91; +const xml_token_t XML_CenterVertical = 92; +const xml_token_t XML_Cf = 93; +const xml_token_t XML_CharSet = 94; +const xml_token_t XML_Characters = 95; +const xml_token_t XML_CharactersWithSpaces = 96; +const xml_token_t XML_ClientParameter = 97; +const xml_token_t XML_ClientParameterBinding = 98; +const xml_token_t XML_ClientParameterBindings = 99; +const xml_token_t XML_ClientParameterValue = 100; +const xml_token_t XML_Clipped = 101; +const xml_token_t XML_CodeName = 102; +const xml_token_t XML_Col1 = 103; +const xml_token_t XML_Col10 = 104; +const xml_token_t XML_Col11 = 105; +const xml_token_t XML_Col12 = 106; +const xml_token_t XML_Col13 = 107; +const xml_token_t XML_Col14 = 108; +const xml_token_t XML_Col15 = 109; +const xml_token_t XML_Col16 = 110; +const xml_token_t XML_Col17 = 111; +const xml_token_t XML_Col18 = 112; +const xml_token_t XML_Col19 = 113; +const xml_token_t XML_Col2 = 114; +const xml_token_t XML_Col20 = 115; +const xml_token_t XML_Col3 = 116; +const xml_token_t XML_Col4 = 117; +const xml_token_t XML_Col5 = 118; +const xml_token_t XML_Col6 = 119; +const xml_token_t XML_Col7 = 120; +const xml_token_t XML_Col8 = 121; +const xml_token_t XML_Col9 = 122; +const xml_token_t XML_ColBreak = 123; +const xml_token_t XML_ColBreaks = 124; +const xml_token_t XML_ColFirst = 125; +const xml_token_t XML_ColLast = 126; +const xml_token_t XML_Color = 127; +const xml_token_t XML_Column = 128; +const xml_token_t XML_ColumnInfo = 129; +const xml_token_t XML_ColumnInputCell = 130; +const xml_token_t XML_ColumnName = 131; +const xml_token_t XML_ComboHide = 132; +const xml_token_t XML_Comma = 133; +const xml_token_t XML_CommandText = 134; +const xml_token_t XML_CommandTextOrignal = 135; +const xml_token_t XML_CommandType = 136; +const xml_token_t XML_Comment = 137; +const xml_token_t XML_CommentsLayout = 138; +const xml_token_t XML_Company = 139; +const xml_token_t XML_ComponentOptions = 140; +const xml_token_t XML_Condition = 141; +const xml_token_t XML_ConditionalFormatting = 142; +const xml_token_t XML_Connection = 143; +const xml_token_t XML_ConnectionInfo = 144; +const xml_token_t XML_ConnectionString = 145; +const xml_token_t XML_Consecutive = 146; +const xml_token_t XML_ConsolidationReference = 147; +const xml_token_t XML_Count = 148; +const xml_token_t XML_CountOfSameItems = 149; +const xml_token_t XML_CreateBackup = 150; +const xml_token_t XML_Created = 151; +const xml_token_t XML_Credential = 152; +const xml_token_t XML_CredentialBinding = 153; +const xml_token_t XML_CredentialValue = 154; +const xml_token_t XML_Crn = 155; +const xml_token_t XML_CubeField = 156; +const xml_token_t XML_CubeSource = 157; +const xml_token_t XML_CurrentPage = 158; +const xml_token_t XML_Custom = 159; +const xml_token_t XML_CustomDocumentProperties = 160; +const xml_token_t XML_Data = 161; +const xml_token_t XML_DataAxisEmpty = 162; +const xml_token_t XML_DataField = 163; +const xml_token_t XML_DataMember = 164; +const xml_token_t XML_DataSource = 165; +const xml_token_t XML_DataTable = 166; +const xml_token_t XML_DataType = 167; +const xml_token_t XML_DataValidation = 168; +const xml_token_t XML_DataValueEditing = 169; +const xml_token_t XML_Date1904 = 170; +const xml_token_t XML_Decimal = 171; +const xml_token_t XML_DefaultColumnWidth = 172; +const xml_token_t XML_DefaultItem = 173; +const xml_token_t XML_DefaultRowHeight = 174; +const xml_token_t XML_DefaultValue = 175; +const xml_token_t XML_DefaultVersion = 176; +const xml_token_t XML_DeletedTitle = 177; +const xml_token_t XML_Delimiters = 178; +const xml_token_t XML_Descending = 179; +const xml_token_t XML_Description = 180; +const xml_token_t XML_DetailFormat = 181; +const xml_token_t XML_DetailMaxHeight = 182; +const xml_token_t XML_DetailMaxWidth = 183; +const xml_token_t XML_DetailRowHeight = 184; +const xml_token_t XML_DetailSortOrder = 185; +const xml_token_t XML_DetailWidth = 186; +const xml_token_t XML_Dimension = 187; +const xml_token_t XML_DisableDateRecognition = 188; +const xml_token_t XML_DisableDrillDown = 189; +const xml_token_t XML_DisableEdit = 190; +const xml_token_t XML_DisableFieldDialog = 191; +const xml_token_t XML_DisableRefresh = 192; +const xml_token_t XML_DisableWizard = 193; +const xml_token_t XML_DisplayDrawingObjects = 194; +const xml_token_t XML_DisplayEmptyMembers = 195; +const xml_token_t XML_DisplayErrorString = 196; +const xml_token_t XML_DisplayFieldList = 197; +const xml_token_t XML_DisplayFormulas = 198; +const xml_token_t XML_DisplayIn = 199; +const xml_token_t XML_DisplayInkNotes = 200; +const xml_token_t XML_DisplayPageBreak = 201; +const xml_token_t XML_DisplayRightToLeft = 202; +const xml_token_t XML_DivID = 203; +const xml_token_t XML_DoNotCalculateBeforeSave = 204; +const xml_token_t XML_DoNotDisplayColHeaders = 205; +const xml_token_t XML_DoNotDisplayGridlines = 206; +const xml_token_t XML_DoNotDisplayHeadings = 207; +const xml_token_t XML_DoNotDisplayOutline = 208; +const xml_token_t XML_DoNotDisplayRowHeaders = 209; +const xml_token_t XML_DoNotDisplayZeros = 210; +const xml_token_t XML_DoNotJoinDelimiters = 211; +const xml_token_t XML_DoNotPersist = 212; +const xml_token_t XML_DoNotPersistSort = 213; +const xml_token_t XML_DoNotPersstAF = 214; +const xml_token_t XML_DoNotPromptForFile = 215; +const xml_token_t XML_DoNotSaveLinkValues = 216; +const xml_token_t XML_DocumentProperties = 217; +const xml_token_t XML_DontShowInFieldList = 218; +const xml_token_t XML_DownloadComponents = 219; +const xml_token_t XML_DraftQuality = 220; +const xml_token_t XML_DrawAspect = 221; +const xml_token_t XML_DrilledLevel = 222; +const xml_token_t XML_DrilledMember = 223; +const xml_token_t XML_EditWebPage = 224; +const xml_token_t XML_ElementType = 225; +const xml_token_t XML_EmbedSaveSmartTags = 226; +const xml_token_t XML_EnableMultiplePageItems = 227; +const xml_token_t XML_EnableRedirections = 228; +const xml_token_t XML_EnableSelection = 229; +const xml_token_t XML_Encode = 230; +const xml_token_t XML_EntirePage = 231; +const xml_token_t XML_Entry = 232; +const xml_token_t XML_Error = 233; +const xml_token_t XML_ErrorHide = 234; +const xml_token_t XML_ErrorMessage = 235; +const xml_token_t XML_ErrorString = 236; +const xml_token_t XML_ErrorStyle = 237; +const xml_token_t XML_ErrorTitle = 238; +const xml_token_t XML_ExcelName = 239; +const xml_token_t XML_ExcelType = 240; +const xml_token_t XML_ExcelWorkbook = 241; +const xml_token_t XML_ExcelWorksheetType = 242; +const xml_token_t XML_Expanded = 243; +const xml_token_t XML_ExpandedColumnCount = 244; +const xml_token_t XML_ExpandedRowCount = 245; +const xml_token_t XML_ExternName = 246; +const xml_token_t XML_ExtraLeftColumns = 247; +const xml_token_t XML_ExtraRightColumns = 248; +const xml_token_t XML_Face = 249; +const xml_token_t XML_Family = 250; +const xml_token_t XML_Field = 251; +const xml_token_t XML_FieldLabelFormat = 252; +const xml_token_t XML_FieldListBottom = 253; +const xml_token_t XML_FieldListLeft = 254; +const xml_token_t XML_FieldListRight = 255; +const xml_token_t XML_FieldListTop = 256; +const xml_token_t XML_FieldStart = 257; +const xml_token_t XML_FieldType = 258; +const xml_token_t XML_File = 259; +const xml_token_t XML_FileName = 260; +const xml_token_t XML_FillDown = 261; +const xml_token_t XML_Filled = 262; +const xml_token_t XML_FilterCaption = 263; +const xml_token_t XML_FilterMember = 264; +const xml_token_t XML_FilterOn = 265; +const xml_token_t XML_FirstVisibleSheet = 266; +const xml_token_t XML_FitHeight = 267; +const xml_token_t XML_FitToPage = 268; +const xml_token_t XML_FitWidth = 269; +const xml_token_t XML_Font = 270; +const xml_token_t XML_FontName = 271; +const xml_token_t XML_Footer = 272; +const xml_token_t XML_Format = 273; +const xml_token_t XML_FormatSettings = 274; +const xml_token_t XML_FormatType = 275; +const xml_token_t XML_Formula = 276; +const xml_token_t XML_FormulaIndex = 277; +const xml_token_t XML_FormulaV10 = 278; +const xml_token_t XML_FreezePanes = 279; +const xml_token_t XML_FrozenNoSplit = 280; +const xml_token_t XML_FullColumns = 281; +const xml_token_t XML_FullRows = 282; +const xml_token_t XML_Function = 283; +const xml_token_t XML_FunctionGroup = 284; +const xml_token_t XML_FunctionGroupIndex = 285; +const xml_token_t XML_FuturePersist = 286; +const xml_token_t XML_FutureVer = 287; +const xml_token_t XML_GrandTotalString = 288; +const xml_token_t XML_GridlineColor = 289; +const xml_token_t XML_GridlineColorIndex = 290; +const xml_token_t XML_Gridlines = 291; +const xml_token_t XML_GroupBy = 292; +const xml_token_t XML_GroupDefinition = 293; +const xml_token_t XML_GroupEnd = 294; +const xml_token_t XML_GroupEndAuto = 295; +const xml_token_t XML_GroupLevel = 296; +const xml_token_t XML_GroupMember = 297; +const xml_token_t XML_GroupNumber = 298; +const xml_token_t XML_GroupStart = 299; +const xml_token_t XML_GroupStartAuto = 300; +const xml_token_t XML_GroupType = 301; +const xml_token_t XML_GroupedWidth = 302; +const xml_token_t XML_Guid = 303; +const xml_token_t XML_HRef = 304; +const xml_token_t XML_HRefScreenTip = 305; +const xml_token_t XML_HTMLFormat = 306; +const xml_token_t XML_HTMLTables = 307; +const xml_token_t XML_HasNoAutoFormat = 308; +const xml_token_t XML_HasNoRecords = 309; +const xml_token_t XML_Header = 310; +const xml_token_t XML_HeaderRange = 311; +const xml_token_t XML_HeaderRow = 312; +const xml_token_t XML_Height = 313; +const xml_token_t XML_Hidden = 314; +const xml_token_t XML_HideDetail = 315; +const xml_token_t XML_HideDropDowns = 316; +const xml_token_t XML_HideFormula = 317; +const xml_token_t XML_HideHorizontalScrollBar = 318; +const xml_token_t XML_HideInactiveListBorder = 319; +const xml_token_t XML_HideOfficeLogo = 320; +const xml_token_t XML_HidePivotTableFieldList = 321; +const xml_token_t XML_HideTotalsAnnotation = 322; +const xml_token_t XML_HideVerticalScrollBar = 323; +const xml_token_t XML_HideWorkbookTabs = 324; +const xml_token_t XML_Horizontal = 325; +const xml_token_t XML_HorizontalResolution = 326; +const xml_token_t XML_Href = 327; +const xml_token_t XML_HtmlType = 328; +const xml_token_t XML_HyperlinkBase = 329; +const xml_token_t XML_I = 330; +const xml_token_t XML_ID = 331; +const xml_token_t XML_IMEMode = 332; +const xml_token_t XML_Id = 333; +const xml_token_t XML_IdWrapped = 334; +const xml_token_t XML_If = 335; +const xml_token_t XML_ImmediateItemsOnDrop = 336; +const xml_token_t XML_Indent = 337; +const xml_token_t XML_Index = 338; +const xml_token_t XML_IndividualCellBorders = 339; +const xml_token_t XML_InputHide = 340; +const xml_token_t XML_InputMessage = 341; +const xml_token_t XML_InputTitle = 342; +const xml_token_t XML_InsertEntireRows = 343; +const xml_token_t XML_InstanceShape = 344; +const xml_token_t XML_Interior = 345; +const xml_token_t XML_IntlMacro = 346; +const xml_token_t XML_Invalid = 347; +const xml_token_t XML_InvertedColumnMember = 348; +const xml_token_t XML_InvertedRowMember = 349; +const xml_token_t XML_IsGroupLevel = 350; +const xml_token_t XML_IsMemberProperty = 351; +const xml_token_t XML_IsNotFiltered = 352; +const xml_token_t XML_Italic = 353; +const xml_token_t XML_Item = 354; +const xml_token_t XML_ItemType = 355; +const xml_token_t XML_Iteration = 356; +const xml_token_t XML_KeyboardShortcut = 357; +const xml_token_t XML_Keywords = 358; +const xml_token_t XML_Label = 359; +const xml_token_t XML_LastAuthor = 360; +const xml_token_t XML_LastPrinted = 361; +const xml_token_t XML_LastSaved = 362; +const xml_token_t XML_Layout = 363; +const xml_token_t XML_LayoutForm = 364; +const xml_token_t XML_LayoutPageBreak = 365; +const xml_token_t XML_LayoutSubtotalLocation = 366; +const xml_token_t XML_LeafColumnMember = 367; +const xml_token_t XML_LeafRowMember = 368; +const xml_token_t XML_Left = 369; +const xml_token_t XML_LeftCell = 370; +const xml_token_t XML_LeftColumnRightPane = 371; +const xml_token_t XML_LeftColumnVisible = 372; +const xml_token_t XML_LeftToRight = 373; +const xml_token_t XML_LengthLevelUniqueName = 374; +const xml_token_t XML_Level = 375; +const xml_token_t XML_LineStyle = 376; +const xml_token_t XML_Lines = 377; +const xml_token_t XML_LoadMode = 378; +const xml_token_t XML_LocalConnection = 379; +const xml_token_t XML_Location = 380; +const xml_token_t XML_LocationOfComponents = 381; +const xml_token_t XML_Macro = 382; +const xml_token_t XML_MainFile = 383; +const xml_token_t XML_Maintain = 384; +const xml_token_t XML_MajorVersion = 385; +const xml_token_t XML_Manager = 386; +const xml_token_t XML_Map = 387; +const xml_token_t XML_MapChildItems = 388; +const xml_token_t XML_MapID = 389; +const xml_token_t XML_MapInfo = 390; +const xml_token_t XML_Mapdata = 391; +const xml_token_t XML_Margin = 392; +const xml_token_t XML_Max = 393; +const xml_token_t XML_MaxChange = 394; +const xml_token_t XML_MaxHeight = 395; +const xml_token_t XML_MaxIterations = 396; +const xml_token_t XML_MaxWidth = 397; +const xml_token_t XML_Measure = 398; +const xml_token_t XML_Member = 399; +const xml_token_t XML_MemberExpand = 400; +const xml_token_t XML_MemberFormat = 401; +const xml_token_t XML_MemberName = 402; +const xml_token_t XML_MemberPropertiesOrder = 403; +const xml_token_t XML_MemberProperty = 404; +const xml_token_t XML_MemberPropertyParent = 405; +const xml_token_t XML_MergeAcross = 406; +const xml_token_t XML_MergeDown = 407; +const xml_token_t XML_MergeLabels = 408; +const xml_token_t XML_Min = 409; +const xml_token_t XML_MinorVersion = 410; +const xml_token_t XML_Missing = 411; +const xml_token_t XML_MissingItemsLimit = 412; +const xml_token_t XML_Moper = 413; +const xml_token_t XML_MoveAfterReturn = 414; +const xml_token_t XML_Name = 415; +const xml_token_t XML_NamedCell = 416; +const xml_token_t XML_NamedRange = 417; +const xml_token_t XML_Names = 418; +const xml_token_t XML_Namespace = 419; +const xml_token_t XML_NewAsync = 420; +const xml_token_t XML_NewItemsHidden = 421; +const xml_token_t XML_NextId = 422; +const xml_token_t XML_NextSheetNumber = 423; +const xml_token_t XML_NoAutoFit = 424; +const xml_token_t XML_NoAutoFormatWidth = 425; +const xml_token_t XML_NoAutoPage = 426; +const xml_token_t XML_NoAutoRecover = 427; +const xml_token_t XML_NoAutofit = 428; +const xml_token_t XML_NoColumnGrand = 429; +const xml_token_t XML_NoDetailAutoFit = 430; +const xml_token_t XML_NoDisplayNullString = 431; +const xml_token_t XML_NoDragToColumn = 432; +const xml_token_t XML_NoDragToData = 433; +const xml_token_t XML_NoDragToHide = 434; +const xml_token_t XML_NoDragToPage = 435; +const xml_token_t XML_NoDragToRow = 436; +const xml_token_t XML_NoInserts = 437; +const xml_token_t XML_NoPreserveFormatting = 438; +const xml_token_t XML_NoPrintRepeatItems = 439; +const xml_token_t XML_NoPrinterInfo = 440; +const xml_token_t XML_NoRefreshCache = 441; +const xml_token_t XML_NoRowGrand = 442; +const xml_token_t XML_NoSaveData = 443; +const xml_token_t XML_NoSummaryColumnsRightDetail = 444; +const xml_token_t XML_NoSummaryRowsBelowDetail = 445; +const xml_token_t XML_NoTextToColumns = 446; +const xml_token_t XML_NoTitles = 447; +const xml_token_t XML_NoToggleDataHeader = 448; +const xml_token_t XML_NoViewCalculatedMembers = 449; +const xml_token_t XML_NonDefaultName = 450; +const xml_token_t XML_NotInverted = 451; +const xml_token_t XML_NotVisible = 452; +const xml_token_t XML_NullString = 453; +const xml_token_t XML_Number = 454; +const xml_token_t XML_NumberFormat = 455; +const xml_token_t XML_NumberOfCopies = 456; +const xml_token_t XML_OLEObject = 457; +const xml_token_t XML_OWCVersion = 458; +const xml_token_t XML_ObjectID = 459; +const xml_token_t XML_OfficeDocumentSettings = 460; +const xml_token_t XML_OleLink = 461; +const xml_token_t XML_Operator = 462; +const xml_token_t XML_OptimizeCache = 463; +const xml_token_t XML_Orientation = 464; +const xml_token_t XML_Outline = 465; +const xml_token_t XML_OverwriteCells = 466; +const xml_token_t XML_PLCaption = 467; +const xml_token_t XML_PLDataOrientation = 468; +const xml_token_t XML_PLExport = 469; +const xml_token_t XML_PLGroupType = 470; +const xml_token_t XML_PLName = 471; +const xml_token_t XML_PLPivotField = 472; +const xml_token_t XML_PLPosition = 473; +const xml_token_t XML_PLSubtotal = 474; +const xml_token_t XML_PLTPivotItem = 475; +const xml_token_t XML_PLTotal = 476; +const xml_token_t XML_PTFormat = 477; +const xml_token_t XML_PTFormula = 478; +const xml_token_t XML_PTLineItem = 479; +const xml_token_t XML_PTLineItems = 480; +const xml_token_t XML_PTPivotData = 481; +const xml_token_t XML_PTRule = 482; +const xml_token_t XML_PTSource = 483; +const xml_token_t XML_PageBreakZoom = 484; +const xml_token_t XML_PageBreaks = 485; +const xml_token_t XML_PageFieldOrder = 486; +const xml_token_t XML_PageFieldStyle = 487; +const xml_token_t XML_PageFieldWrapCount = 488; +const xml_token_t XML_PageMargins = 489; +const xml_token_t XML_PageSetup = 490; +const xml_token_t XML_Pages = 491; +const xml_token_t XML_Pane = 492; +const xml_token_t XML_Panes = 493; +const xml_token_t XML_PaperSizeIndex = 494; +const xml_token_t XML_Paragraphs = 495; +const xml_token_t XML_Parameter = 496; +const xml_token_t XML_ParameterType = 497; +const xml_token_t XML_ParameterValue = 498; +const xml_token_t XML_Parent = 499; +const xml_token_t XML_ParentField = 500; +const xml_token_t XML_ParentIsOther = 501; +const xml_token_t XML_ParentName = 502; +const xml_token_t XML_ParentUniqueName = 503; +const xml_token_t XML_ParseFormulaAsV10 = 504; +const xml_token_t XML_ParseRuleAsV10 = 505; +const xml_token_t XML_PasteFormula = 506; +const xml_token_t XML_PasteRefersTo = 507; +const xml_token_t XML_Path = 508; +const xml_token_t XML_Pattern = 509; +const xml_token_t XML_PatternColor = 510; +const xml_token_t XML_PivotAxis = 511; +const xml_token_t XML_PivotCache = 512; +const xml_token_t XML_PivotField = 513; +const xml_token_t XML_PivotItem = 514; +const xml_token_t XML_PivotTable = 515; +const xml_token_t XML_PivotView = 516; +const xml_token_t XML_Position = 517; +const xml_token_t XML_PrecisionAsDisplayed = 518; +const xml_token_t XML_PresentationFormat = 519; +const xml_token_t XML_Print = 520; +const xml_token_t XML_PrintErrors = 521; +const xml_token_t XML_PrintSetTitles = 522; +const xml_token_t XML_ProgID = 523; +const xml_token_t XML_PromptString = 524; +const xml_token_t XML_ProtectContents = 525; +const xml_token_t XML_ProtectObjects = 526; +const xml_token_t XML_ProtectScenarios = 527; +const xml_token_t XML_ProtectStructure = 528; +const xml_token_t XML_ProtectWindows = 529; +const xml_token_t XML_Protected = 530; +const xml_token_t XML_Protection = 531; +const xml_token_t XML_Proxy = 532; +const xml_token_t XML_PublishObject = 533; +const xml_token_t XML_PublishObjects = 534; +const xml_token_t XML_Purpose = 535; +const xml_token_t XML_QTSource = 536; +const xml_token_t XML_Qualifier = 537; +const xml_token_t XML_Query97 = 538; +const xml_token_t XML_QuerySource = 539; +const xml_token_t XML_QueryTable = 540; +const xml_token_t XML_QueryType = 541; +const xml_token_t XML_Range = 542; +const xml_token_t XML_RangeSelection = 543; +const xml_token_t XML_ReadOnly = 544; +const xml_token_t XML_ReadingOrder = 545; +const xml_token_t XML_RefModeR1C1 = 546; +const xml_token_t XML_Reference = 547; +const xml_token_t XML_RefersTo = 548; +const xml_token_t XML_RefreshDate = 549; +const xml_token_t XML_RefreshDateCopy = 550; +const xml_token_t XML_RefreshInfo = 551; +const xml_token_t XML_RefreshName = 552; +const xml_token_t XML_RefreshOnChange = 553; +const xml_token_t XML_RefreshOnFileOpen = 554; +const xml_token_t XML_RefreshTimeSpan = 555; +const xml_token_t XML_RefreshedInXl9 = 556; +const xml_token_t XML_Resource = 557; +const xml_token_t XML_Revision = 558; +const xml_token_t XML_Right = 559; +const xml_token_t XML_RightToLeft = 560; +const xml_token_t XML_RobustConnect = 561; +const xml_token_t XML_RootElement = 562; +const xml_token_t XML_Rotate = 563; +const xml_token_t XML_Rotation = 564; +const xml_token_t XML_Row = 565; +const xml_token_t XML_RowBreak = 566; +const xml_token_t XML_RowBreaks = 567; +const xml_token_t XML_RowColHeadings = 568; +const xml_token_t XML_RowInputCell = 569; +const xml_token_t XML_RowLast = 570; +const xml_token_t XML_RowNumbers = 571; +const xml_token_t XML_Rule = 572; +const xml_token_t XML_RuleType = 573; +const xml_token_t XML_RuleV10 = 574; +const xml_token_t XML_S = 575; +const xml_token_t XML_SOAPAction = 576; +const xml_token_t XML_SQLType = 577; +const xml_token_t XML_Scale = 578; +const xml_token_t XML_Schema = 579; +const xml_token_t XML_SchemaID = 580; +const xml_token_t XML_SchemaRef = 581; +const xml_token_t XML_Selected = 582; +const xml_token_t XML_SelectedSheets = 583; +const xml_token_t XML_Selection = 584; +const xml_token_t XML_SelectionNamespaces = 585; +const xml_token_t XML_SemiColon = 586; +const xml_token_t XML_SeqNum = 587; +const xml_token_t XML_Sequence = 588; +const xml_token_t XML_ServerBased = 589; +const xml_token_t XML_ServerSortOrder = 590; +const xml_token_t XML_Set = 591; +const xml_token_t XML_Shadow = 592; +const xml_token_t XML_ShapeID = 593; +const xml_token_t XML_SheetIndex = 594; +const xml_token_t XML_SheetName = 595; +const xml_token_t XML_ShowAllItems = 596; +const xml_token_t XML_ShowAlways = 597; +const xml_token_t XML_ShowCellBackgroundFromOLAP = 598; +const xml_token_t XML_ShowImportExportValidationErrors = 599; +const xml_token_t XML_ShowPageBreakZoom = 600; +const xml_token_t XML_ShowPageMultipleItemLabel = 601; +const xml_token_t XML_ShowTotals = 602; +const xml_token_t XML_ShrinkToFit = 603; +const xml_token_t XML_Size = 604; +const xml_token_t XML_SmallGrid = 605; +const xml_token_t XML_SmartTagType = 606; +const xml_token_t XML_SmartTags = 607; +const xml_token_t XML_SolveOrder = 608; +const xml_token_t XML_Sort = 609; +const xml_token_t XML_SortKey = 610; +const xml_token_t XML_SortOrder = 611; +const xml_token_t XML_Sorting = 612; +const xml_token_t XML_Source = 613; +const xml_token_t XML_SourceConnectionFile = 614; +const xml_token_t XML_SourceConsolidation = 615; +const xml_token_t XML_SourceDataFile = 616; +const xml_token_t XML_SourceHierarchy = 617; +const xml_token_t XML_SourceHierarchyLevel = 618; +const xml_token_t XML_SourceName = 619; +const xml_token_t XML_SourceType = 620; +const xml_token_t XML_Space = 621; +const xml_token_t XML_SpaceAbove = 622; +const xml_token_t XML_SpaceBelow = 623; +const xml_token_t XML_Span = 624; +const xml_token_t XML_SplitHorizontal = 625; +const xml_token_t XML_SplitVertical = 626; +const xml_token_t XML_SpreadsheetAutoFit = 627; +const xml_token_t XML_StandardWidth = 628; +const xml_token_t XML_StartPageNumber = 629; +const xml_token_t XML_StartRow = 630; +const xml_token_t XML_StrikeThrough = 631; +const xml_token_t XML_Style = 632; +const xml_token_t XML_StyleID = 633; +const xml_token_t XML_Styles = 634; +const xml_token_t XML_Sub = 635; +const xml_token_t XML_SubType = 636; +const xml_token_t XML_Subject = 637; +const xml_token_t XML_Subtotal = 638; +const xml_token_t XML_SubtotalFormat = 639; +const xml_token_t XML_SubtotalHiddenPageItems = 640; +const xml_token_t XML_SubtotalName = 641; +const xml_token_t XML_Sup = 642; +const xml_token_t XML_SupBook = 643; +const xml_token_t XML_Synchronous = 644; +const xml_token_t XML_Tab = 645; +const xml_token_t XML_TabColorIndex = 646; +const xml_token_t XML_TabRatio = 647; +const xml_token_t XML_Table = 648; +const xml_token_t XML_TableStyle = 649; +const xml_token_t XML_Tag = 650; +const xml_token_t XML_Text = 651; +const xml_token_t XML_TextQualifier = 652; +const xml_token_t XML_TextWizardSettings = 653; +const xml_token_t XML_ThousandSeparator = 654; +const xml_token_t XML_Ticked = 655; +const xml_token_t XML_Title = 656; +const xml_token_t XML_Toolbar = 657; +const xml_token_t XML_TooltipInfo = 658; +const xml_token_t XML_Top = 659; +const xml_token_t XML_TopCell = 660; +const xml_token_t XML_TopRowBottomPane = 661; +const xml_token_t XML_TopRowVisible = 662; +const xml_token_t XML_TotalAlignment = 663; +const xml_token_t XML_TotalAllMembers = 664; +const xml_token_t XML_TotalCaptionAlignment = 665; +const xml_token_t XML_TotalFormat = 666; +const xml_token_t XML_TotalTime = 667; +const xml_token_t XML_TotalWidth = 668; +const xml_token_t XML_TransitionExpressionEvaluation = 669; +const xml_token_t XML_TransitionFormulaEntry = 670; +const xml_token_t XML_Type = 671; +const xml_token_t XML_U = 672; +const xml_token_t XML_URLString = 673; +const xml_token_t XML_Uncalced = 674; +const xml_token_t XML_Underline = 675; +const xml_token_t XML_UniqueName = 676; +const xml_token_t XML_Unsynced = 677; +const xml_token_t XML_UseBlank = 678; +const xml_token_t XML_UseLocalConnection = 679; +const xml_token_t XML_UseSameSettings = 680; +const xml_token_t XML_User = 681; +const xml_token_t XML_VMLFrame = 682; +const xml_token_t XML_VacatedStyle = 683; +const xml_token_t XML_ValidPrinterInfo = 684; +const xml_token_t XML_Value = 685; +const xml_token_t XML_Value1 = 686; +const xml_token_t XML_Value2 = 687; +const xml_token_t XML_Version = 688; +const xml_token_t XML_VersionLastEdit = 689; +const xml_token_t XML_VersionLastRefresh = 690; +const xml_token_t XML_VersionLastUpdate = 691; +const xml_token_t XML_VersionRefreshableMin = 692; +const xml_token_t XML_VersionUpdateableMin = 693; +const xml_token_t XML_Vertical = 694; +const xml_token_t XML_VerticalAlign = 695; +const xml_token_t XML_VerticalResolution = 696; +const xml_token_t XML_VerticalText = 697; +const xml_token_t XML_ViewableRange = 698; +const xml_token_t XML_Visible = 699; +const xml_token_t XML_VisualTotals = 700; +const xml_token_t XML_WantAdvise = 701; +const xml_token_t XML_WantPict = 702; +const xml_token_t XML_Watch = 703; +const xml_token_t XML_Watches = 704; +const xml_token_t XML_WebPostString = 705; +const xml_token_t XML_Weight = 706; +const xml_token_t XML_Width = 707; +const xml_token_t XML_WindowHeight = 708; +const xml_token_t XML_WindowHidden = 709; +const xml_token_t XML_WindowIconic = 710; +const xml_token_t XML_WindowTopX = 711; +const xml_token_t XML_WindowTopY = 712; +const xml_token_t XML_WindowWidth = 713; +const xml_token_t XML_Windows = 714; +const xml_token_t XML_Words = 715; +const xml_token_t XML_Workbook = 716; +const xml_token_t XML_WorkbookOptions = 717; +const xml_token_t XML_Worksheet = 718; +const xml_token_t XML_WorksheetOptions = 719; +const xml_token_t XML_WorksheetSource = 720; +const xml_token_t XML_WrapText = 721; +const xml_token_t XML_XPath = 722; +const xml_token_t XML_XSDType = 723; +const xml_token_t XML_Xct = 724; +const xml_token_t XML_ZeroHeight = 725; +const xml_token_t XML_Zoom = 726; +const xml_token_t XML_accentbar = 727; +const xml_token_t XML_adj = 728; +const xml_token_t XML_adjusthandles = 729; +const xml_token_t XML_alignshape = 730; +const xml_token_t XML_allowincell = 731; +const xml_token_t XML_allowoverlap = 732; +const xml_token_t XML_alt = 733; +const xml_token_t XML_althref = 734; +const xml_token_t XML_angle = 735; +const xml_token_t XML_arc = 736; +const xml_token_t XML_arcsize = 737; +const xml_token_t XML_arrowok = 738; +const xml_token_t XML_aspect = 739; +const xml_token_t XML_aspectratio = 740; +const xml_token_t XML_attribute = 741; +const xml_token_t XML_autorotationcenter = 742; +const xml_token_t XML_backdepth = 743; +const xml_token_t XML_background = 744; +const xml_token_t XML_bilevel = 745; +const xml_token_t XML_blacklevel = 746; +const xml_token_t XML_borderbottomcolor = 747; +const xml_token_t XML_borderleftcolor = 748; +const xml_token_t XML_borderrightcolor = 749; +const xml_token_t XML_bordertopcolor = 750; +const xml_token_t XML_brightness = 751; +const xml_token_t XML_bullet = 752; +const xml_token_t XML_button = 753; +const xml_token_t XML_bwmode = 754; +const xml_token_t XML_bwnormal = 755; +const xml_token_t XML_bwpure = 756; +const xml_token_t XML_callout = 757; +const xml_token_t XML_caption = 758; +const xml_token_t XML_chromakey = 759; +const xml_token_t XML_class = 760; +const xml_token_t XML_clip = 761; +const xml_token_t XML_color = 762; +const xml_token_t XML_color2 = 763; +const xml_token_t XML_colormenu = 764; +const xml_token_t XML_colormode = 765; +const xml_token_t XML_colormru = 766; +const xml_token_t XML_colors = 767; +const xml_token_t XML_complex = 768; +const xml_token_t XML_connectangles = 769; +const xml_token_t XML_connectloc = 770; +const xml_token_t XML_connectlocs = 771; +const xml_token_t XML_connectortype = 772; +const xml_token_t XML_connecttype = 773; +const xml_token_t XML_content = 774; +const xml_token_t XML_control1 = 775; +const xml_token_t XML_control2 = 776; +const xml_token_t XML_coordorigin = 777; +const xml_token_t XML_coordsize = 778; +const xml_token_t XML_cropbottom = 779; +const xml_token_t XML_cropleft = 780; +const xml_token_t XML_cropping = 781; +const xml_token_t XML_cropright = 782; +const xml_token_t XML_croptop = 783; +const xml_token_t XML_curve = 784; +const xml_token_t XML_dashstyle = 785; +const xml_token_t XML_data = 786; +const xml_token_t XML_datatype = 787; +const xml_token_t XML_detectmouseclick = 788; +const xml_token_t XML_diffusity = 789; +const xml_token_t XML_displaycustomheaders = 790; +const xml_token_t XML_distance = 791; +const xml_token_t XML_doubleclicknotify = 792; +const xml_token_t XML_drop = 793; +const xml_token_t XML_dropauto = 794; +const xml_token_t XML_dt = 795; +const xml_token_t XML_edge = 796; +const xml_token_t XML_editas = 797; +const xml_token_t XML_embosscolor = 798; +const xml_token_t XML_end = 799; +const xml_token_t XML_endAngle = 800; +const xml_token_t XML_endarrow = 801; +const xml_token_t XML_endarrowlength = 802; +const xml_token_t XML_endarrowwidth = 803; +const xml_token_t XML_endcap = 804; +const xml_token_t XML_entry = 805; +const xml_token_t XML_eqn = 806; +const xml_token_t XML_ext = 807; +const xml_token_t XML_extends = 808; +const xml_token_t XML_extrusion = 809; +const xml_token_t XML_extrusioncolor = 810; +const xml_token_t XML_extrusionok = 811; +const xml_token_t XML_f = 812; +const xml_token_t XML_facet = 813; +const xml_token_t XML_fill = 814; +const xml_token_t XML_fillcolor = 815; +const xml_token_t XML_filled = 816; +const xml_token_t XML_fillok = 817; +const xml_token_t XML_filltype = 818; +const xml_token_t XML_fitpath = 819; +const xml_token_t XML_fitshape = 820; +const xml_token_t XML_focus = 821; +const xml_token_t XML_focusposition = 822; +const xml_token_t XML_focussize = 823; +const xml_token_t XML_forcedash = 824; +const xml_token_t XML_foredepth = 825; +const xml_token_t XML_formulas = 826; +const xml_token_t XML_from = 827; +const xml_token_t XML_gain = 828; +const xml_token_t XML_gamma = 829; +const xml_token_t XML_gap = 830; +const xml_token_t XML_gradientshapeok = 831; +const xml_token_t XML_grayscale = 832; +const xml_token_t XML_group = 833; +const xml_token_t XML_grouping = 834; +const xml_token_t XML_h = 835; +const xml_token_t XML_handles = 836; +const xml_token_t XML_hidden = 837; +const xml_token_t XML_how = 838; +const xml_token_t XML_hr = 839; +const xml_token_t XML_hralign = 840; +const xml_token_t XML_href = 841; +const xml_token_t XML_hrheight = 842; +const xml_token_t XML_hrnoshade = 843; +const xml_token_t XML_hrpct = 844; +const xml_token_t XML_hrstd = 845; +const xml_token_t XML_hrwidth = 846; +const xml_token_t XML_id = 847; +const xml_token_t XML_idmap = 848; +const xml_token_t XML_idref = 849; +const xml_token_t XML_image = 850; +const xml_token_t XML_imagealignshape = 851; +const xml_token_t XML_imageaspect = 852; +const xml_token_t XML_imagedata = 853; +const xml_token_t XML_imagesize = 854; +const xml_token_t XML_inset = 855; +const xml_token_t XML_insetmode = 856; +const xml_token_t XML_invx = 857; +const xml_token_t XML_invy = 858; +const xml_token_t XML_joinstyle = 859; +const xml_token_t XML_length = 860; +const xml_token_t XML_lengthspecified = 861; +const xml_token_t XML_lightface = 862; +const xml_token_t XML_lightharsh = 863; +const xml_token_t XML_lightharsh2 = 864; +const xml_token_t XML_lightlevel = 865; +const xml_token_t XML_lightlevel2 = 866; +const xml_token_t XML_lightposition = 867; +const xml_token_t XML_lightposition2 = 868; +const xml_token_t XML_limo = 869; +const xml_token_t XML_line = 870; +const xml_token_t XML_linestyle = 871; +const xml_token_t XML_lock = 872; +const xml_token_t XML_lockrotationcenter = 873; +const xml_token_t XML_map = 874; +const xml_token_t XML_master = 875; +const xml_token_t XML_matrix = 876; +const xml_token_t XML_maxLength = 877; +const xml_token_t XML_metal = 878; +const xml_token_t XML_method = 879; +const xml_token_t XML_minusx = 880; +const xml_token_t XML_minusy = 881; +const xml_token_t XML_miterlimit = 882; +const xml_token_t XML_movie = 883; +const xml_token_t XML_name = 884; +const xml_token_t XML_namespaceuri = 885; +const xml_token_t XML_new = 886; +const xml_token_t XML_obscured = 887; +const xml_token_t XML_offset = 888; +const xml_token_t XML_offset2 = 889; +const xml_token_t XML_old = 890; +const xml_token_t XML_ole = 891; +const xml_token_t XML_oleicon = 892; +const xml_token_t XML_oleid = 893; +const xml_token_t XML_on = 894; +const xml_token_t XML_oned = 895; +const xml_token_t XML_onmouseover = 896; +const xml_token_t XML_opacity = 897; +const xml_token_t XML_opacity2 = 898; +const xml_token_t XML_orientation = 899; +const xml_token_t XML_orientationangle = 900; +const xml_token_t XML_origin = 901; +const xml_token_t XML_oval = 902; +const xml_token_t XML_password = 903; +const xml_token_t XML_path = 904; +const xml_token_t XML_phonetictext = 905; +const xml_token_t XML_plane = 906; +const xml_token_t XML_points = 907; +const xml_token_t XML_polar = 908; +const xml_token_t XML_polyline = 909; +const xml_token_t XML_position = 910; +const xml_token_t XML_preferrelative = 911; +const xml_token_t XML_print = 912; +const xml_token_t XML_proxy = 913; +const xml_token_t XML_r = 914; +const xml_token_t XML_radiusrange = 915; +const xml_token_t XML_rect = 916; +const xml_token_t XML_regroupid = 917; +const xml_token_t XML_regrouptable = 918; +const xml_token_t XML_relativeposition = 919; +const xml_token_t XML_render = 920; +const xml_token_t XML_rotation = 921; +const xml_token_t XML_rotationangle = 922; +const xml_token_t XML_rotationcenter = 923; +const xml_token_t XML_roundrect = 924; +const xml_token_t XML_row = 925; +const xml_token_t XML_ruleinitiator = 926; +const xml_token_t XML_ruleproxy = 927; +const xml_token_t XML_rules = 928; +const xml_token_t XML_selection = 929; +const xml_token_t XML_shadow = 930; +const xml_token_t XML_shadowcolor = 931; +const xml_token_t XML_shadowok = 932; +const xml_token_t XML_shape = 933; +const xml_token_t XML_shapedefaults = 934; +const xml_token_t XML_shapelayout = 935; +const xml_token_t XML_shapetype = 936; +const xml_token_t XML_shininess = 937; +const xml_token_t XML_singleclick = 938; +const xml_token_t XML_size = 939; +const xml_token_t XML_skew = 940; +const xml_token_t XML_skewamt = 941; +const xml_token_t XML_skewangle = 942; +const xml_token_t XML_specularity = 943; +const xml_token_t XML_spid = 944; +const xml_token_t XML_spidmax = 945; +const xml_token_t XML_spt = 946; +const xml_token_t XML_src = 947; +const xml_token_t XML_start = 948; +const xml_token_t XML_startAngle = 949; +const xml_token_t XML_startarrow = 950; +const xml_token_t XML_startarrowlength = 951; +const xml_token_t XML_startarrowwidth = 952; +const xml_token_t XML_string = 953; +const xml_token_t XML_stroke = 954; +const xml_token_t XML_strokecolor = 955; +const xml_token_t XML_stroked = 956; +const xml_token_t XML_strokeok = 957; +const xml_token_t XML_strokeweight = 958; +const xml_token_t XML_style = 959; +const xml_token_t XML_switch = 960; +const xml_token_t XML_tablelimits = 961; +const xml_token_t XML_tableproperties = 962; +const xml_token_t XML_target = 963; +const xml_token_t XML_targetscreensize = 964; +const xml_token_t XML_text = 965; +const xml_token_t XML_textborder = 966; +const xml_token_t XML_textbox = 967; +const xml_token_t XML_textboxrect = 968; +const xml_token_t XML_textpath = 969; +const xml_token_t XML_textpathok = 970; +const xml_token_t XML_title = 971; +const xml_token_t XML_to = 972; +const xml_token_t XML_trim = 973; +const xml_token_t XML_type = 974; +const xml_token_t XML_url = 975; +const xml_token_t XML_useExplicit = 976; +const xml_token_t XML_userId = 977; +const xml_token_t XML_userdrawn = 978; +const xml_token_t XML_userhidden = 979; +const xml_token_t XML_v = 980; +const xml_token_t XML_verticies = 981; +const xml_token_t XML_viewpoint = 982; +const xml_token_t XML_viewpointorigin = 983; +const xml_token_t XML_visible = 984; +const xml_token_t XML_weight = 985; +const xml_token_t XML_worksheetoptions = 986; +const xml_token_t XML_wrapcoords = 987; +const xml_token_t XML_xrange = 988; +const xml_token_t XML_xscale = 989; +const xml_token_t XML_yrange = 990; diff --git a/src/liborcus/xls_xml_tokens.cpp b/src/liborcus/xls_xml_tokens.cpp new file mode 100644 index 0000000..1ba9001 --- /dev/null +++ b/src/liborcus/xls_xml_tokens.cpp @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xls_xml_tokens.hpp" + +namespace orcus { + +namespace { + +#include "xls_xml_tokens.inl" + +} + +tokens xls_xml_tokens = tokens(token_names, token_name_count); + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xls_xml_tokens.hpp b/src/liborcus/xls_xml_tokens.hpp new file mode 100644 index 0000000..0180db1 --- /dev/null +++ b/src/liborcus/xls_xml_tokens.hpp @@ -0,0 +1,20 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_XLS_XML_TOKENS_HPP +#define ORCUS_XLS_XML_TOKENS_HPP + +#include "orcus/tokens.hpp" + +namespace orcus { + +extern tokens xls_xml_tokens; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xls_xml_tokens.inl b/src/liborcus/xls_xml_tokens.inl new file mode 100644 index 0000000..73cd1fc --- /dev/null +++ b/src/liborcus/xls_xml_tokens.inl @@ -0,0 +1,997 @@ +// This file has been auto-generated. Do not hand-edit this. + +const char* token_names[] = { + "??", // 0 + "AcceptLabelsInFormulas", // 1 + "Action", // 2 + "ActiveChart", // 3 + "ActiveCol", // 4 + "ActiveColumn", // 5 + "ActivePane", // 6 + "ActiveRow", // 7 + "ActiveRows", // 8 + "ActiveSheet", // 9 + "Aggregate", // 10 + "AlertVersion", // 11 + "Alignment", // 12 + "AllItemName", // 13 + "AllowDeleteCols", // 14 + "AllowDeleteRows", // 15 + "AllowFilter", // 16 + "AllowFormatCells", // 17 + "AllowInsertCols", // 18 + "AllowInsertHyperlinks", // 19 + "AllowInsertRows", // 20 + "AllowPNG", // 21 + "AllowSizeCols", // 22 + "AllowSizeRows", // 23 + "AllowSort", // 24 + "AllowUsePivotTables", // 25 + "AlternateMethod", // 26 + "AppName", // 27 + "Append", // 28 + "ApplyAutomaticOutlineStyles", // 29 + "Area", // 30 + "ArrayRange", // 31 + "Async", // 32 + "Attribute", // 33 + "AttributeType", // 34 + "Authentication", // 35 + "Author", // 36 + "AutoFilter", // 37 + "AutoFilterAnd", // 38 + "AutoFilterColumn", // 39 + "AutoFilterCondition", // 40 + "AutoFilterOr", // 41 + "AutoFitHeight", // 42 + "AutoFitWidth", // 43 + "AutoFormatAlignment", // 44 + "AutoFormatBorder", // 45 + "AutoFormatFont", // 46 + "AutoFormatName", // 47 + "AutoFormatNumber", // 48 + "AutoFormatPattern", // 49 + "AutoFormatWidth", // 50 + "AutoRepublish", // 51 + "AutoShowCount", // 52 + "AutoShowField", // 53 + "AutoShowRange", // 54 + "AutoShowType", // 55 + "AutoSortField", // 56 + "AutoSortOrder", // 57 + "B", // 58 + "BackgroundQuery", // 59 + "BaseField", // 60 + "BaseItem", // 61 + "Basic", // 62 + "Behavior", // 63 + "Binding", // 64 + "BlackAndWhite", // 65 + "BlankLineAfterItems", // 66 + "BlockTotal", // 67 + "Bold", // 68 + "Boolean", // 69 + "Border", // 70 + "Borders", // 71 + "Bottom", // 72 + "BoundField", // 73 + "Bytes", // 74 + "CacheDetails", // 75 + "CacheFile", // 76 + "CacheIndex", // 77 + "CachePosition", // 78 + "CalculatedMember", // 79 + "Calculation", // 80 + "CantGetUniqueItems", // 81 + "Caption", // 82 + "CaptionAlignment", // 83 + "CaseSensitive", // 84 + "Category", // 85 + "Cell", // 86 + "CellRangeList", // 87 + "CellsExpanded", // 88 + "CellsExpandedSeqNum", // 89 + "CellsNotExpanded", // 90 + "CenterHorizontal", // 91 + "CenterVertical", // 92 + "Cf", // 93 + "CharSet", // 94 + "Characters", // 95 + "CharactersWithSpaces", // 96 + "ClientParameter", // 97 + "ClientParameterBinding", // 98 + "ClientParameterBindings", // 99 + "ClientParameterValue", // 100 + "Clipped", // 101 + "CodeName", // 102 + "Col1", // 103 + "Col10", // 104 + "Col11", // 105 + "Col12", // 106 + "Col13", // 107 + "Col14", // 108 + "Col15", // 109 + "Col16", // 110 + "Col17", // 111 + "Col18", // 112 + "Col19", // 113 + "Col2", // 114 + "Col20", // 115 + "Col3", // 116 + "Col4", // 117 + "Col5", // 118 + "Col6", // 119 + "Col7", // 120 + "Col8", // 121 + "Col9", // 122 + "ColBreak", // 123 + "ColBreaks", // 124 + "ColFirst", // 125 + "ColLast", // 126 + "Color", // 127 + "Column", // 128 + "ColumnInfo", // 129 + "ColumnInputCell", // 130 + "ColumnName", // 131 + "ComboHide", // 132 + "Comma", // 133 + "CommandText", // 134 + "CommandTextOrignal", // 135 + "CommandType", // 136 + "Comment", // 137 + "CommentsLayout", // 138 + "Company", // 139 + "ComponentOptions", // 140 + "Condition", // 141 + "ConditionalFormatting", // 142 + "Connection", // 143 + "ConnectionInfo", // 144 + "ConnectionString", // 145 + "Consecutive", // 146 + "ConsolidationReference", // 147 + "Count", // 148 + "CountOfSameItems", // 149 + "CreateBackup", // 150 + "Created", // 151 + "Credential", // 152 + "CredentialBinding", // 153 + "CredentialValue", // 154 + "Crn", // 155 + "CubeField", // 156 + "CubeSource", // 157 + "CurrentPage", // 158 + "Custom", // 159 + "CustomDocumentProperties", // 160 + "Data", // 161 + "DataAxisEmpty", // 162 + "DataField", // 163 + "DataMember", // 164 + "DataSource", // 165 + "DataTable", // 166 + "DataType", // 167 + "DataValidation", // 168 + "DataValueEditing", // 169 + "Date1904", // 170 + "Decimal", // 171 + "DefaultColumnWidth", // 172 + "DefaultItem", // 173 + "DefaultRowHeight", // 174 + "DefaultValue", // 175 + "DefaultVersion", // 176 + "DeletedTitle", // 177 + "Delimiters", // 178 + "Descending", // 179 + "Description", // 180 + "DetailFormat", // 181 + "DetailMaxHeight", // 182 + "DetailMaxWidth", // 183 + "DetailRowHeight", // 184 + "DetailSortOrder", // 185 + "DetailWidth", // 186 + "Dimension", // 187 + "DisableDateRecognition", // 188 + "DisableDrillDown", // 189 + "DisableEdit", // 190 + "DisableFieldDialog", // 191 + "DisableRefresh", // 192 + "DisableWizard", // 193 + "DisplayDrawingObjects", // 194 + "DisplayEmptyMembers", // 195 + "DisplayErrorString", // 196 + "DisplayFieldList", // 197 + "DisplayFormulas", // 198 + "DisplayIn", // 199 + "DisplayInkNotes", // 200 + "DisplayPageBreak", // 201 + "DisplayRightToLeft", // 202 + "DivID", // 203 + "DoNotCalculateBeforeSave", // 204 + "DoNotDisplayColHeaders", // 205 + "DoNotDisplayGridlines", // 206 + "DoNotDisplayHeadings", // 207 + "DoNotDisplayOutline", // 208 + "DoNotDisplayRowHeaders", // 209 + "DoNotDisplayZeros", // 210 + "DoNotJoinDelimiters", // 211 + "DoNotPersist", // 212 + "DoNotPersistSort", // 213 + "DoNotPersstAF", // 214 + "DoNotPromptForFile", // 215 + "DoNotSaveLinkValues", // 216 + "DocumentProperties", // 217 + "DontShowInFieldList", // 218 + "DownloadComponents", // 219 + "DraftQuality", // 220 + "DrawAspect", // 221 + "DrilledLevel", // 222 + "DrilledMember", // 223 + "EditWebPage", // 224 + "ElementType", // 225 + "EmbedSaveSmartTags", // 226 + "EnableMultiplePageItems", // 227 + "EnableRedirections", // 228 + "EnableSelection", // 229 + "Encode", // 230 + "EntirePage", // 231 + "Entry", // 232 + "Error", // 233 + "ErrorHide", // 234 + "ErrorMessage", // 235 + "ErrorString", // 236 + "ErrorStyle", // 237 + "ErrorTitle", // 238 + "ExcelName", // 239 + "ExcelType", // 240 + "ExcelWorkbook", // 241 + "ExcelWorksheetType", // 242 + "Expanded", // 243 + "ExpandedColumnCount", // 244 + "ExpandedRowCount", // 245 + "ExternName", // 246 + "ExtraLeftColumns", // 247 + "ExtraRightColumns", // 248 + "Face", // 249 + "Family", // 250 + "Field", // 251 + "FieldLabelFormat", // 252 + "FieldListBottom", // 253 + "FieldListLeft", // 254 + "FieldListRight", // 255 + "FieldListTop", // 256 + "FieldStart", // 257 + "FieldType", // 258 + "File", // 259 + "FileName", // 260 + "FillDown", // 261 + "Filled", // 262 + "FilterCaption", // 263 + "FilterMember", // 264 + "FilterOn", // 265 + "FirstVisibleSheet", // 266 + "FitHeight", // 267 + "FitToPage", // 268 + "FitWidth", // 269 + "Font", // 270 + "FontName", // 271 + "Footer", // 272 + "Format", // 273 + "FormatSettings", // 274 + "FormatType", // 275 + "Formula", // 276 + "FormulaIndex", // 277 + "FormulaV10", // 278 + "FreezePanes", // 279 + "FrozenNoSplit", // 280 + "FullColumns", // 281 + "FullRows", // 282 + "Function", // 283 + "FunctionGroup", // 284 + "FunctionGroupIndex", // 285 + "FuturePersist", // 286 + "FutureVer", // 287 + "GrandTotalString", // 288 + "GridlineColor", // 289 + "GridlineColorIndex", // 290 + "Gridlines", // 291 + "GroupBy", // 292 + "GroupDefinition", // 293 + "GroupEnd", // 294 + "GroupEndAuto", // 295 + "GroupLevel", // 296 + "GroupMember", // 297 + "GroupNumber", // 298 + "GroupStart", // 299 + "GroupStartAuto", // 300 + "GroupType", // 301 + "GroupedWidth", // 302 + "Guid", // 303 + "HRef", // 304 + "HRefScreenTip", // 305 + "HTMLFormat", // 306 + "HTMLTables", // 307 + "HasNoAutoFormat", // 308 + "HasNoRecords", // 309 + "Header", // 310 + "HeaderRange", // 311 + "HeaderRow", // 312 + "Height", // 313 + "Hidden", // 314 + "HideDetail", // 315 + "HideDropDowns", // 316 + "HideFormula", // 317 + "HideHorizontalScrollBar", // 318 + "HideInactiveListBorder", // 319 + "HideOfficeLogo", // 320 + "HidePivotTableFieldList", // 321 + "HideTotalsAnnotation", // 322 + "HideVerticalScrollBar", // 323 + "HideWorkbookTabs", // 324 + "Horizontal", // 325 + "HorizontalResolution", // 326 + "Href", // 327 + "HtmlType", // 328 + "HyperlinkBase", // 329 + "I", // 330 + "ID", // 331 + "IMEMode", // 332 + "Id", // 333 + "IdWrapped", // 334 + "If", // 335 + "ImmediateItemsOnDrop", // 336 + "Indent", // 337 + "Index", // 338 + "IndividualCellBorders", // 339 + "InputHide", // 340 + "InputMessage", // 341 + "InputTitle", // 342 + "InsertEntireRows", // 343 + "InstanceShape", // 344 + "Interior", // 345 + "IntlMacro", // 346 + "Invalid", // 347 + "InvertedColumnMember", // 348 + "InvertedRowMember", // 349 + "IsGroupLevel", // 350 + "IsMemberProperty", // 351 + "IsNotFiltered", // 352 + "Italic", // 353 + "Item", // 354 + "ItemType", // 355 + "Iteration", // 356 + "KeyboardShortcut", // 357 + "Keywords", // 358 + "Label", // 359 + "LastAuthor", // 360 + "LastPrinted", // 361 + "LastSaved", // 362 + "Layout", // 363 + "LayoutForm", // 364 + "LayoutPageBreak", // 365 + "LayoutSubtotalLocation", // 366 + "LeafColumnMember", // 367 + "LeafRowMember", // 368 + "Left", // 369 + "LeftCell", // 370 + "LeftColumnRightPane", // 371 + "LeftColumnVisible", // 372 + "LeftToRight", // 373 + "LengthLevelUniqueName", // 374 + "Level", // 375 + "LineStyle", // 376 + "Lines", // 377 + "LoadMode", // 378 + "LocalConnection", // 379 + "Location", // 380 + "LocationOfComponents", // 381 + "Macro", // 382 + "MainFile", // 383 + "Maintain", // 384 + "MajorVersion", // 385 + "Manager", // 386 + "Map", // 387 + "MapChildItems", // 388 + "MapID", // 389 + "MapInfo", // 390 + "Mapdata", // 391 + "Margin", // 392 + "Max", // 393 + "MaxChange", // 394 + "MaxHeight", // 395 + "MaxIterations", // 396 + "MaxWidth", // 397 + "Measure", // 398 + "Member", // 399 + "MemberExpand", // 400 + "MemberFormat", // 401 + "MemberName", // 402 + "MemberPropertiesOrder", // 403 + "MemberProperty", // 404 + "MemberPropertyParent", // 405 + "MergeAcross", // 406 + "MergeDown", // 407 + "MergeLabels", // 408 + "Min", // 409 + "MinorVersion", // 410 + "Missing", // 411 + "MissingItemsLimit", // 412 + "Moper", // 413 + "MoveAfterReturn", // 414 + "Name", // 415 + "NamedCell", // 416 + "NamedRange", // 417 + "Names", // 418 + "Namespace", // 419 + "NewAsync", // 420 + "NewItemsHidden", // 421 + "NextId", // 422 + "NextSheetNumber", // 423 + "NoAutoFit", // 424 + "NoAutoFormatWidth", // 425 + "NoAutoPage", // 426 + "NoAutoRecover", // 427 + "NoAutofit", // 428 + "NoColumnGrand", // 429 + "NoDetailAutoFit", // 430 + "NoDisplayNullString", // 431 + "NoDragToColumn", // 432 + "NoDragToData", // 433 + "NoDragToHide", // 434 + "NoDragToPage", // 435 + "NoDragToRow", // 436 + "NoInserts", // 437 + "NoPreserveFormatting", // 438 + "NoPrintRepeatItems", // 439 + "NoPrinterInfo", // 440 + "NoRefreshCache", // 441 + "NoRowGrand", // 442 + "NoSaveData", // 443 + "NoSummaryColumnsRightDetail", // 444 + "NoSummaryRowsBelowDetail", // 445 + "NoTextToColumns", // 446 + "NoTitles", // 447 + "NoToggleDataHeader", // 448 + "NoViewCalculatedMembers", // 449 + "NonDefaultName", // 450 + "NotInverted", // 451 + "NotVisible", // 452 + "NullString", // 453 + "Number", // 454 + "NumberFormat", // 455 + "NumberOfCopies", // 456 + "OLEObject", // 457 + "OWCVersion", // 458 + "ObjectID", // 459 + "OfficeDocumentSettings", // 460 + "OleLink", // 461 + "Operator", // 462 + "OptimizeCache", // 463 + "Orientation", // 464 + "Outline", // 465 + "OverwriteCells", // 466 + "PLCaption", // 467 + "PLDataOrientation", // 468 + "PLExport", // 469 + "PLGroupType", // 470 + "PLName", // 471 + "PLPivotField", // 472 + "PLPosition", // 473 + "PLSubtotal", // 474 + "PLTPivotItem", // 475 + "PLTotal", // 476 + "PTFormat", // 477 + "PTFormula", // 478 + "PTLineItem", // 479 + "PTLineItems", // 480 + "PTPivotData", // 481 + "PTRule", // 482 + "PTSource", // 483 + "PageBreakZoom", // 484 + "PageBreaks", // 485 + "PageFieldOrder", // 486 + "PageFieldStyle", // 487 + "PageFieldWrapCount", // 488 + "PageMargins", // 489 + "PageSetup", // 490 + "Pages", // 491 + "Pane", // 492 + "Panes", // 493 + "PaperSizeIndex", // 494 + "Paragraphs", // 495 + "Parameter", // 496 + "ParameterType", // 497 + "ParameterValue", // 498 + "Parent", // 499 + "ParentField", // 500 + "ParentIsOther", // 501 + "ParentName", // 502 + "ParentUniqueName", // 503 + "ParseFormulaAsV10", // 504 + "ParseRuleAsV10", // 505 + "PasteFormula", // 506 + "PasteRefersTo", // 507 + "Path", // 508 + "Pattern", // 509 + "PatternColor", // 510 + "PivotAxis", // 511 + "PivotCache", // 512 + "PivotField", // 513 + "PivotItem", // 514 + "PivotTable", // 515 + "PivotView", // 516 + "Position", // 517 + "PrecisionAsDisplayed", // 518 + "PresentationFormat", // 519 + "Print", // 520 + "PrintErrors", // 521 + "PrintSetTitles", // 522 + "ProgID", // 523 + "PromptString", // 524 + "ProtectContents", // 525 + "ProtectObjects", // 526 + "ProtectScenarios", // 527 + "ProtectStructure", // 528 + "ProtectWindows", // 529 + "Protected", // 530 + "Protection", // 531 + "Proxy", // 532 + "PublishObject", // 533 + "PublishObjects", // 534 + "Purpose", // 535 + "QTSource", // 536 + "Qualifier", // 537 + "Query97", // 538 + "QuerySource", // 539 + "QueryTable", // 540 + "QueryType", // 541 + "Range", // 542 + "RangeSelection", // 543 + "ReadOnly", // 544 + "ReadingOrder", // 545 + "RefModeR1C1", // 546 + "Reference", // 547 + "RefersTo", // 548 + "RefreshDate", // 549 + "RefreshDateCopy", // 550 + "RefreshInfo", // 551 + "RefreshName", // 552 + "RefreshOnChange", // 553 + "RefreshOnFileOpen", // 554 + "RefreshTimeSpan", // 555 + "RefreshedInXl9", // 556 + "Resource", // 557 + "Revision", // 558 + "Right", // 559 + "RightToLeft", // 560 + "RobustConnect", // 561 + "RootElement", // 562 + "Rotate", // 563 + "Rotation", // 564 + "Row", // 565 + "RowBreak", // 566 + "RowBreaks", // 567 + "RowColHeadings", // 568 + "RowInputCell", // 569 + "RowLast", // 570 + "RowNumbers", // 571 + "Rule", // 572 + "RuleType", // 573 + "RuleV10", // 574 + "S", // 575 + "SOAPAction", // 576 + "SQLType", // 577 + "Scale", // 578 + "Schema", // 579 + "SchemaID", // 580 + "SchemaRef", // 581 + "Selected", // 582 + "SelectedSheets", // 583 + "Selection", // 584 + "SelectionNamespaces", // 585 + "SemiColon", // 586 + "SeqNum", // 587 + "Sequence", // 588 + "ServerBased", // 589 + "ServerSortOrder", // 590 + "Set", // 591 + "Shadow", // 592 + "ShapeID", // 593 + "SheetIndex", // 594 + "SheetName", // 595 + "ShowAllItems", // 596 + "ShowAlways", // 597 + "ShowCellBackgroundFromOLAP", // 598 + "ShowImportExportValidationErrors", // 599 + "ShowPageBreakZoom", // 600 + "ShowPageMultipleItemLabel", // 601 + "ShowTotals", // 602 + "ShrinkToFit", // 603 + "Size", // 604 + "SmallGrid", // 605 + "SmartTagType", // 606 + "SmartTags", // 607 + "SolveOrder", // 608 + "Sort", // 609 + "SortKey", // 610 + "SortOrder", // 611 + "Sorting", // 612 + "Source", // 613 + "SourceConnectionFile", // 614 + "SourceConsolidation", // 615 + "SourceDataFile", // 616 + "SourceHierarchy", // 617 + "SourceHierarchyLevel", // 618 + "SourceName", // 619 + "SourceType", // 620 + "Space", // 621 + "SpaceAbove", // 622 + "SpaceBelow", // 623 + "Span", // 624 + "SplitHorizontal", // 625 + "SplitVertical", // 626 + "SpreadsheetAutoFit", // 627 + "StandardWidth", // 628 + "StartPageNumber", // 629 + "StartRow", // 630 + "StrikeThrough", // 631 + "Style", // 632 + "StyleID", // 633 + "Styles", // 634 + "Sub", // 635 + "SubType", // 636 + "Subject", // 637 + "Subtotal", // 638 + "SubtotalFormat", // 639 + "SubtotalHiddenPageItems", // 640 + "SubtotalName", // 641 + "Sup", // 642 + "SupBook", // 643 + "Synchronous", // 644 + "Tab", // 645 + "TabColorIndex", // 646 + "TabRatio", // 647 + "Table", // 648 + "TableStyle", // 649 + "Tag", // 650 + "Text", // 651 + "TextQualifier", // 652 + "TextWizardSettings", // 653 + "ThousandSeparator", // 654 + "Ticked", // 655 + "Title", // 656 + "Toolbar", // 657 + "TooltipInfo", // 658 + "Top", // 659 + "TopCell", // 660 + "TopRowBottomPane", // 661 + "TopRowVisible", // 662 + "TotalAlignment", // 663 + "TotalAllMembers", // 664 + "TotalCaptionAlignment", // 665 + "TotalFormat", // 666 + "TotalTime", // 667 + "TotalWidth", // 668 + "TransitionExpressionEvaluation", // 669 + "TransitionFormulaEntry", // 670 + "Type", // 671 + "U", // 672 + "URLString", // 673 + "Uncalced", // 674 + "Underline", // 675 + "UniqueName", // 676 + "Unsynced", // 677 + "UseBlank", // 678 + "UseLocalConnection", // 679 + "UseSameSettings", // 680 + "User", // 681 + "VMLFrame", // 682 + "VacatedStyle", // 683 + "ValidPrinterInfo", // 684 + "Value", // 685 + "Value1", // 686 + "Value2", // 687 + "Version", // 688 + "VersionLastEdit", // 689 + "VersionLastRefresh", // 690 + "VersionLastUpdate", // 691 + "VersionRefreshableMin", // 692 + "VersionUpdateableMin", // 693 + "Vertical", // 694 + "VerticalAlign", // 695 + "VerticalResolution", // 696 + "VerticalText", // 697 + "ViewableRange", // 698 + "Visible", // 699 + "VisualTotals", // 700 + "WantAdvise", // 701 + "WantPict", // 702 + "Watch", // 703 + "Watches", // 704 + "WebPostString", // 705 + "Weight", // 706 + "Width", // 707 + "WindowHeight", // 708 + "WindowHidden", // 709 + "WindowIconic", // 710 + "WindowTopX", // 711 + "WindowTopY", // 712 + "WindowWidth", // 713 + "Windows", // 714 + "Words", // 715 + "Workbook", // 716 + "WorkbookOptions", // 717 + "Worksheet", // 718 + "WorksheetOptions", // 719 + "WorksheetSource", // 720 + "WrapText", // 721 + "XPath", // 722 + "XSDType", // 723 + "Xct", // 724 + "ZeroHeight", // 725 + "Zoom", // 726 + "accentbar", // 727 + "adj", // 728 + "adjusthandles", // 729 + "alignshape", // 730 + "allowincell", // 731 + "allowoverlap", // 732 + "alt", // 733 + "althref", // 734 + "angle", // 735 + "arc", // 736 + "arcsize", // 737 + "arrowok", // 738 + "aspect", // 739 + "aspectratio", // 740 + "attribute", // 741 + "autorotationcenter", // 742 + "backdepth", // 743 + "background", // 744 + "bilevel", // 745 + "blacklevel", // 746 + "borderbottomcolor", // 747 + "borderleftcolor", // 748 + "borderrightcolor", // 749 + "bordertopcolor", // 750 + "brightness", // 751 + "bullet", // 752 + "button", // 753 + "bwmode", // 754 + "bwnormal", // 755 + "bwpure", // 756 + "callout", // 757 + "caption", // 758 + "chromakey", // 759 + "class", // 760 + "clip", // 761 + "color", // 762 + "color2", // 763 + "colormenu", // 764 + "colormode", // 765 + "colormru", // 766 + "colors", // 767 + "complex", // 768 + "connectangles", // 769 + "connectloc", // 770 + "connectlocs", // 771 + "connectortype", // 772 + "connecttype", // 773 + "content", // 774 + "control1", // 775 + "control2", // 776 + "coordorigin", // 777 + "coordsize", // 778 + "cropbottom", // 779 + "cropleft", // 780 + "cropping", // 781 + "cropright", // 782 + "croptop", // 783 + "curve", // 784 + "dashstyle", // 785 + "data", // 786 + "datatype", // 787 + "detectmouseclick", // 788 + "diffusity", // 789 + "displaycustomheaders", // 790 + "distance", // 791 + "doubleclicknotify", // 792 + "drop", // 793 + "dropauto", // 794 + "dt", // 795 + "edge", // 796 + "editas", // 797 + "embosscolor", // 798 + "end", // 799 + "endAngle", // 800 + "endarrow", // 801 + "endarrowlength", // 802 + "endarrowwidth", // 803 + "endcap", // 804 + "entry", // 805 + "eqn", // 806 + "ext", // 807 + "extends", // 808 + "extrusion", // 809 + "extrusioncolor", // 810 + "extrusionok", // 811 + "f", // 812 + "facet", // 813 + "fill", // 814 + "fillcolor", // 815 + "filled", // 816 + "fillok", // 817 + "filltype", // 818 + "fitpath", // 819 + "fitshape", // 820 + "focus", // 821 + "focusposition", // 822 + "focussize", // 823 + "forcedash", // 824 + "foredepth", // 825 + "formulas", // 826 + "from", // 827 + "gain", // 828 + "gamma", // 829 + "gap", // 830 + "gradientshapeok", // 831 + "grayscale", // 832 + "group", // 833 + "grouping", // 834 + "h", // 835 + "handles", // 836 + "hidden", // 837 + "how", // 838 + "hr", // 839 + "hralign", // 840 + "href", // 841 + "hrheight", // 842 + "hrnoshade", // 843 + "hrpct", // 844 + "hrstd", // 845 + "hrwidth", // 846 + "id", // 847 + "idmap", // 848 + "idref", // 849 + "image", // 850 + "imagealignshape", // 851 + "imageaspect", // 852 + "imagedata", // 853 + "imagesize", // 854 + "inset", // 855 + "insetmode", // 856 + "invx", // 857 + "invy", // 858 + "joinstyle", // 859 + "length", // 860 + "lengthspecified", // 861 + "lightface", // 862 + "lightharsh", // 863 + "lightharsh2", // 864 + "lightlevel", // 865 + "lightlevel2", // 866 + "lightposition", // 867 + "lightposition2", // 868 + "limo", // 869 + "line", // 870 + "linestyle", // 871 + "lock", // 872 + "lockrotationcenter", // 873 + "map", // 874 + "master", // 875 + "matrix", // 876 + "maxLength", // 877 + "metal", // 878 + "method", // 879 + "minusx", // 880 + "minusy", // 881 + "miterlimit", // 882 + "movie", // 883 + "name", // 884 + "namespaceuri", // 885 + "new", // 886 + "obscured", // 887 + "offset", // 888 + "offset2", // 889 + "old", // 890 + "ole", // 891 + "oleicon", // 892 + "oleid", // 893 + "on", // 894 + "oned", // 895 + "onmouseover", // 896 + "opacity", // 897 + "opacity2", // 898 + "orientation", // 899 + "orientationangle", // 900 + "origin", // 901 + "oval", // 902 + "password", // 903 + "path", // 904 + "phonetictext", // 905 + "plane", // 906 + "points", // 907 + "polar", // 908 + "polyline", // 909 + "position", // 910 + "preferrelative", // 911 + "print", // 912 + "proxy", // 913 + "r", // 914 + "radiusrange", // 915 + "rect", // 916 + "regroupid", // 917 + "regrouptable", // 918 + "relativeposition", // 919 + "render", // 920 + "rotation", // 921 + "rotationangle", // 922 + "rotationcenter", // 923 + "roundrect", // 924 + "row", // 925 + "ruleinitiator", // 926 + "ruleproxy", // 927 + "rules", // 928 + "selection", // 929 + "shadow", // 930 + "shadowcolor", // 931 + "shadowok", // 932 + "shape", // 933 + "shapedefaults", // 934 + "shapelayout", // 935 + "shapetype", // 936 + "shininess", // 937 + "singleclick", // 938 + "size", // 939 + "skew", // 940 + "skewamt", // 941 + "skewangle", // 942 + "specularity", // 943 + "spid", // 944 + "spidmax", // 945 + "spt", // 946 + "src", // 947 + "start", // 948 + "startAngle", // 949 + "startarrow", // 950 + "startarrowlength", // 951 + "startarrowwidth", // 952 + "string", // 953 + "stroke", // 954 + "strokecolor", // 955 + "stroked", // 956 + "strokeok", // 957 + "strokeweight", // 958 + "style", // 959 + "switch", // 960 + "tablelimits", // 961 + "tableproperties", // 962 + "target", // 963 + "targetscreensize", // 964 + "text", // 965 + "textborder", // 966 + "textbox", // 967 + "textboxrect", // 968 + "textpath", // 969 + "textpathok", // 970 + "title", // 971 + "to", // 972 + "trim", // 973 + "type", // 974 + "url", // 975 + "useExplicit", // 976 + "userId", // 977 + "userdrawn", // 978 + "userhidden", // 979 + "v", // 980 + "verticies", // 981 + "viewpoint", // 982 + "viewpointorigin", // 983 + "visible", // 984 + "weight", // 985 + "worksheetoptions", // 986 + "wrapcoords", // 987 + "xrange", // 988 + "xscale", // 989 + "yrange" // 990 +}; + +size_t token_name_count = 991; diff --git a/src/liborcus/xlsx_autofilter_context.cpp b/src/liborcus/xlsx_autofilter_context.cpp new file mode 100644 index 0000000..7a4d5ab --- /dev/null +++ b/src/liborcus/xlsx_autofilter_context.cpp @@ -0,0 +1,140 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xlsx_autofilter_context.hpp" +#include "xml_context_global.hpp" +#include "ooxml_namespace_types.hpp" +#include "ooxml_token_constants.hpp" + +#include "orcus/spreadsheet/import_interface.hpp" + +#include <iostream> + +using namespace std; + +namespace orcus { + +xlsx_autofilter_context::xlsx_autofilter_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_reference_resolver& resolver) : + xml_context_base(session_cxt, tokens), + m_resolver(resolver), + m_cur_col(-1) {} + +xlsx_autofilter_context::~xlsx_autofilter_context() {} + +xml_context_base* xlsx_autofilter_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void xlsx_autofilter_context::end_child_context( + xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void xlsx_autofilter_context::start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + + if (ns != NS_ooxml_xlsx) + return; + + switch (name) + { + case XML_autoFilter: + { + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + m_ref_range = for_each( + attrs.begin(), attrs.end(), + single_attr_getter(m_pool, NS_ooxml_xlsx, XML_ref)).get_value(); + } + break; + case XML_filterColumn: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_autoFilter); + m_cur_col = for_each( + attrs.begin(), attrs.end(), + single_long_attr_getter(NS_ooxml_xlsx, XML_colId)).get_value(); + } + break; + case XML_filters: + xml_element_expected(parent, NS_ooxml_xlsx, XML_filterColumn); + break; + case XML_filter: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_filters); + std::string_view val = for_each( + attrs.begin(), attrs.end(), + single_attr_getter(m_pool, NS_ooxml_xlsx, XML_val)).get_value(); + if (!val.empty()) + m_cur_match_values.push_back(val); + } + break; + default: + warn_unhandled(); + } +} + +bool xlsx_autofilter_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_ooxml_xlsx) + { + switch (name) + { + case XML_filterColumn: + { + if (m_cur_col >= 0) + { + m_column_filters.insert( + column_filters_type::value_type(m_cur_col, m_cur_match_values)); + } + m_cur_col = -1; + m_cur_match_values.clear(); + } + break; + default: + ; + } + } + return pop_stack(ns, name); +} + +void xlsx_autofilter_context::characters(std::string_view /*str*/, bool /*transient*/) +{ +} + +void xlsx_autofilter_context::push_to_model(spreadsheet::iface::import_auto_filter& af) const +{ + spreadsheet::src_range_t range = m_resolver.resolve_range(m_ref_range); + af.set_range(to_rc_range(range)); + + for (const auto& v : m_column_filters) + { + spreadsheet::col_t col = v.first; + const match_values_type& match_values = v.second; + + af.set_column(col); + for (std::string_view value : match_values) + af.append_column_match_value(value); + af.commit_column(); + } + af.commit(); +} + +void xlsx_autofilter_context::reset() +{ + m_pool.clear(); + m_ref_range = std::string_view{}; + m_cur_col = -1; + m_cur_match_values.clear(); + m_column_filters.clear(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_autofilter_context.hpp b/src/liborcus/xlsx_autofilter_context.hpp new file mode 100644 index 0000000..27f5e7b --- /dev/null +++ b/src/liborcus/xlsx_autofilter_context.hpp @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_XLSX_AUTOFILTER_CONTEXT_HPP +#define ORCUS_XLSX_AUTOFILTER_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "orcus/string_pool.hpp" +#include "orcus/spreadsheet/types.hpp" + +#include <vector> +#include <map> + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_auto_filter; +class import_reference_resolver; + +}} + +class xlsx_autofilter_context : public xml_context_base +{ +public: + typedef std::vector<std::string_view> match_values_type; + typedef std::map<spreadsheet::col_t, match_values_type> column_filters_type; + + xlsx_autofilter_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_reference_resolver& resolver); + virtual ~xlsx_autofilter_context(); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child); + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + virtual void characters(std::string_view str, bool transient); + + void push_to_model(spreadsheet::iface::import_auto_filter& af) const; + + void reset(); + +private: + spreadsheet::iface::import_reference_resolver& m_resolver; + + string_pool m_pool; + + std::string_view m_ref_range; + spreadsheet::col_t m_cur_col; + match_values_type m_cur_match_values; + column_filters_type m_column_filters; +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_conditional_format_context.cpp b/src/liborcus/xlsx_conditional_format_context.cpp new file mode 100644 index 0000000..e667d83 --- /dev/null +++ b/src/liborcus/xlsx_conditional_format_context.cpp @@ -0,0 +1,878 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xlsx_conditional_format_context.hpp" +#include "xlsx_helper.hpp" +#include "xlsx_types.hpp" +#include "ooxml_token_constants.hpp" +#include "ooxml_namespace_types.hpp" + +#include "orcus/exception.hpp" +#include "orcus/spreadsheet/import_interface.hpp" +#include "orcus/measurement.hpp" + +#include <mdds/sorted_string_map.hpp> +#include <mdds/global.hpp> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace { + +enum xlsx_cond_format_type +{ + none = 0, + expression, + cellIs, + colorScale, + dataBar, + iconSet, + top10, + uniqueValues, + duplicateValues, + containsText, + notContainsText, + beginsWith, + endsWith, + containsBlanks, + notContainsBlanks, + containsErrors, + notContainsErrors, + timePeriod, + aboveAverage +}; + +enum xlsx_cond_format_operator +{ + operator_default = 0, + operator_beginsWith, + operator_between, + operator_containsText, + operator_endsWith, + operator_equal, + operator_greaterThan, + operator_greaterThanOrEqual, + operator_lessThan, + operator_lessThanOrEqual, + operator_notBetween, + operator_notContains, + operator_notEqual +}; + +enum xlsx_cond_format_date +{ + date_default = 0, + date_last7Days, + date_lastMonth, + date_lastWeek, + date_nextMonth, + date_thisMonth, + date_thisWeek, + date_today, + date_tomorrow, + date_yesterday +}; + +enum xlsx_cond_format_boolean +{ + boolean_default = 0, + boolean_true, + boolean_false +}; + +typedef mdds::sorted_string_map<xlsx_cond_format_type> cond_format_type_map; + +typedef mdds::sorted_string_map<xlsx_cond_format_boolean> cond_format_boolean_map; + +typedef mdds::sorted_string_map<xlsx_cond_format_operator> cond_format_operator_map; + +typedef mdds::sorted_string_map<xlsx_cond_format_date> cond_format_date_map; + +cond_format_type_map::entry cond_format_type_entries[] = +{ + { MDDS_ASCII("aboveAverage"), aboveAverage }, + { MDDS_ASCII("beginsWith"), beginsWith }, + { MDDS_ASCII("cellIs"), cellIs }, + { MDDS_ASCII("colorScale"), colorScale }, + { MDDS_ASCII("containsBlanks"), containsBlanks }, + { MDDS_ASCII("containsErrors"), containsErrors }, + { MDDS_ASCII("containsText"), containsText }, + { MDDS_ASCII("dataBar"), dataBar }, + { MDDS_ASCII("duplicateValues"), duplicateValues }, + { MDDS_ASCII("endsWith"), endsWith }, + { MDDS_ASCII("expression"), expression }, + { MDDS_ASCII("iconSet"), iconSet }, + { MDDS_ASCII("notContainsErrors"), notContainsErrors }, + { MDDS_ASCII("notContainsText"), notContainsText }, + { MDDS_ASCII("timePeriod"), timePeriod }, + { MDDS_ASCII("top10"), top10 }, + { MDDS_ASCII("uniqueValues"), uniqueValues } +}; + +cond_format_operator_map::entry cond_format_operator_entries[] = +{ + { MDDS_ASCII("beginsWith"), operator_beginsWith }, + { MDDS_ASCII("between"), operator_between }, + { MDDS_ASCII("containsText"), operator_containsText }, + { MDDS_ASCII("endsWith"), operator_endsWith }, + { MDDS_ASCII("equal"), operator_equal }, + { MDDS_ASCII("greaterThan"), operator_greaterThan }, + { MDDS_ASCII("greaterThanOrEqual"), operator_greaterThanOrEqual }, + { MDDS_ASCII("lessThan"), operator_lessThan }, + { MDDS_ASCII("lessThanOrEqual"), operator_lessThanOrEqual }, + { MDDS_ASCII("notBetween"), operator_notBetween }, + { MDDS_ASCII("notContains"), operator_notContains }, + { MDDS_ASCII("notEqual"), operator_notEqual } +}; + +cond_format_date_map::entry cond_format_date_entries[] = +{ + { MDDS_ASCII("last7Days"), date_last7Days }, + { MDDS_ASCII("lastMonth"), date_lastMonth }, + { MDDS_ASCII("lastWeek"), date_lastWeek }, + { MDDS_ASCII("nextMonth"), date_nextMonth }, + { MDDS_ASCII("thisMonth"), date_thisMonth }, + { MDDS_ASCII("thisWeek"), date_thisWeek }, + { MDDS_ASCII("today"), date_today }, + { MDDS_ASCII("tomorrow"), date_tomorrow }, + { MDDS_ASCII("yesterday"), date_yesterday } +}; + +cond_format_boolean_map::entry cond_format_boolean_entries[] = +{ + { MDDS_ASCII("0"), boolean_false }, + { MDDS_ASCII("1"), boolean_true }, + { MDDS_ASCII("false"), boolean_true }, + { MDDS_ASCII("true"), boolean_false } +}; + +bool parse_boolean_flag(const xml_token_attr_t& attr, bool default_value) +{ + static const cond_format_boolean_map boolean_map(cond_format_boolean_entries, sizeof(cond_format_boolean_entries)/sizeof(cond_format_boolean_entries[0]), boolean_default); + xlsx_cond_format_boolean val = boolean_map.find(attr.value.data(), attr.value.size()); + switch (val) + { + case boolean_default: + return default_value; + case boolean_true: + return true; + case boolean_false: + return false; + } + + return default_value; +} + +struct cfRule_attr_parser +{ + + cfRule_attr_parser(ss::iface::import_conditional_format& cond_format): + m_cond_format(cond_format), + m_type(none), + m_operator(operator_default), + m_date(date_default), + m_above_average(true), + m_equal_average(false), + m_percent(false), + m_bottom(false) + { + } + + void operator()(const xml_token_attr_t& attr) + { + switch(attr.name) + { + case XML_type: + { + cond_format_type_map type_map(cond_format_type_entries, sizeof(cond_format_type_entries)/sizeof(cond_format_type_entries[0]), none); + m_type = type_map.find(attr.value.data(), attr.value.size()); + } + break; + case XML_dxfId: + { + // TODO: actually we need to translate between dxf id and xf id + size_t dxf_id = to_long(attr.value); + m_cond_format.set_xf_id(dxf_id); + } + break; + case XML_aboveAverage: + { + m_above_average = parse_boolean_flag(attr, true); + } + break; + case XML_percent: + m_percent = parse_boolean_flag(attr, false); + break; + case XML_bottom: + m_bottom = parse_boolean_flag(attr, false); + break; + case XML_operator: + { + cond_format_operator_map operator_map(cond_format_operator_entries, sizeof(cond_format_operator_entries)/sizeof(cond_format_operator_entries[0]), operator_default); + m_operator = operator_map.find(attr.value.data(), attr.value.size()); + } + break; + case XML_text: + // do we need to worry about the transient flag here? + m_text = attr.value; + break; + case XML_timePeriod: + { + cond_format_date_map date_map(cond_format_date_entries, sizeof(cond_format_date_entries)/sizeof(cond_format_date_entries[0]), date_default); + m_date = date_map.find(attr.value.data(), attr.value.size()); + } + break; + case XML_rank: + // do we need to worry about the transient flag here? + m_rank = attr.value; + break; + case XML_stdDev: + // do we need to worry about the transient flag here? + m_std_dev = attr.value; + break; + case XML_equalAverage: + m_equal_average = parse_boolean_flag(attr, false); + break; + default: + break; + } + } + + void set_type() + { + switch (m_type) + { + case expression: + m_cond_format.set_type(ss::conditional_format_t::condition); + m_cond_format.set_operator(ss::condition_operator_t::expression); + break; + case cellIs: + m_cond_format.set_type(ss::conditional_format_t::condition); + m_cond_format.set_operator(ss::condition_operator_t::expression); + switch (m_operator) + { + case operator_beginsWith: + m_cond_format.set_operator(ss::condition_operator_t::begins_with); + break; + case operator_between: + m_cond_format.set_operator(ss::condition_operator_t::between); + break; + case operator_containsText: + m_cond_format.set_operator(ss::condition_operator_t::contains); + break; + case operator_endsWith: + m_cond_format.set_operator(ss::condition_operator_t::ends_with); + break; + case operator_equal: + m_cond_format.set_operator(ss::condition_operator_t::equal); + break; + case operator_greaterThan: + m_cond_format.set_operator(ss::condition_operator_t::greater); + break; + case operator_greaterThanOrEqual: + m_cond_format.set_operator(ss::condition_operator_t::greater_equal); + break; + case operator_lessThan: + m_cond_format.set_operator(ss::condition_operator_t::less); + break; + case operator_lessThanOrEqual: + m_cond_format.set_operator(ss::condition_operator_t::less_equal); + break; + case operator_notBetween: + m_cond_format.set_operator(ss::condition_operator_t::not_between); + break; + case operator_notContains: + m_cond_format.set_operator(ss::condition_operator_t::not_contains); + break; + case operator_notEqual: + m_cond_format.set_operator(ss::condition_operator_t::not_equal); + break; + default: + break; + } + break; + case colorScale: + m_cond_format.set_type(ss::conditional_format_t::colorscale); + break; + case dataBar: + m_cond_format.set_type(ss::conditional_format_t::databar); + break; + case iconSet: + m_cond_format.set_type(ss::conditional_format_t::iconset); + break; + case top10: + m_cond_format.set_type(ss::conditional_format_t::condition); + if (m_bottom) + { + m_cond_format.set_operator(ss::condition_operator_t::bottom_n); + } + else + { + m_cond_format.set_operator(ss::condition_operator_t::top_n); + } + m_cond_format.set_formula(m_rank); + break; + case uniqueValues: + m_cond_format.set_type(ss::conditional_format_t::condition); + m_cond_format.set_operator(ss::condition_operator_t::unique); + break; + case duplicateValues: + m_cond_format.set_type(ss::conditional_format_t::condition); + m_cond_format.set_operator(ss::condition_operator_t::duplicate); + break; + case containsText: + m_cond_format.set_type(ss::conditional_format_t::condition); + m_cond_format.set_operator(ss::condition_operator_t::contains); + m_cond_format.set_formula(m_text); + break; + case notContainsText: + m_cond_format.set_type(ss::conditional_format_t::condition); + m_cond_format.set_operator(ss::condition_operator_t::not_contains); + m_cond_format.set_formula(m_text); + break; + case beginsWith: + m_cond_format.set_type(ss::conditional_format_t::condition); + m_cond_format.set_operator(ss::condition_operator_t::begins_with); + m_cond_format.set_formula(m_text); + break; + case endsWith: + m_cond_format.set_type(ss::conditional_format_t::condition); + m_cond_format.set_operator(ss::condition_operator_t::ends_with); + m_cond_format.set_formula(m_text); + break; + case containsBlanks: + m_cond_format.set_type(ss::conditional_format_t::condition); + m_cond_format.set_operator(ss::condition_operator_t::contains_blanks); + break; + case containsErrors: + m_cond_format.set_type(ss::conditional_format_t::condition); + m_cond_format.set_operator(ss::condition_operator_t::contains_error); + break; + case notContainsErrors: + m_cond_format.set_type(ss::conditional_format_t::condition); + m_cond_format.set_operator(ss::condition_operator_t::contains_no_error); + break; + case timePeriod: + m_cond_format.set_type(ss::conditional_format_t::date); + switch (m_date) + { + case date_last7Days: + m_cond_format.set_date(ss::condition_date_t::last_7_days); + break; + case date_lastMonth: + m_cond_format.set_date(ss::condition_date_t::last_month); + break; + case date_lastWeek: + m_cond_format.set_date(ss::condition_date_t::last_week); + break; + case date_nextMonth: + m_cond_format.set_date(ss::condition_date_t::next_month); + break; + case date_thisMonth: + m_cond_format.set_date(ss::condition_date_t::this_month); + break; + case date_thisWeek: + m_cond_format.set_date(ss::condition_date_t::this_week); + break; + case date_today: + m_cond_format.set_date(ss::condition_date_t::today); + break; + case date_tomorrow: + m_cond_format.set_date(ss::condition_date_t::tomorrow); + break; + case date_yesterday: + m_cond_format.set_date(ss::condition_date_t::yesterday); + break; + default: + break; + } + break; + case aboveAverage: + m_cond_format.set_type(ss::conditional_format_t::condition); + if (!m_std_dev.empty()) + { + // TODO: we need a way to mark that as std dev in the interfaces + m_cond_format.set_formula(m_std_dev); + } + if (m_above_average) + { + if (m_equal_average) + { + m_cond_format.set_operator(ss::condition_operator_t::above_equal_average); + } + else + { + m_cond_format.set_operator(ss::condition_operator_t::above_average); + } + } + else + { + if (m_equal_average) + { + m_cond_format.set_operator(ss::condition_operator_t::below_equal_average); + } + else + { + m_cond_format.set_operator(ss::condition_operator_t::below_average); + } + } + break; + default: + break; + } + } + +private: + ss::iface::import_conditional_format& m_cond_format; + xlsx_cond_format_type m_type; + xlsx_cond_format_operator m_operator; + xlsx_cond_format_date m_date; + bool m_above_average; + bool m_equal_average; + bool m_percent; + bool m_bottom; + std::string_view m_text; + std::string_view m_std_dev; + std::string_view m_rank; +}; + +struct conditional_formatting_attr_parser +{ + conditional_formatting_attr_parser(ss::iface::import_conditional_format* cond_format): + m_cond_format(cond_format) + { + } + + void operator()(const xml_token_attr_t& attr) + { + switch (attr.name) + { + case XML_sqref: + m_cond_format->set_range(attr.value); + break; + } + } + +private: + ss::iface::import_conditional_format* m_cond_format; +}; + +enum xlsx_cond_format_cfvo_type +{ + cfvo_default = 0, + cfvo_num, + cfvo_percent, + cfvo_max, + cfvo_min, + cfvo_formula, + cfvo_percentile +}; + +typedef mdds::sorted_string_map<xlsx_cond_format_cfvo_type> cond_format_cfvo_type_map; + +cond_format_cfvo_type_map::entry cond_format_cfvo_entries[] = +{ + { MDDS_ASCII("num"), cfvo_num }, + { MDDS_ASCII("percent"), cfvo_percent }, + { MDDS_ASCII("max"), cfvo_max }, + { MDDS_ASCII("min"), cfvo_min }, + { MDDS_ASCII("formula"), cfvo_formula }, + { MDDS_ASCII("percentile"), cfvo_percentile }, +}; + +} + +struct cfvo_values +{ + cfvo_values(): + m_include_equal(true), + m_type(cfvo_default) + { + } + + bool m_include_equal; + xlsx_cond_format_cfvo_type m_type; + std::string_view m_value; +}; + +namespace { + +struct cfvo_attr_parser +{ + cfvo_attr_parser(string_pool& pool): + m_string_pool(pool) + { + } + + void operator()(const xml_token_attr_t& attr) + { + switch (attr.name) + { + case XML_gte: + m_values.m_include_equal = parse_boolean_flag(attr, true); + break; + case XML_type: + { + cond_format_cfvo_type_map cfvo_type_map(cond_format_cfvo_entries, sizeof(cond_format_cfvo_entries)/sizeof(cond_format_cfvo_entries[0]), cfvo_default); + m_values.m_type = cfvo_type_map.find(attr.value.data(), attr.value.size()); + } + break; + case XML_val: + if (attr.transient) + { + m_values.m_value = m_string_pool.intern(attr.value).first; + } + else + { + m_values.m_value = attr.value; + } + break; + default: + break; + } + } + + cfvo_values get_values() + { + return m_values; + } + +private: + cfvo_values m_values; + string_pool& m_string_pool; +}; + +struct data_bar_attr_parser +{ + data_bar_attr_parser(): + m_show_value(true), + m_min_length(10), + m_max_length(90) + { + } + + void operator()(const xml_token_attr_t& attr) + { + switch (attr.name) + { + case XML_showValue: + m_show_value = parse_boolean_flag(attr, true); + break; + case XML_maxLength: + m_max_length = to_long(attr.value); + break; + case XML_minLength: + m_min_length = to_long(attr.value); + break; + default: + break; + } + } + + void import_data(ss::iface::import_conditional_format& cond_format) + { + cond_format.set_show_value(m_show_value); + cond_format.set_min_databar_length(m_min_length); + cond_format.set_max_databar_length(m_max_length); + } + +private: + bool m_show_value; + size_t m_min_length; + size_t m_max_length; +}; + +struct icon_set_attr_parser +{ + icon_set_attr_parser(): + m_reverse(false), + m_percent(true), + m_show_value(true), + icon_name("3Arrows") + { + } + + void operator()(const xml_token_attr_t& attr) + { + switch (attr.name) + { + case XML_iconSet: + icon_name = attr.value; + break; + case XML_percent: + m_percent = parse_boolean_flag(attr, true); + break; + case XML_reverse: + m_reverse = parse_boolean_flag(attr, false); + break; + case XML_showValue: + m_show_value = parse_boolean_flag(attr, true); + break; + default: + break; + } + } + + void import_data(ss::iface::import_conditional_format& cond_format) + { + cond_format.set_show_value(m_show_value); + cond_format.set_iconset_reverse(m_reverse); + cond_format.set_icon_name(icon_name); + } + +private: + bool m_reverse; + bool m_percent; + bool m_show_value; + std::string_view icon_name; +}; + +} + +xlsx_conditional_format_context::xlsx_conditional_format_context( + session_context& session_cxt, const tokens& tokens, + ss::iface::import_conditional_format* import_cond_format): + xml_context_base(session_cxt, tokens), + m_cond_format(import_cond_format) +{ +} + +xlsx_conditional_format_context::~xlsx_conditional_format_context() +{ +} + +xml_context_base* xlsx_conditional_format_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void xlsx_conditional_format_context::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void xlsx_conditional_format_context::start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + + switch (name) + { + case XML_conditionalFormatting: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_worksheet); + if (m_cond_format) + std::for_each(attrs.begin(), attrs.end(), conditional_formatting_attr_parser(m_cond_format)); + break; + } + case XML_cfRule: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_conditionalFormatting); + if (m_cond_format) + { + cfRule_attr_parser parser = std::for_each(attrs.begin(), attrs.end(), cfRule_attr_parser(*m_cond_format)); + parser.set_type(); + } + break; + } + case XML_cfvo: + { + cfvo_attr_parser parser = std::for_each(attrs.begin(), attrs.end(), cfvo_attr_parser(m_pool)); + m_cfvo_values.push_back(parser.get_values()); + break; + } + case XML_dataBar: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_cfRule); + data_bar_attr_parser parser = std::for_each(attrs.begin(), attrs.end(), data_bar_attr_parser()); + if (m_cond_format) + parser.import_data(*m_cond_format); + break; + } + case XML_iconSet: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_cfRule); + icon_set_attr_parser parser = std::for_each(attrs.begin(), attrs.end(), icon_set_attr_parser()); + if (m_cond_format) + parser.import_data(*m_cond_format); + break; + } + case XML_color: + { + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_rgb: + { + argb_color color; + if (to_rgb(attr.value, color.alpha, color.red, color.green, color.blue)) + m_colors.push_back(color); + break; + } + default: + ; + } + } + break; + } + case XML_formula: + break; + case XML_colorScale: + break; + default: + warn_unhandled(); + } +} + +namespace { + +void import_cfvo(const cfvo_values& values, ss::iface::import_conditional_format& cond_format) +{ + if (!values.m_value.empty()) + cond_format.set_formula(values.m_value); + + switch (values.m_type) + { + case cfvo_num: + cond_format.set_condition_type(ss::condition_type_t::value); + break; + case cfvo_percent: + cond_format.set_condition_type(ss::condition_type_t::percent); + break; + case cfvo_max: + cond_format.set_condition_type(ss::condition_type_t::max); + break; + case cfvo_min: + cond_format.set_condition_type(ss::condition_type_t::min); + break; + case cfvo_formula: + cond_format.set_condition_type(ss::condition_type_t::formula); + break; + case cfvo_percentile: + cond_format.set_condition_type(ss::condition_type_t::percentile); + break; + default:; + } +} + +} + +bool xlsx_conditional_format_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + switch (name) + { + case XML_conditionalFormatting: + { + if (m_cond_format) + m_cond_format->commit_format(); + break; + } + case XML_cfRule: + { + if (m_cond_format) + m_cond_format->commit_entry(); + m_cfvo_values.clear(); + m_colors.clear(); + break; + } + case XML_cfvo: + break; + case XML_color: + break; + case XML_formula: + { + if (m_cond_format) + { + m_cond_format->set_formula(m_cur_str); + m_cond_format->commit_condition(); + } + break; + } + case XML_dataBar: + { + if (m_colors.size() != 1) + throw general_error("invalid dataBar record"); + + if (m_cfvo_values.size() != 2) + throw general_error("invalid dataBar record"); + + if (m_cond_format) + { + argb_color& color = m_colors[0]; + m_cond_format->set_databar_color_positive(color.alpha, color.red, + color.green, color.blue); + m_cond_format->set_databar_color_negative(color.alpha, color.red, + color.green, color.blue); + + for (const auto& cfvo : m_cfvo_values) + { + import_cfvo(cfvo, *m_cond_format); + m_cond_format->commit_condition(); + } + } + break; + } + case XML_iconSet: + { + if (m_cfvo_values.size() < 2) + throw general_error("invalid iconSet record"); + + if (m_cond_format) + { + for (const auto& cfvo : m_cfvo_values) + { + import_cfvo(cfvo, *m_cond_format); + m_cond_format->commit_condition(); + } + } + break; + } + case XML_colorScale: + { + if (m_cfvo_values.size() < 2) + throw general_error("invalid colorScale record"); + + if (m_cfvo_values.size() != m_colors.size()) + throw general_error("invalid colorScale record"); + + if (m_cond_format) + { + std::vector<argb_color>::const_iterator itrColor = m_colors.begin(); + for (std::vector<cfvo_values>::const_iterator itr = m_cfvo_values.begin(); itr != m_cfvo_values.end(); ++itr, ++itrColor) + { + import_cfvo(*itr, *m_cond_format); + m_cond_format->set_color(itrColor->alpha, itrColor->red, + itrColor->green, itrColor->blue); + m_cond_format->commit_condition(); + } + } + break; + } + } + + m_cur_str = std::string_view{}; + return pop_stack(ns, name); +} + +void xlsx_conditional_format_context::characters(std::string_view str, bool transient) +{ + m_cur_str = str; + if (transient) + m_cur_str = m_pool.intern(m_cur_str).first; +} + +void xlsx_conditional_format_context::reset() +{ + m_pool.clear(); + m_cur_str = std::string_view{}; + m_cfvo_values.clear(); + m_colors.clear(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_conditional_format_context.hpp b/src/liborcus/xlsx_conditional_format_context.hpp new file mode 100644 index 0000000..f03d53d --- /dev/null +++ b/src/liborcus/xlsx_conditional_format_context.hpp @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_XLSX_CONDITIONAL_FORMAT_CONTEXT_HPP +#define ORCUS_XLSX_CONDITIONAL_FORMAT_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "ooxml_types.hpp" +#include "xlsx_types.hpp" + +#include "orcus/spreadsheet/types.hpp" +#include "orcus/string_pool.hpp" + +namespace orcus { + +struct session_context; + +namespace spreadsheet { namespace iface { + class import_conditional_format; +} } + +struct cfvo_values; + +struct argb_color +{ + spreadsheet::color_elem_t alpha; + spreadsheet::color_elem_t red; + spreadsheet::color_elem_t green; + spreadsheet::color_elem_t blue; +}; + +class xlsx_conditional_format_context : public xml_context_base +{ +public: + + xlsx_conditional_format_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_conditional_format* import_cond_format); + virtual ~xlsx_conditional_format_context() override; + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name) override; + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) override; + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) override; + virtual bool end_element(xmlns_id_t ns, xml_token_t name) override; + virtual void characters(std::string_view str, bool transient) override; + + void reset(); + +private: + spreadsheet::iface::import_conditional_format* m_cond_format; + + string_pool m_pool; + std::string_view m_cur_str; + + std::vector<cfvo_values> m_cfvo_values; + std::vector<argb_color> m_colors; +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_drawing_context.cpp b/src/liborcus/xlsx_drawing_context.cpp new file mode 100644 index 0000000..606cd62 --- /dev/null +++ b/src/liborcus/xlsx_drawing_context.cpp @@ -0,0 +1,173 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xlsx_drawing_context.hpp" +#include "ooxml_namespace_types.hpp" +#include "ooxml_token_constants.hpp" +#include "ooxml_global.hpp" + +#include "orcus/measurement.hpp" + +#include <iostream> + +using namespace std; + +namespace orcus { + +xlsx_drawing_context::xlsx_drawing_context(session_context& cxt, const tokens& tkns) : + xml_context_base(cxt, tkns), + m_col(-1), m_row(-1), m_col_offset(-1), m_row_offset(-1) +{ + init_ooxml_context(*this); +} + +xlsx_drawing_context::~xlsx_drawing_context() {} + +xml_context_base* xlsx_drawing_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void xlsx_drawing_context::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void xlsx_drawing_context::start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& /*attrs*/) +{ + xml_token_pair_t parent = push_stack(ns, name); + + if (ns == NS_ooxml_xdr) + { + switch (name) + { + case XML_oneCellAnchor: + case XML_twoCellAnchor: + { + xml_element_expected(parent, NS_ooxml_xdr, XML_wsDr); + reset(); + break; + } + case XML_from: + case XML_sp: + case XML_clientData: + { + const xml_elem_set_t expected = { + { NS_ooxml_xdr, XML_absoluteAnchor }, + { NS_ooxml_xdr, XML_grpSp }, + { NS_ooxml_xdr, XML_oneCellAnchor }, + { NS_ooxml_xdr, XML_twoCellAnchor }, + }; + xml_element_expected(parent, expected); + break; + } + case XML_to: + { + xml_element_expected(parent, NS_ooxml_xdr, XML_twoCellAnchor); + break; + } + case XML_col: + case XML_colOff: + case XML_row: + case XML_rowOff: + { + xml_elem_stack_t expected; + expected.emplace_back(NS_ooxml_xdr, XML_from); + expected.emplace_back(NS_ooxml_xdr, XML_to); + xml_element_expected(parent, expected); + break; + } + case XML_nvSpPr: + case XML_style: + case XML_txBody: + { + const xml_elem_stack_t expected = { + { NS_ooxml_xdr, XML_cxnSp }, + { NS_ooxml_xdr, XML_sp }, + }; + xml_element_expected(parent, expected); + break; + } + case XML_spPr: + { + const xml_elem_stack_t expected = { + { NS_ooxml_xdr, XML_cxnSp }, + { NS_ooxml_xdr, XML_sp }, + { NS_ooxml_xdr, XML_pic }, + }; + xml_element_expected(parent, expected); + break; + } + default: + warn_unhandled(); + } + } + else if (ns == NS_ooxml_a) + { + warn_unhandled(); + } + else + warn_unhandled(); +} + +bool xlsx_drawing_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_ooxml_xdr) + { + switch (name) + { + case XML_twoCellAnchor: + case XML_oneCellAnchor: + if (get_config().debug) + cout << "col: " << m_col << "; row: " << m_row << "; col offset: " << m_col_offset << "; row offset: " << m_row_offset << endl; + break; + default: + ; + } + } + else if (ns == NS_ooxml_a) + { + + } + return pop_stack(ns, name); +} + +void xlsx_drawing_context::characters(std::string_view str, bool /*transient*/) +{ + xml_token_pair_t elem = get_current_element(); + if (elem.first == NS_ooxml_xdr) + { + switch (elem.second) + { + case XML_col: + m_col = to_long(str); + break; + case XML_row: + m_row = to_long(str); + break; + case XML_colOff: + m_col_offset = to_long(str); + break; + case XML_rowOff: + m_row_offset = to_long(str); + break; + default: + ; + } + } +} + +void xlsx_drawing_context::reset() +{ + m_col = -1; + m_row = -1; + m_col_offset = -1; + m_row_offset = -1; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_drawing_context.hpp b/src/liborcus/xlsx_drawing_context.hpp new file mode 100644 index 0000000..5089326 --- /dev/null +++ b/src/liborcus/xlsx_drawing_context.hpp @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_XLSX_DRAWING_CONTEXT_HPP +#define INCLUDED_ORCUS_XLSX_DRAWING_CONTEXT_HPP + +#include "xml_context_base.hpp" + +namespace orcus { + +struct session_context; +class tokens; + +class xlsx_drawing_context : public xml_context_base +{ + long m_col; + long m_row; + long m_col_offset; + long m_row_offset; + +public: + xlsx_drawing_context(session_context& cxt, const tokens& tkns); + + virtual ~xlsx_drawing_context(); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child); + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& attrs); + + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + + virtual void characters(std::string_view str, bool transient); + +private: + void reset(); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_handler.cpp b/src/liborcus/xlsx_handler.cpp new file mode 100644 index 0000000..e013bde --- /dev/null +++ b/src/liborcus/xlsx_handler.cpp @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xlsx_handler.hpp" +#include "xlsx_sheet_context.hpp" +#include "xlsx_table_context.hpp" +#include "xlsx_pivot_context.hpp" +#include "xlsx_drawing_context.hpp" + +#include <iostream> + +using namespace std; + +namespace orcus { + +xlsx_sheet_xml_handler::xlsx_sheet_xml_handler( + session_context& session_cxt, const tokens& t, + spreadsheet::sheet_t sheet_id, + spreadsheet::iface::import_reference_resolver& resolver, + spreadsheet::iface::import_sheet& sheet) : + xml_stream_handler(session_cxt, t, std::make_unique<xlsx_sheet_context>(session_cxt, t, sheet_id, resolver, sheet)) +{ +} + +xlsx_sheet_xml_handler::~xlsx_sheet_xml_handler() +{ +} + +void xlsx_sheet_xml_handler::pop_rel_extras(opc_rel_extras_t& other) +{ + xlsx_sheet_context& cxt = static_cast<xlsx_sheet_context&>(get_root_context()); + cxt.pop_rel_extras(other); +} + +xlsx_table_xml_handler::xlsx_table_xml_handler( + session_context& session_cxt, const tokens& t, + spreadsheet::iface::import_table& table, + spreadsheet::iface::import_reference_resolver& resolver) : + xml_stream_handler(session_cxt, t, std::make_unique<xlsx_table_context>(session_cxt, t, table, resolver)) +{ +} + +xlsx_pivot_cache_def_xml_handler::xlsx_pivot_cache_def_xml_handler( + session_context& cxt, const tokens& t, + spreadsheet::iface::import_pivot_cache_definition& pcache, + spreadsheet::pivot_cache_id_t pcache_id) : + xml_stream_handler(cxt, t, std::make_unique<xlsx_pivot_cache_def_context>(cxt, t, pcache, pcache_id)) {} + +opc_rel_extras_t xlsx_pivot_cache_def_xml_handler::pop_rel_extras() +{ + xlsx_pivot_cache_def_context& cxt = + static_cast<xlsx_pivot_cache_def_context&>(get_root_context()); + + return cxt.pop_rel_extras(); +} + +xlsx_pivot_cache_rec_xml_handler::xlsx_pivot_cache_rec_xml_handler( + session_context& cxt, const tokens& t, + spreadsheet::iface::import_pivot_cache_records& pc_records) : + xml_stream_handler(cxt, t, std::make_unique<xlsx_pivot_cache_rec_context>(cxt, t, pc_records)) {} + +xlsx_pivot_table_xml_handler::xlsx_pivot_table_xml_handler( + session_context& cxt, const tokens& t) : + xml_stream_handler(cxt, t, std::make_unique<xlsx_pivot_table_context>(cxt, t)) {} + +xlsx_drawing_xml_handler::xlsx_drawing_xml_handler( + session_context& cxt, const tokens& t) : + xml_stream_handler(cxt, t, std::make_unique<xlsx_drawing_context>(cxt, t)) {} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_handler.hpp b/src/liborcus/xlsx_handler.hpp new file mode 100644 index 0000000..81676c5 --- /dev/null +++ b/src/liborcus/xlsx_handler.hpp @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_XLSX_HANDLER_HPP +#define INCLUDED_ORCUS_XLSX_HANDLER_HPP + +#include "xml_stream_handler.hpp" +#include "xml_context_base.hpp" + +#include "orcus/spreadsheet/types.hpp" + +#include <string> +#include <vector> + +namespace orcus { + +struct session_context; +struct opc_rel_extras_t; + +namespace spreadsheet { namespace iface { + +class import_sheet; +class import_table; +class import_reference_resolver; +class import_pivot_cache_definition; +class import_pivot_cache_records; + +}} + +class xlsx_sheet_xml_handler : public xml_stream_handler +{ +public: + xlsx_sheet_xml_handler( + session_context& cxt, const tokens& t, + spreadsheet::sheet_t sheet_id, + spreadsheet::iface::import_reference_resolver& resolver, + spreadsheet::iface::import_sheet& sheet); + + virtual ~xlsx_sheet_xml_handler(); + + void pop_rel_extras(opc_rel_extras_t& other); +}; + +class xlsx_table_xml_handler : public xml_stream_handler +{ +public: + xlsx_table_xml_handler( + session_context& cxt, const tokens& t, + spreadsheet::iface::import_table& table, + spreadsheet::iface::import_reference_resolver& resolver); +}; + +class xlsx_pivot_cache_def_xml_handler : public xml_stream_handler +{ +public: + xlsx_pivot_cache_def_xml_handler( + session_context& cxt, const tokens& t, + spreadsheet::iface::import_pivot_cache_definition& pcache, + spreadsheet::pivot_cache_id_t pcache_id); + + opc_rel_extras_t pop_rel_extras(); +}; + +class xlsx_pivot_cache_rec_xml_handler : public xml_stream_handler +{ +public: + xlsx_pivot_cache_rec_xml_handler( + session_context& cxt, const tokens& t, + spreadsheet::iface::import_pivot_cache_records& pc_records); +}; + +class xlsx_pivot_table_xml_handler : public xml_stream_handler +{ +public: + xlsx_pivot_table_xml_handler(session_context& cxt, const tokens& t); +}; + +class xlsx_drawing_xml_handler : public xml_stream_handler +{ +public: + xlsx_drawing_xml_handler(session_context& cxt, const tokens& t); +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_helper.cpp b/src/liborcus/xlsx_helper.cpp new file mode 100644 index 0000000..9559d2b --- /dev/null +++ b/src/liborcus/xlsx_helper.cpp @@ -0,0 +1,33 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xlsx_helper.hpp" + +namespace orcus { + +bool to_rgb( + std::string_view ps, spreadsheet::color_elem_t& alpha, + spreadsheet::color_elem_t& red, spreadsheet::color_elem_t& green, spreadsheet::color_elem_t& blue) +{ + // RGB string is a 8-character string representing 32-bit hexadecimal + // number e.g. 'FF004A12' (alpha - red - green - blue) + size_t n = ps.size(); + if (n != 8) + return false; + + unsigned long v = strtoul(ps.data(), nullptr, 16); + blue = (0x000000FF & v); + green = (0x000000FF & (v >> 8)); + red = (0x000000FF & (v >> 16)); + alpha = (0x000000FF & (v >> 24)); + + return true; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_helper.hpp b/src/liborcus/xlsx_helper.hpp new file mode 100644 index 0000000..1643db1 --- /dev/null +++ b/src/liborcus/xlsx_helper.hpp @@ -0,0 +1,18 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/spreadsheet/types.hpp> + +namespace orcus { + +bool to_rgb(std::string_view ps, spreadsheet::color_elem_t& alpha, + spreadsheet::color_elem_t& red, spreadsheet::color_elem_t& gree, + spreadsheet::color_elem_t& blue); + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_pivot_context.cpp b/src/liborcus/xlsx_pivot_context.cpp new file mode 100644 index 0000000..026914d --- /dev/null +++ b/src/liborcus/xlsx_pivot_context.cpp @@ -0,0 +1,1734 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xlsx_pivot_context.hpp" +#include "ooxml_namespace_types.hpp" +#include "ooxml_token_constants.hpp" +#include "xml_context_global.hpp" +#include "session_context.hpp" +#include "xlsx_types.hpp" + +#include "orcus/measurement.hpp" +#include "orcus/spreadsheet/import_interface_pivot.hpp" + +#include <iostream> +#include <optional> +#include <mdds/sorted_string_map.hpp> + +using std::cout; +using std::endl; + +namespace orcus { + +namespace { + +namespace pc_source { + +using map_type = mdds::sorted_string_map<xlsx_pivot_cache_def_context::source_type, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "consolidation", xlsx_pivot_cache_def_context::source_type::consolidation }, + { "external", xlsx_pivot_cache_def_context::source_type::external }, + { "scenario", xlsx_pivot_cache_def_context::source_type::scenario }, + { "worksheet", xlsx_pivot_cache_def_context::source_type::worksheet }, +}; + +const map_type& get() +{ + static const map_type map( + entries, std::size(entries), + xlsx_pivot_cache_def_context::source_type::unknown); + + return map; +} + +} // namespace pc_source + +} + +xlsx_pivot_cache_def_context::xlsx_pivot_cache_def_context( + session_context& cxt, const tokens& tokens, + spreadsheet::iface::import_pivot_cache_definition& pcache, + spreadsheet::pivot_cache_id_t pcache_id) : + xml_context_base(cxt, tokens), m_pcache(pcache), m_pcache_id(pcache_id) {} + +xml_context_base* xlsx_pivot_cache_def_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void xlsx_pivot_cache_def_context::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void xlsx_pivot_cache_def_context::start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + if (ns != NS_ooxml_xlsx) + return; + + switch (name) + { + case XML_pivotCacheDefinition: + { + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + + std::string_view refreshed_by; + std::string_view rid; + long record_count = -1; + + for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (!attr.ns || attr.ns == NS_ooxml_xlsx) + { + switch (attr.name) + { + case XML_refreshedBy: + refreshed_by = attr.value; + break; + case XML_recordCount: + record_count = to_long(attr.value); + break; + default: + ; + } + } + else if (attr.ns == NS_ooxml_r) + { + switch (attr.name) + { + case XML_id: + // relation id for its cache record. + rid = attr.value; + break; + default: + ; + } + } + } + ); + + if (get_config().debug) + { + cout << "---" << endl; + cout << "pivot cache definition" << endl; + cout << "refreshed by: " << refreshed_by << endl; + cout << "record count: " << record_count << endl; + cout << "rid: " << rid << endl; + } + + if (!rid.empty()) + { + // The rid string here must be persistent beyond the current + // context. + rid = get_session_context().spool.intern(rid).first; + + m_pcache_info.data.insert( + opc_rel_extras_t::map_type::value_type( + rid, std::make_unique<xlsx_rel_pivot_cache_record_info>(m_pcache_id))); + } + + break; + } + case XML_cacheSource: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotCacheDefinition); + + std::string_view source_type_s; + + for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_type: + m_source_type = pc_source::get().find(attr.value); + source_type_s = attr.value; + break; + default: + ; + } + } + ); + + if (get_config().debug) + cout << "type: " << source_type_s << endl; + + break; + } + case XML_worksheetSource: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_cacheSource); + if (m_source_type != source_type::worksheet) + throw xml_structure_error( + "worksheetSource element encountered while the source type is not worksheet."); + + std::string_view ref, sheet_name, table_name; + + for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_ref: + ref = attr.value; + break; + case XML_sheet: + sheet_name = attr.value; + break; + case XML_name: + table_name = attr.value; + break; + default: + ; + } + } + ); + + if (get_config().debug) + { + cout << "table: " << table_name << endl; + cout << "ref: " << ref << endl; + cout << "sheet: " << sheet_name << endl; + } + + if (!table_name.empty()) + m_pcache.set_worksheet_source(table_name); + else + m_pcache.set_worksheet_source(ref, sheet_name); + break; + } + case XML_cacheFields: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotCacheDefinition); + single_long_attr_getter func(NS_ooxml_xlsx, XML_count); + long field_count = for_each(attrs.begin(), attrs.end(), func).get_value(); + + if (get_config().debug) + cout << "field count: " << field_count << endl; + + if (field_count < 0) + throw xml_structure_error("field count of a pivot cache must be positive."); + + m_pcache.set_field_count(field_count); + break; + } + case XML_cacheField: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_cacheFields); + + std::string_view field_name; + long numfmt_id = -1; + + for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_name: + field_name = attr.value; + break; + case XML_numFmtId: + numfmt_id = to_long(attr.value); + break; + default: + ; + } + } + ); + + // TODO : Handle number format ID here. + m_pcache.set_field_name(field_name); + + if (get_config().debug) + { + cout << "* name: " << field_name << endl; + cout << " number format id: " << numfmt_id << endl; + } + break; + } + case XML_fieldGroup: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_cacheField); + long group_parent = -1; + long group_base = -1; + + for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_par: + group_parent = to_long(attr.value); + break; + case XML_base: + group_base = to_long(attr.value); + break; + default: + ; + } + } + ); + + if (get_config().debug) + { + if (group_parent >= 0) + cout << " * group parent index: " << group_parent << endl; + if (group_base >= 0) + cout << " * group base index: " << group_base << endl; + } + + if (group_base >= 0) + { + // This is a group field. + m_pcache_field_group = m_pcache.start_field_group(group_base); + } + break; + } + case XML_discretePr: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_fieldGroup); + + long count = -1; + + for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_count: + count = to_long(attr.value); + break; + default: + ; + } + } + ); + + if (get_config().debug) + cout << " * group child member count: " << count << endl; + + break; + } + case XML_rangePr: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_fieldGroup); + + bool auto_start = true; + bool auto_end = true; + double start = 0.0; + double end = 0.0; + double interval = 1.0; + + std::optional<date_time_t> start_date; + std::optional<date_time_t> end_date; + + // Default group-by type appears to be 'range'. + spreadsheet::pivot_cache_group_by_t group_by = + spreadsheet::pivot_cache_group_by_t::range; + + for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_autoStart: + auto_start = to_bool(attr.value); + break; + case XML_autoEnd: + auto_end = to_bool(attr.value); + break; + case XML_startNum: + start = to_double(attr.value); + break; + case XML_endNum: + end = to_double(attr.value); + break; + case XML_groupInterval: + interval = to_double(attr.value); + break; + case XML_startDate: + start_date = date_time_t::from_chars(attr.value); + break; + case XML_endDate: + end_date = date_time_t::from_chars(attr.value); + break; + case XML_groupBy: + group_by = spreadsheet::to_pivot_cache_group_by_enum(attr.value); + break; + default: + ; + } + } + ); + + if (m_pcache_field_group) + { + // Pass the values to the interface. + m_pcache_field_group->set_range_grouping_type(group_by); + m_pcache_field_group->set_range_auto_start(auto_start); + m_pcache_field_group->set_range_auto_end(auto_end); + m_pcache_field_group->set_range_start_number(start); + m_pcache_field_group->set_range_end_number(end); + m_pcache_field_group->set_range_interval(interval); + + if (start_date) + m_pcache_field_group->set_range_start_date(*start_date); + if (end_date) + m_pcache_field_group->set_range_end_date(*end_date); + } + + if (get_config().debug) + { + cout << " auto start: " << auto_start << endl; + cout << " auto end: " << auto_end << endl; + cout << " start: " << start << endl; + cout << " end: " << end << endl; + cout << " interval: " << interval << endl; + + if (start_date) + cout << "start date: " << *start_date << endl; + if (end_date) + cout << "end date: " << *end_date << endl; + } + + break; + } + case XML_sharedItems: + { + start_element_shared_items(parent, attrs); + break; + } + case XML_groupItems: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_fieldGroup); + + long count = -1; + + for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_count: + count = to_long(attr.value); + break; + default: + ; + } + } + ); + + if (get_config().debug) + cout << " * group member count: " << count << endl; + + break; + } + case XML_s: + { + start_element_s(parent, attrs); + break; + } + case XML_n: + { + start_element_n(parent, attrs); + break; + } + case XML_d: + { + start_element_d(parent, attrs); + break; + } + case XML_e: + { + start_element_e(parent, attrs); + break; + } + case XML_x: + { + const xml_elem_set_t expected = { + { NS_ooxml_xlsx, XML_discretePr }, + { NS_ooxml_xlsx, XML_reference }, + }; + xml_element_expected(parent, expected); + + long index = -1; + + for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_v: + index = to_long(attr.value); + break; + default: + ; + } + } + ); + + if (index < 0) + throw xml_structure_error("element 'x' without a required attribute 'v'."); + + if (get_config().debug) + cout << " * index = " << index << endl; + + if (m_pcache_field_group) + m_pcache_field_group->link_base_to_group_items(index); + + break; + } + default: + warn_unhandled(); + } +} + +bool xlsx_pivot_cache_def_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_ooxml_xlsx) + { + switch (name) + { + case XML_pivotCacheDefinition: + { + m_pcache.commit(); + break; + } + case XML_cacheField: + { + m_pcache.commit_field(); + m_pcache_field_group = nullptr; + break; + } + case XML_discretePr: + { + break; + } + case XML_fieldGroup: + { + if (m_pcache_field_group) + m_pcache_field_group->commit(); + break; + } + case XML_s: + end_element_s(); + break; + case XML_n: + end_element_n(); + break; + case XML_d: + end_element_d(); + break; + case XML_e: + end_element_e(); + break; + default: + ; + } + } + + return pop_stack(ns, name); +} + +void xlsx_pivot_cache_def_context::characters(std::string_view /*str*/, bool /*transient*/) +{ +} + +opc_rel_extras_t xlsx_pivot_cache_def_context::pop_rel_extras() +{ + return std::move(m_pcache_info); +} + +void xlsx_pivot_cache_def_context::start_element_s( + const xml_token_pair_t& parent, const std::vector<xml_token_attr_t>& attrs) +{ + if (parent.first != NS_ooxml_xlsx) + { + warn_unhandled(); + return; + } + + std::string_view value; + + for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_v: + value = attr.value; + break; + default: + ; + } + } + ); + + switch (parent.second) + { + case XML_sharedItems: + { + // regular (non-group) field member name. + + if (get_config().debug) + cout << " * field member: " << value << endl; + + m_field_item_used = true; + m_pcache.set_field_item_string(value); + break; + } + case XML_groupItems: + { + // group field member name. + + if (get_config().debug) + cout << " * group field member: " << value << endl; + + m_field_item_used = true; + if (m_pcache_field_group) + m_pcache_field_group->set_field_item_string(value); + break; + } + default: + warn_unhandled(); + } +} + +void xlsx_pivot_cache_def_context::end_element_s() +{ + const xml_token_pair_t& parent = get_parent_element(); + if (parent.first != NS_ooxml_xlsx) + return; + + switch (parent.second) + { + case XML_sharedItems: + { + if (m_field_item_used) + m_pcache.commit_field_item(); + break; + } + case XML_groupItems: + { + if (m_pcache_field_group && m_field_item_used) + m_pcache_field_group->commit_field_item(); + break; + } + default: + ; + } +} + +void xlsx_pivot_cache_def_context::start_element_n( + const xml_token_pair_t& parent, const std::vector<xml_token_attr_t>& attrs) +{ + if (parent.first != NS_ooxml_xlsx) + { + warn_unhandled(); + return; + } + + switch (parent.second) + { + case XML_sharedItems: + { + // numeric item of a cache field. + double value = 0.0; + m_field_item_used = true; + + for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_v: + value = to_double(attr.value); + break; + case XML_u: + // flag for unused item. + m_field_item_used = !to_bool(attr.value); + default: + ; + } + } + ); + + if (get_config().debug) + { + cout << " * n: " << value; + if (!m_field_item_used) + cout << " (unused)"; + cout << endl; + + } + + if (m_field_item_used) + m_pcache.set_field_item_numeric(value); + + break; + } + default: + warn_unhandled(); + } +} + +void xlsx_pivot_cache_def_context::end_element_n() +{ + const xml_token_pair_t& parent = get_parent_element(); + if (parent.first != NS_ooxml_xlsx) + return; + + switch (parent.second) + { + case XML_sharedItems: + { + if (m_field_item_used) + m_pcache.commit_field_item(); + break; + } + default: + ; + } +} + +void xlsx_pivot_cache_def_context::start_element_d( + const xml_token_pair_t& parent, const std::vector<xml_token_attr_t>& attrs) +{ + if (parent.first != NS_ooxml_xlsx) + { + warn_unhandled(); + return; + } + + switch (parent.second) + { + case XML_sharedItems: + { + // date item of a cache field. + date_time_t dt; + m_field_item_used = true; + + for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_v: + dt = date_time_t::from_chars(attr.value); + break; + case XML_u: + // flag for unused item. + m_field_item_used = !to_bool(attr.value); + default: + ; + } + } + ); + + if (get_config().debug) + { + cout << " * d: " << dt; + if (!m_field_item_used) + cout << " (unused)"; + cout << endl; + + } + + if (m_field_item_used) + m_pcache.set_field_item_date_time(dt); + + break; + } + default: + ; + } +} + +void xlsx_pivot_cache_def_context::end_element_d() +{ + const xml_token_pair_t& parent = get_parent_element(); + if (parent.first != NS_ooxml_xlsx) + return; + + switch (parent.second) + { + case XML_sharedItems: + { + if (m_field_item_used) + m_pcache.commit_field_item(); + break; + } + default: + ; + } +} + +void xlsx_pivot_cache_def_context::start_element_e( + const xml_token_pair_t& parent, const std::vector<xml_token_attr_t>& attrs) +{ + if (parent.first != NS_ooxml_xlsx) + { + warn_unhandled(); + return; + } + + switch (parent.second) + { + case XML_sharedItems: + { + // error value item of a cache field. + spreadsheet::error_value_t ev = spreadsheet::error_value_t::unknown; + m_field_item_used = true; + + for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_v: + ev = spreadsheet::to_error_value_enum(attr.value); + break; + case XML_u: + // flag for unused item. + m_field_item_used = !to_bool(attr.value); + default: + ; + } + } + ); + + if (get_config().debug) + { + cout << " * e: " << ev; + if (!m_field_item_used) + cout << " (unused)"; + cout << endl; + } + + if (m_field_item_used) + m_pcache.set_field_item_error(ev); + + break; + } + default: + ; + } +} + +void xlsx_pivot_cache_def_context::end_element_e() +{ + const xml_token_pair_t& parent = get_parent_element(); + if (parent.first != NS_ooxml_xlsx) + return; + + switch (parent.second) + { + case XML_sharedItems: + { + if (m_field_item_used) + m_pcache.commit_field_item(); + break; + } + default: + ; + } +} + +void xlsx_pivot_cache_def_context::start_element_shared_items( + const xml_token_pair_t& parent, const std::vector<xml_token_attr_t>& attrs) +{ + xml_element_expected(parent, NS_ooxml_xlsx, XML_cacheField); + + // If "semi-mixed types" is set, the field contains text values and at + // least one other type. + bool semi_mixed_types = true; + + bool has_non_date = true; + bool has_date = false; + bool has_string = true; + bool has_blank = false; + + // If "mixed types" is set, the field contains more than one data types. + bool mixed_types = false; + + bool has_number = false; + bool has_integer = false; + bool has_long_text = false; + + long count = -1; + std::optional<double> min_value; + std::optional<double> max_value; + std::optional<date_time_t> min_date; + std::optional<date_time_t> max_date; + + for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_count: + count = to_long(attr.value); + break; + case XML_containsMixedTypes: + mixed_types = to_bool(attr.value); + break; + case XML_containsSemiMixedTypes: + semi_mixed_types = to_bool(attr.value); + break; + case XML_containsNonDate: + has_non_date = to_bool(attr.value); + break; + case XML_containsString: + has_string = to_bool(attr.value); + break; + case XML_containsBlank: + has_blank = to_bool(attr.value); + break; + case XML_containsNumber: + has_number = to_bool(attr.value); + break; + case XML_containsInteger: + has_integer = to_bool(attr.value); + break; + case XML_minValue: + min_value = to_double(attr.value); + break; + case XML_maxValue: + max_value = to_double(attr.value); + break; + case XML_minDate: + min_date = date_time_t::from_chars(attr.value); + break; + case XML_maxDate: + max_date = date_time_t::from_chars(attr.value); + break; + case XML_longText: + has_long_text = to_bool(attr.value); + break; + default: + ; + } + } + ); + + if (min_value) + m_pcache.set_field_min_value(*min_value); + + if (max_value) + m_pcache.set_field_max_value(*max_value); + + if (min_date) + m_pcache.set_field_min_date(*min_date); + + if (max_date) + m_pcache.set_field_max_date(*max_date); + + if (get_config().debug) + { + cout << " contains semi-mixed types: " << semi_mixed_types << endl; + cout << " contains non-date: " << has_non_date << endl; + cout << " contains date: " << has_date << endl; + cout << " contains string: " << has_string << endl; + cout << " contains blank: " << has_blank << endl; + cout << " contains mixed types: " << mixed_types << endl; + cout << " contains number: " << has_number << endl; + cout << " contains integer: " << has_integer << endl; + cout << " contains long text: " << has_long_text << endl; + cout << " count: " << count << endl; + + if (min_value) + cout << " min value: " << *min_value << endl; + if (max_value) + cout << " max value: " << *max_value << endl; + if (min_date) + cout << " min date: " << *min_date << endl; + if (max_date) + cout << " max date: " << *max_date << endl; + } +} + +xlsx_pivot_cache_rec_context::xlsx_pivot_cache_rec_context( + session_context& cxt, const tokens& tokens, + spreadsheet::iface::import_pivot_cache_records& pc_records) : + xml_context_base(cxt, tokens), + m_pc_records(pc_records) {} + +xml_context_base* xlsx_pivot_cache_rec_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void xlsx_pivot_cache_rec_context::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void xlsx_pivot_cache_rec_context::start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + + if (ns != NS_ooxml_xlsx) + return; + + switch (name) + { + case XML_pivotCacheRecords: + { + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + long count = single_long_attr_getter::get(attrs, NS_ooxml_xlsx, XML_count); + + if (get_config().debug) + { + cout << "---" << endl; + cout << "pivot cache record (count: " << count << ")" << endl; + } + + m_pc_records.set_record_count(count); + break; + } + case XML_r: // record + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotCacheRecords); + if (get_config().debug) + cout << "* record" << endl; + + break; + case XML_s: // character value + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_r); + + std::string_view cv = single_attr_getter::get(attrs, NS_ooxml_xlsx, XML_v); + + if (get_config().debug) + cout << " * s = '" << cv << "'" << endl; + + m_pc_records.append_record_value_character(cv); + break; + } + case XML_x: // shared item index + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_r); + long v = single_long_attr_getter::get(attrs, NS_ooxml_xlsx, XML_v); + if (get_config().debug) + cout << " * x = " << v << endl; + + m_pc_records.append_record_value_shared_item(v); + break; + } + case XML_n: // numeric + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_r); + double val = single_double_attr_getter::get(attrs, NS_ooxml_xlsx, XML_v); + if (get_config().debug) + cout << " * n = " << val << endl; + + m_pc_records.append_record_value_numeric(val); + break; + } + case XML_e: // error value + { + std::string_view cv = single_attr_getter::get(attrs, NS_ooxml_xlsx, XML_v); + + if (get_config().debug) + cout << " * e = " << cv << endl; + + break; + } + case XML_b: // boolean + case XML_d: // date time + case XML_m: // no value + default: + warn_unhandled(); + } +} + +bool xlsx_pivot_cache_rec_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_ooxml_xlsx) + { + switch (name) + { + case XML_pivotCacheRecords: + m_pc_records.commit(); + break; + case XML_r: // record + m_pc_records.commit_record(); + break; + default: + ; + } + } + + return pop_stack(ns, name); +} + +xlsx_pivot_table_context::xlsx_pivot_table_context(session_context& cxt, const tokens& tokens) : + xml_context_base(cxt, tokens) {} + +xml_context_base* xlsx_pivot_table_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void xlsx_pivot_table_context::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void xlsx_pivot_table_context::start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + if (ns == NS_ooxml_xlsx) + { + switch (name) + { + case XML_pivotTableDefinition: + { + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + if (get_config().debug) + cout << "---" << endl; + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + continue; + + long v = 0; + bool b = false; + + switch (attr.name) + { + case XML_name: + if (get_config().debug) + cout << "name: " << attr.value << endl; + break; + case XML_cacheId: + v = to_long(attr.value); + if (get_config().debug) + cout << "cache ID: " << v << endl; + break; + case XML_applyNumberFormats: + b = to_bool(attr.value); + if (get_config().debug) + cout << "apply number formats: " << b << endl; + break; + case XML_applyBorderFormats: + b = to_bool(attr.value); + if (get_config().debug) + cout << "apply border formats: " << b << endl; + break; + case XML_applyFontFormats: + b = to_bool(attr.value); + if (get_config().debug) + cout << "apply font formats: " << b << endl; + break; + case XML_applyPatternFormats: + b = to_bool(attr.value); + if (get_config().debug) + cout << "apply pattern formats: " << b << endl; + break; + case XML_applyAlignmentFormats: + b = to_bool(attr.value); + if (get_config().debug) + cout << "apply alignment formats: " << b << endl; + break; + case XML_applyWidthHeightFormats: + b = to_bool(attr.value); + if (get_config().debug) + cout << "apply width/height formats: " << b << endl; + break; + case XML_dataCaption: + if (get_config().debug) + cout << "data caption: " << attr.value << endl; + break; + case XML_updatedVersion: + v = to_long(attr.value); + if (get_config().debug) + cout << "updated version: " << v << endl; + break; + case XML_minRefreshableVersion: + v = to_long(attr.value); + if (get_config().debug) + cout << "minimum refreshable version: " << v << endl; + break; + case XML_showCalcMbrs: + b = to_bool(attr.value); + if (get_config().debug) + cout << "show calc members (?): " << b << endl; + break; + case XML_useAutoFormatting: + b = to_bool(attr.value); + if (get_config().debug) + cout << "use auto formatting: " << b << endl; + break; + case XML_itemPrintTitles: + b = to_bool(attr.value); + if (get_config().debug) + cout << "item print titles (?): " << b << endl; + break; + case XML_createdVersion: + v = to_long(attr.value); + if (get_config().debug) + cout << "created version: " << v << endl; + break; + case XML_indent: + b = to_bool(attr.value); + if (get_config().debug) + cout << "indent: " << b << endl; + break; + case XML_compact: + b = to_bool(attr.value); + if (get_config().debug) + cout << "compact: " << b << endl; + break; + case XML_compactData: + b = to_bool(attr.value); + if (get_config().debug) + cout << "compact data: " << b << endl; + break; + case XML_outline: + b = to_bool(attr.value); + if (get_config().debug) + cout << "outline: " << b << endl; + break; + case XML_outlineData: + b = to_bool(attr.value); + if (get_config().debug) + cout << "outline data: " << b << endl; + break; + case XML_gridDropZones: + b = to_bool(attr.value); + if (get_config().debug) + cout << "grid drop zones: " << b << endl; + break; + case XML_multipleFieldFilters: + b = to_bool(attr.value); + if (get_config().debug) + cout << "multiple field filters: " << b << endl; + break; + default: + ; + } + } + } + break; + case XML_location: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotTableDefinition); + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + continue; + + long v = -1; + switch (attr.name) + { + case XML_ref: + if (get_config().debug) + cout << "ref: " << attr.value << endl; + break; + case XML_firstHeaderRow: + v = to_long(attr.value); + if (get_config().debug) + cout << "first header row: " << v << endl; + break; + case XML_firstDataRow: + v = to_long(attr.value); + if (get_config().debug) + cout << "first data row: " << v << endl; + break; + case XML_firstDataCol: + v = to_long(attr.value); + if (get_config().debug) + cout << "first data column: " << v << endl; + break; + default: + ; + } + } + } + break; + case XML_pivotFields: + { + // pivotFields and its child elements represent the visual + // appearances of the fields inside pivot table. + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotTableDefinition); + size_t count = single_long_attr_getter::get(attrs, NS_ooxml_xlsx, XML_count); + if (get_config().debug) + cout << "field count: " << count << endl; + } + break; + case XML_pivotField: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotFields); + + if (get_config().debug) + cout << "---" << endl; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + continue; + + switch (attr.name) + { + case XML_axis: + if (get_config().debug) + cout << " * axis: " << attr.value << endl; + break; + case XML_compact: + { + bool b = to_bool(attr.value); + if (get_config().debug) + cout << " * compact: " << b << endl; + } + break; + case XML_outline: + { + bool b = to_bool(attr.value); + if (get_config().debug) + cout << " * outline: " << b << endl; + } + break; + case XML_showAll: + { + bool b = to_bool(attr.value); + if (get_config().debug) + cout << " * show all: " << b << endl; + } + break; + case XML_dataField: + { + bool b = to_bool(attr.value); + if (get_config().debug) + cout << " * data field: " << b << endl; + } + break; + default: + ; + } + } + } + break; + case XML_items: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotField); + size_t count = single_long_attr_getter::get(attrs, NS_ooxml_xlsx, XML_count); + if (get_config().debug) + cout << " * item count: " << count << endl; + } + break; + case XML_item: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_items); + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + continue; + + switch (attr.name) + { + case XML_x: + { + // field item index as defined in the pivot cache. + long idx = to_long(attr.value); + if (get_config().debug) + cout << " * x = " << idx << endl; + } + break; + case XML_t: + { + // When the <item> element has attribute 't', it's subtotal or + // some sort of function item. See 3.18.45 ST_ItemType + // (PivotItem Type) for possible values. + if (get_config().debug) + cout << " * type = " << attr.value << endl; + } + break; + default: + ; + } + } + } + break; + case XML_rowFields: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotTableDefinition); + size_t count = single_long_attr_getter::get(attrs, NS_ooxml_xlsx, XML_count); + if (get_config().debug) + { + cout << "---" << endl; + cout << "row field count: " << count << endl; + } + } + break; + case XML_colFields: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotTableDefinition); + size_t count = single_long_attr_getter::get(attrs, NS_ooxml_xlsx, XML_count); + if (get_config().debug) + { + cout << "---" << endl; + cout << "column field count: " << count << endl; + } + } + break; + case XML_pageFields: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotTableDefinition); + size_t count = single_long_attr_getter::get(attrs, NS_ooxml_xlsx, XML_count); + if (get_config().debug) + { + cout << "---" << endl; + cout << "page field count: " << count << endl; + } + } + break; + case XML_pageField: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_pageFields); + + if (get_config().debug) + cout << " * page field:"; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + continue; + + switch (attr.name) + { + case XML_fld: + { + long fld = to_long(attr.value); + if (get_config().debug) + cout << "field index = " << fld << "; "; + break; + } + case XML_item: + { + long item = to_long(attr.value); + if (get_config().debug) + cout << "item index = " << item << "; "; + break; + } + case XML_hier: + { + long hier = to_long(attr.value); + // -1 if not applicable. + if (get_config().debug) + cout << "OLAP hierarchy index = " << hier << "; "; + break; + } + default: + ; + } + } + + if (get_config().debug) + cout << endl; + break; + } + case XML_field: + { + xml_elem_stack_t expected; + expected.reserve(3); + expected.push_back(xml_token_pair_t(NS_ooxml_xlsx, XML_rowFields)); + expected.push_back(xml_token_pair_t(NS_ooxml_xlsx, XML_colFields)); + xml_element_expected(parent, expected); + + // Index into the list of <pivotField> collection which is + // given earlier under the <pivotFields> element. The value + // of -2 represents a special field that displays the list of + // data fields when the pivot table contains more than one + // data field. + long idx = single_long_attr_getter::get(attrs, NS_ooxml_xlsx, XML_x); + if (get_config().debug) + cout << " * x = " << idx << endl; + } + break; + case XML_dataFields: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotTableDefinition); + size_t count = single_long_attr_getter::get(attrs, NS_ooxml_xlsx, XML_count); + if (get_config().debug) + { + cout << "---" << endl; + cout << "data field count: " << count << endl; + } + } + break; + case XML_dataField: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_dataFields); + + if (get_config().debug) + cout << " * data field: "; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + continue; + + switch (attr.name) + { + case XML_name: + { + if (get_config().debug) + cout << "name = " << attr.value << "; "; + break; + } + case XML_fld: + { + long fld = to_long(attr.value); + if (get_config().debug) + cout << "field = " << fld << "; "; + break; + } + case XML_baseField: + { + long fld = to_long(attr.value); + if (get_config().debug) + cout << "base field = " << fld << "; "; + break; + } + case XML_baseItem: + { + long fld = to_long(attr.value); + if (get_config().debug) + cout << "base item = " << fld << "; "; + break; + } + case XML_subtotal: + { + if (get_config().debug) + cout << "subtotal = " << attr.value << "; "; + break; + } + default: + ; + } + } + + if (get_config().debug) + cout << endl; + } + break; + case XML_rowItems: + { + // <rowItems> structure describes the displayed content of + // cells in the row field area. Each <i> child element + // represents a single row. + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotTableDefinition); + size_t count = single_long_attr_getter::get(attrs, NS_ooxml_xlsx, XML_count); + if (get_config().debug) + { + cout << "---" << endl; + cout << "row item count: " << count << endl; + } + } + break; + case XML_colItems: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotTableDefinition); + size_t count = single_long_attr_getter::get(attrs, NS_ooxml_xlsx, XML_count); + if (get_config().debug) + { + cout << "---" << endl; + cout << "column item count: " << count << endl; + } + } + break; + case XML_i: + { + xml_elem_stack_t expected; + expected.reserve(2); + expected.push_back(xml_token_pair_t(NS_ooxml_xlsx, XML_rowItems)); + expected.push_back(xml_token_pair_t(NS_ooxml_xlsx, XML_colItems)); + xml_element_expected(parent, expected); + + if (get_config().debug) + cout << "---" << endl; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + continue; + + switch (attr.name) + { + case XML_t: + { + // total or subtotal function type. + if (get_config().debug) + cout << " * type = " << attr.value << endl; + } + break; + case XML_r: + { + // "repeated item count" which basically is the number of + // blank cells that occur after the preivous non-empty cell on + // the same row (in the classic layout mode). + long v = to_long(attr.value); + if (get_config().debug) + cout << " * repeat item count = " << v << endl; + } + break; + case XML_i: + { + // zero-based data field index in case of multiple data fields. + long v = to_long(attr.value); + if (get_config().debug) + cout << " * data field index = " << v << endl; + } + break; + default: + ; + } + } + } + break; + case XML_x: + { + if (parent.first != NS_ooxml_xlsx) + { + warn_unhandled(); + break; + } + + if (parent.second == XML_i) + { + long idx = single_long_attr_getter::get(attrs, NS_ooxml_xlsx, XML_v); + if (idx < 0) + // 0 is default when not set. + idx = 0; + + if (get_config().debug) + cout << " * v = " << idx << endl; + break; + } + + warn_unhandled(); + } + break; + case XML_pivotTableStyleInfo: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotTableDefinition); + + if (get_config().debug) + { + cout << "---" << endl; + cout << "* style info: "; + } + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + continue; + + bool b = false; + + switch (attr.name) + { + case XML_name: + if (get_config().debug) + cout << "name='" << attr.value << "'; "; + break; + case XML_showRowHeaders: + b = to_bool(attr.value); + if (get_config().debug) + cout << "show row headers=" << b << "; "; + break; + case XML_showColHeaders: + b = to_bool(attr.value); + if (get_config().debug) + cout << "show column headers=" << b << "; "; + break; + case XML_showRowStripes: + b = to_bool(attr.value); + if (get_config().debug) + cout << "show row stripes=" << b << "; "; + break; + case XML_showColStripes: + b = to_bool(attr.value); + if (get_config().debug) + cout << "show column stripes=" << b << "; "; + break; + case XML_showLastColumn: + b = to_bool(attr.value); + if (get_config().debug) + cout << "show last column=" << b << "; "; + break; + default: + ; + } + } + + if (get_config().debug) + cout << endl; + break; + } + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool xlsx_pivot_table_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + return pop_stack(ns, name); +} + +void xlsx_pivot_table_context::characters(std::string_view /*str*/, bool /*transient*/) +{ +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_pivot_context.hpp b/src/liborcus/xlsx_pivot_context.hpp new file mode 100644 index 0000000..f9610ba --- /dev/null +++ b/src/liborcus/xlsx_pivot_context.hpp @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_XLSX_PIVOT_CONTEXT_HPP +#define ORCUS_XLSX_PIVOT_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "ooxml_types.hpp" +#include "orcus/spreadsheet/types.hpp" + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_pivot_cache_definition; +class import_pivot_cache_field_group; +class import_pivot_cache_records; + +}} + +/** + * Base context for pivotCacheDefinition[n].xml part, which defines the + * structure of a pivot cache. + */ +class xlsx_pivot_cache_def_context : public xml_context_base +{ +public: + enum class source_type { + unknown = 0, + worksheet, + external, + consolidation, + scenario + }; + +private: + spreadsheet::iface::import_pivot_cache_definition& m_pcache; + spreadsheet::pivot_cache_id_t m_pcache_id; + spreadsheet::iface::import_pivot_cache_field_group* m_pcache_field_group = nullptr; + source_type m_source_type = source_type::unknown; + bool m_field_item_used = true; + + opc_rel_extras_t m_pcache_info; + +public: + xlsx_pivot_cache_def_context( + session_context& cxt, const tokens& tokens, + spreadsheet::iface::import_pivot_cache_definition& pcache, + spreadsheet::pivot_cache_id_t pcache_id); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child); + virtual void start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + virtual void characters(std::string_view str, bool transient); + + opc_rel_extras_t pop_rel_extras(); + +private: + void start_element_s(const xml_token_pair_t& parent, const std::vector<xml_token_attr_t>& attrs); + void end_element_s(); + + void start_element_n(const xml_token_pair_t& parent, const std::vector<xml_token_attr_t>& attrs); + void end_element_n(); + + void start_element_d(const xml_token_pair_t& parent, const std::vector<xml_token_attr_t>& attrs); + void end_element_d(); + + void start_element_e(const xml_token_pair_t& parent, const std::vector<xml_token_attr_t>& attrs); + void end_element_e(); + + void start_element_shared_items(const xml_token_pair_t& parent, const std::vector<xml_token_attr_t>& attrs); +}; + +/** + * Context for pivotCacheRecords[n].xml part, which contains the records in + * a pivot cache. + */ +class xlsx_pivot_cache_rec_context : public xml_context_base +{ + spreadsheet::iface::import_pivot_cache_records& m_pc_records; + +public: + xlsx_pivot_cache_rec_context( + session_context& cxt, const tokens& tokens, + spreadsheet::iface::import_pivot_cache_records& pc_records); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child); + virtual void start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); +}; + +/** + * Context for pivotTable[n].xml part which defines the structure of a pivot + * table model. + */ +class xlsx_pivot_table_context : public xml_context_base +{ +public: + xlsx_pivot_table_context(session_context& cxt, const tokens& tokens); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child); + virtual void start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + virtual void characters(std::string_view str, bool transient); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_revision_context.cpp b/src/liborcus/xlsx_revision_context.cpp new file mode 100644 index 0000000..637659f --- /dev/null +++ b/src/liborcus/xlsx_revision_context.cpp @@ -0,0 +1,578 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xlsx_revision_context.hpp" +#include "ooxml_namespace_types.hpp" +#include "ooxml_token_constants.hpp" +#include "session_context.hpp" +#include "xml_context_global.hpp" + +#include "orcus/measurement.hpp" +#include "orcus/string_pool.hpp" + +#include <iostream> +#include <limits> + +using namespace std; + +namespace orcus { + +namespace { + +class headers_attr_parser +{ + std::string_view m_guid; + long m_highest_revid; + long m_version; + bool m_disk_revisions; + +public: + headers_attr_parser() : m_highest_revid(-1), m_version(-1), m_disk_revisions(false) {} + + std::string_view get_last_guid() const { return m_guid; } + long get_highest_revid() const { return m_highest_revid; } + long get_version() const { return m_version; } + bool is_disk_revisions() const { return m_disk_revisions; } + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns != NS_ooxml_xlsx) + // All attributes are in the xlsx namespace. + return; + + switch (attr.name) + { + case XML_guid: + // guid should never be transient as it's not supposed to contain any encoded characters. + // TODO : We should convert guid to a numeric value here. + m_guid = attr.value; + break; + case XML_diskRevisions: + m_disk_revisions = to_long(attr.value) != 0; + break; + case XML_revisionId: + m_highest_revid = to_long(attr.value); + break; + case XML_version: + m_version = to_long(attr.value); + break; + default: + ; + } + } +}; + +class header_attr_parser +{ + string_pool* m_pool; + + std::string_view m_guid; + std::string_view m_username; + std::string_view m_rid; + + date_time_t m_date_time; + long m_next_sheet_id; + long m_min_revid; + long m_max_revid; + +public: + header_attr_parser(string_pool& pool) : + m_pool(&pool), m_next_sheet_id(-1), m_min_revid(-1), m_max_revid(-1) {} + + std::string_view get_guid() const { return m_guid; } + std::string_view get_username() const { return m_username; } + std::string_view get_rid() const { return m_rid; } + date_time_t get_date_time() const { return m_date_time; } + long get_next_sheet_id() const { return m_next_sheet_id; } + long get_min_revid() const { return m_min_revid; } + long get_max_revid() const { return m_max_revid; } + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns == NS_ooxml_xlsx) + { + switch (attr.name) + { + case XML_guid: + m_guid = attr.value; + break; + case XML_dateTime: + m_date_time = date_time_t::from_chars(attr.value); + break; + case XML_maxSheetId: + m_next_sheet_id = to_long(attr.value); + break; + case XML_userName: + m_username = attr.value; + if (attr.transient) + m_username = m_pool->intern(m_username).first; + break; + case XML_minRId: + m_min_revid = to_long(attr.value); + break; + case XML_maxRId: + m_max_revid = to_long(attr.value); + break; + default: + ; + } + } + else if (attr.ns == NS_ooxml_r && attr.name == XML_id) + { + // Pick up a rel id here. + if (attr.transient) + // Rel ID's should never be transient. + return; + + m_rid = attr.value; + } + } +}; + +} + +xlsx_revheaders_context::xlsx_revheaders_context(session_context& session_cxt, const tokens& tokens) : + xml_context_base(session_cxt, tokens) {} + +xlsx_revheaders_context::~xlsx_revheaders_context() {} + +xml_context_base* xlsx_revheaders_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void xlsx_revheaders_context::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void xlsx_revheaders_context::start_element(xmlns_id_t ns, xml_token_t name, const vector<xml_token_attr_t>& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + if (ns == NS_ooxml_xlsx) + { + switch (name) + { + case XML_headers: + { + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + headers_attr_parser func; + func = for_each(attrs.begin(), attrs.end(), func); + cout << "* last guid: " << func.get_last_guid() << endl; + cout << "* highest revision ID: " << func.get_highest_revid() << endl; + cout << "* version: " << func.get_version() << endl; + cout << "* disk revisions: " << func.is_disk_revisions() << endl; + } + break; + case XML_header: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_headers); + header_attr_parser func(get_session_context().spool); + func = for_each(attrs.begin(), attrs.end(), func); + cout << "* revision header (guid:" << func.get_guid() << ")" << endl; + cout << " - timestamp: " << func.get_date_time().to_string() << endl; + cout << " - user name: " << func.get_username() << endl; + + if (func.get_min_revid() != -1 && func.get_max_revid() != -1) + cout << " - revision range: " << func.get_min_revid() << "-" << func.get_max_revid() << endl; + + long next_sheet = func.get_next_sheet_id(); + if (next_sheet != -1) + cout << " - next available sheet: " << (next_sheet - 1) << endl; + + cout << " - revision log rid: " << func.get_rid() << endl; + // TODO : Intern the rid here when passing it to the revision log stream. + } + break; + case XML_sheetIdMap: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_header); + m_cur_sheet_ids.clear(); + long n = single_long_attr_getter::get(attrs, NS_ooxml_xlsx, XML_count); + if (n > 0) + m_cur_sheet_ids.reserve(n); + } + break; + case XML_sheetId: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_sheetIdMap); + long val = single_long_attr_getter::get(attrs, NS_ooxml_xlsx, XML_val); + if (val > 0) + m_cur_sheet_ids.push_back(val-1); // convert from 1-based to 0-based. + } + break; + default: + warn_unhandled(); + } + } +} + +bool xlsx_revheaders_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_ooxml_xlsx) + { + switch (name) + { + case XML_sheetIdMap: + { + cout << " - sheet indices: "; + for (size_t i = 0; i < m_cur_sheet_ids.size(); ++i) + cout << m_cur_sheet_ids[i] << " "; + cout << endl; + } + break; + default: + ; + } + } + return pop_stack(ns, name); +} + +void xlsx_revheaders_context::characters(std::string_view /*str*/, bool /*transient*/) +{ +} + +namespace { + +class rcc_attr_parser +{ + long m_revision_id; + long m_sheet_id; + +public: + rcc_attr_parser() : m_revision_id(-1), m_sheet_id(-1) {} + + long get_revision_id() const { return m_revision_id; } + long get_sheet_id() const { return m_sheet_id; } + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_rId: + // revision ID + m_revision_id = to_long(attr.value); + break; + case XML_sId: + // sheet ID + m_sheet_id = to_long(attr.value); + break; + default: + ; + } + } +}; + +class rrc_attr_parser +{ + long m_revision_id; + long m_sheet_id; + + std::string_view m_ref; + xlsx_rev_row_column_action_t m_action_type; + + bool m_end_of_list; + +public: + rrc_attr_parser() : m_revision_id(-1), m_sheet_id(-1), + m_action_type(xlsx_rev_rca_unknown), m_end_of_list(false) {} + + long get_revision_id() const { return m_revision_id; } + long get_sheet_id() const { return m_sheet_id; } + bool is_end_of_list() const { return m_end_of_list; } + std::string_view get_ref() const { return m_ref; } + xlsx_rev_row_column_action_t get_action_type() const { return m_action_type; } + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_rId: + // revision ID + m_revision_id = to_long(attr.value); + break; + case XML_sId: + // sheet ID + m_sheet_id = to_long(attr.value); + break; + case XML_eol: + m_end_of_list = to_long(attr.value) > 0; + break; + case XML_ref: + if (!attr.transient) + m_ref = attr.value; + break; + case XML_action: + m_action_type = to_xlsx_rev_row_column_action_type(attr.value); + break; + default: + ; + } + } +}; + +class cell_data_attr_parser +{ + std::string_view m_ref; + xlsx_cell_t m_type; + +public: + cell_data_attr_parser() : m_type(xlsx_ct_numeric) {} + + std::string_view get_ref() const { return m_ref; } + xlsx_cell_t get_cell_type() const { return m_type; } + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_r: + if (!attr.transient) + m_ref = attr.value; + break; + case XML_t: + m_type = to_xlsx_cell_type(attr.value); + default: + ; + } + } +}; + +} + +xlsx_revlog_context::xlsx_revlog_context(session_context& session_cxt, const tokens& tokens) : + xml_context_base(session_cxt, tokens), + m_cur_value(std::numeric_limits<double>::quiet_NaN()), + m_cur_cell_type(xlsx_ct_unknown), m_cur_formula(false) +{ +} + +xlsx_revlog_context::~xlsx_revlog_context() {} + +xml_context_base* xlsx_revlog_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void xlsx_revlog_context::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void xlsx_revlog_context::start_element(xmlns_id_t ns, xml_token_t name, const vector<xml_token_attr_t>& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + + if (ns == NS_ooxml_xlsx) + { + switch (name) + { + case XML_revisions: + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + break; + case XML_raf: + // revision auto format + xml_element_expected(parent, NS_ooxml_xlsx, XML_revisions); + break; + case XML_rcc: + { + // revision cell change + xml_element_expected(parent, NS_ooxml_xlsx, XML_revisions); + rcc_attr_parser func; + func = for_each(attrs.begin(), attrs.end(), func); + cout << "* revision id: " << func.get_revision_id() << " type: cell change" << endl; + cout << " - sheet index: " << func.get_sheet_id() << endl; + m_cur_cell_type = xlsx_ct_unknown; + } + break; + case XML_rcft: + // revision merge conflict + xml_element_expected(parent, NS_ooxml_xlsx, XML_revisions); + break; + case XML_rcmt: + // revision cell comment + xml_element_expected(parent, NS_ooxml_xlsx, XML_revisions); + break; + case XML_rcv: + // revision custom view + xml_element_expected(parent, NS_ooxml_xlsx, XML_revisions); + break; + case XML_rdn: + // revision defined name + xml_element_expected(parent, NS_ooxml_xlsx, XML_revisions); + break; + case XML_rfmt: + { + // revision format + const xml_elem_set_t expected = { + { NS_ooxml_xlsx, XML_revisions }, + { NS_ooxml_xlsx, XML_rm }, + { NS_ooxml_xlsx, XML_rrc }, + }; + xml_element_expected(parent, expected); + break; + } + case XML_ris: + // revision insert sheet + xml_element_expected(parent, NS_ooxml_xlsx, XML_revisions); + break; + case XML_rm: + // revision cell move + xml_element_expected(parent, NS_ooxml_xlsx, XML_revisions); + break; + case XML_rqt: + // revision query table + xml_element_expected(parent, NS_ooxml_xlsx, XML_revisions); + break; + case XML_rrc: + { + // revision row column insert delete + xml_element_expected(parent, NS_ooxml_xlsx, XML_revisions); + rrc_attr_parser func; + func = for_each(attrs.begin(), attrs.end(), func); + cout << "* revision id: " << func.get_revision_id() << " type: row column insert delete" << endl; + cout << " - sheet index: " << func.get_sheet_id() << endl; + cout << " - action type: " << to_string(func.get_action_type()) << endl; + cout << " - range: " << func.get_ref() << endl; + cout << " - end of list: " << (func.is_end_of_list() ? "true":"false") << endl; + } + break; + case XML_rsnm: + // revision sheet name + xml_element_expected(parent, NS_ooxml_xlsx, XML_revisions); + break; + case XML_oc: + // old cell data + xml_element_expected(parent, NS_ooxml_xlsx, XML_rcc); + break; + case XML_nc: + { + // new cell data + xml_element_expected(parent, NS_ooxml_xlsx, XML_rcc); + cell_data_attr_parser func; + func = for_each(attrs.begin(), attrs.end(), func); + m_cur_cell_type = func.get_cell_type(); + + m_cur_formula = false; + m_cur_value = 0.0; + m_cur_string = std::string_view{}; + + cout << " - new cell position: " << func.get_ref() << endl; + cout << " - new cell type: " << to_string(m_cur_cell_type) << endl; + } + break; + case XML_f: + { + xml_elem_stack_t elems; + elems.push_back(xml_token_pair_t(NS_ooxml_xlsx, XML_oc)); + elems.push_back(xml_token_pair_t(NS_ooxml_xlsx, XML_nc)); + xml_element_expected(parent, elems); + } + break; + case XML_v: + { + xml_elem_stack_t elems; + elems.push_back(xml_token_pair_t(NS_ooxml_xlsx, XML_oc)); + elems.push_back(xml_token_pair_t(NS_ooxml_xlsx, XML_nc)); + xml_element_expected(parent, elems); + } + break; + case XML_is: + { + xml_elem_stack_t elems; + elems.push_back(xml_token_pair_t(NS_ooxml_xlsx, XML_oc)); + elems.push_back(xml_token_pair_t(NS_ooxml_xlsx, XML_nc)); + xml_element_expected(parent, elems); + } + break; + case XML_t: + { + xml_elem_stack_t elems; + elems.push_back(xml_token_pair_t(NS_ooxml_xlsx, XML_is)); + elems.push_back(xml_token_pair_t(NS_ooxml_xlsx, XML_r)); + xml_element_expected(parent, elems); + } + break; + default: + warn_unhandled(); + } + } +} + +bool xlsx_revlog_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_ooxml_xlsx) + { + switch (name) + { + case XML_nc: + { + cout << " - new cell value: "; + switch (m_cur_cell_type) + { + case xlsx_ct_boolean: + if (m_cur_value != 0.0) + cout << "true"; + else + cout << "false"; + break; + case xlsx_ct_numeric: + if (m_cur_formula) + cout << m_cur_string; + else + cout << m_cur_value; + break; + case xlsx_ct_inline_string: + cout << m_cur_string; + break; + default: + ; + } + cout << endl; + } + break; + default: + ; + } + } + return pop_stack(ns, name); +} + +void xlsx_revlog_context::characters(std::string_view str, bool transient) +{ + xml_token_pair_t elem = get_current_element(); + if (elem.first == NS_ooxml_xlsx) + { + switch (elem.second) + { + case XML_v: + m_cur_value = to_double(str); + break; + case XML_f: + m_cur_formula = true; + // fall through to get the string. + case XML_t: + m_cur_string = str; + if (transient) + m_cur_string = get_session_context().spool.intern(m_cur_string).first; + break; + default: + ; + } + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_revision_context.hpp b/src/liborcus/xlsx_revision_context.hpp new file mode 100644 index 0000000..a560e07 --- /dev/null +++ b/src/liborcus/xlsx_revision_context.hpp @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_XLSX_REVHEADERS_CONTEXT_HPP +#define ORCUS_XLSX_REVHEADERS_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "xlsx_types.hpp" + +namespace orcus { + +class xlsx_revheaders_context : public xml_context_base +{ + std::vector<long> m_cur_sheet_ids; /// current sheet ID's. +public: + xlsx_revheaders_context(session_context& session_cxt, const tokens& tokens); + virtual ~xlsx_revheaders_context(); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child); + virtual void start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + virtual void characters(std::string_view str, bool transient); +}; + +class xlsx_revlog_context : public xml_context_base +{ + double m_cur_value; + std::string_view m_cur_string; + xlsx_cell_t m_cur_cell_type; + + bool m_cur_formula; + +public: + xlsx_revlog_context(session_context& session_cxt, const tokens& tokens); + virtual ~xlsx_revlog_context(); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child); + virtual void start_element(xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + virtual void characters(std::string_view str, bool transient); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_session_data.cpp b/src/liborcus/xlsx_session_data.cpp new file mode 100644 index 0000000..599a136 --- /dev/null +++ b/src/liborcus/xlsx_session_data.cpp @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xlsx_session_data.hpp" + +namespace orcus { + +xlsx_session_data::formula::formula( + spreadsheet::sheet_t _sheet, spreadsheet::row_t _row, spreadsheet::col_t _column, + std::string_view _exp) : + sheet(_sheet), exp(_exp) +{ + ref.column = _column; + ref.row = _row; +} + +xlsx_session_data::array_formula::array_formula( + spreadsheet::sheet_t _sheet, const spreadsheet::range_t& _ref, std::string_view _exp) : + sheet(_sheet), + ref(_ref), + exp(_exp), + results( + std::make_shared<range_formula_results>( + ref.last.row-ref.first.row+1, + ref.last.column-ref.first.column+1)) +{ +} + +xlsx_session_data::shared_formula::shared_formula( + spreadsheet::sheet_t _sheet, spreadsheet::row_t _row, spreadsheet::col_t _column, size_t _identifier) : + sheet(_sheet), row(_row), column(_column), identifier(_identifier), master(false) {} + +xlsx_session_data::shared_formula::shared_formula( + spreadsheet::sheet_t _sheet, spreadsheet::row_t _row, spreadsheet::col_t _column, + size_t _identifier, std::string_view _formula) : + sheet(_sheet), row(_row), column(_column), + identifier(_identifier), formula(_formula), master(true) {} + +xlsx_session_data::~xlsx_session_data() = default; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_session_data.hpp b/src/liborcus/xlsx_session_data.hpp new file mode 100644 index 0000000..af254d0 --- /dev/null +++ b/src/liborcus/xlsx_session_data.hpp @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_XLSX_SESSION_DATA_HPP +#define INCLUDED_ORCUS_XLSX_SESSION_DATA_HPP + +#include "session_context.hpp" +#include "formula_result.hpp" + +#include "orcus/spreadsheet/types.hpp" + +#include <string> +#include <vector> +#include <memory> +#include <unordered_map> + +namespace orcus { + +/** + * Collection of global data that need to be persistent across different + * parts during a single import session. + */ +struct xlsx_session_data : public session_context::custom_data +{ + struct formula + { + spreadsheet::sheet_t sheet; + spreadsheet::address_t ref; + std::string exp; + + formula_result result; + + formula( + spreadsheet::sheet_t _sheet, spreadsheet::row_t _row, spreadsheet::col_t _column, + std::string_view _exp); + }; + + struct array_formula + { + spreadsheet::sheet_t sheet; + spreadsheet::range_t ref; + std::string exp; + + std::shared_ptr<range_formula_results> results; + + array_formula( + spreadsheet::sheet_t sheet, const spreadsheet::range_t& ref, + std::string_view exp); + }; + + struct shared_formula + { + spreadsheet::sheet_t sheet; + spreadsheet::row_t row; + spreadsheet::col_t column; + size_t identifier; + std::string formula; + bool master; + + formula_result result; + + shared_formula( + spreadsheet::sheet_t _sheet, spreadsheet::row_t _row, spreadsheet::col_t _column, + size_t _identifier); + + shared_formula( + spreadsheet::sheet_t _sheet, spreadsheet::row_t _row, spreadsheet::col_t _column, + size_t _identifier, std::string_view _formula); + }; + + typedef std::vector<std::unique_ptr<formula>> formulas_type; + typedef std::vector<std::unique_ptr<array_formula>> array_formulas_type; + typedef std::vector<std::unique_ptr<shared_formula>> shared_formulas_type; + typedef std::unordered_map<std::string_view, spreadsheet::sheet_t> sheet_name_map_type; + + formulas_type m_formulas; + array_formulas_type m_array_formulas; + shared_formulas_type m_shared_formulas; + string_pool m_formula_result_strings; + + virtual ~xlsx_session_data(); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_shared_strings_context.cpp b/src/liborcus/xlsx_shared_strings_context.cpp new file mode 100644 index 0000000..29fac3e --- /dev/null +++ b/src/liborcus/xlsx_shared_strings_context.cpp @@ -0,0 +1,253 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xlsx_shared_strings_context.hpp" +#include "ooxml_token_constants.hpp" +#include "ooxml_namespace_types.hpp" +#include "xlsx_helper.hpp" +#include "xml_context_global.hpp" + +#include <orcus/spreadsheet/import_interface.hpp> +#include <orcus/measurement.hpp> + +#include <optional> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace { + +class shared_strings_root_attr_parser +{ +public: + shared_strings_root_attr_parser() : m_count(0), m_unique_count(0) {} + + void operator() (const xml_token_attr_t &attr) + { + switch (attr.name) + { + case XML_count: + m_count = to_long(attr.value); + break; + case XML_uniqueCount: + m_unique_count = to_long(attr.value); + break; + } + } + + shared_strings_root_attr_parser& operator= (const shared_strings_root_attr_parser& r) + { + m_count = r.m_count; + m_unique_count = r.m_unique_count; + return *this; + } + + size_t get_count() const { return m_count; } + size_t get_unique_count() const { return m_unique_count; } +private: + size_t m_count; + size_t m_unique_count; +}; + +} + +xlsx_shared_strings_context::xlsx_shared_strings_context(session_context& session_cxt, const tokens& tokens, spreadsheet::iface::import_shared_strings* strings) : + xml_context_base(session_cxt, tokens), mp_strings(strings), m_in_segments(false) {} + +xlsx_shared_strings_context::~xlsx_shared_strings_context() {} + +void xlsx_shared_strings_context::start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + switch (name) + { + case XML_sst: + { + // root element for the shared string part. + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + if (get_config().debug) + print_attrs(get_tokens(), attrs); + + shared_strings_root_attr_parser func; + func = for_each(attrs.begin(), attrs.end(), func); + + if (get_config().debug) + std::cout << "count: " << func.get_count() << " unique count: " << func.get_unique_count() << std::endl; + } + break; + case XML_si: + // single shared string entry. + m_in_segments = false; + xml_element_expected(parent, NS_ooxml_xlsx, XML_sst); + break; + case XML_r: + // rich text run + m_in_segments = true; + xml_element_expected(parent, NS_ooxml_xlsx, XML_si); + break; + case XML_rPr: + // rich text run property + xml_element_expected(parent, NS_ooxml_xlsx, XML_r); + break; + case XML_b: + // bold + xml_element_expected(parent, NS_ooxml_xlsx, XML_rPr); + break; + case XML_i: + // italic + xml_element_expected(parent, NS_ooxml_xlsx, XML_rPr); + break; + case XML_sz: + { + // font size + xml_element_expected(parent, NS_ooxml_xlsx, XML_rPr); + std::string_view s = for_each(attrs.begin(), attrs.end(), single_attr_getter(m_pool, NS_ooxml_xlsx, XML_val)).get_value(); + double point = to_double(s); + mp_strings->set_segment_font_size(point); + } + break; + case XML_color: + { + // font color + xml_element_expected(parent, NS_ooxml_xlsx, XML_rPr); + + std::optional<std::string_view> rgb; + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_rgb: + rgb = attr.value; + break; + case XML_theme: + // TODO : handle this. + break; + } + } + + if (rgb) + { + ss::color_elem_t alpha; + ss::color_elem_t red; + ss::color_elem_t green; + ss::color_elem_t blue; + if (to_rgb(*rgb, alpha, red, green, blue)) + mp_strings->set_segment_font_color(alpha, red, green, blue); + } + } + break; + case XML_rFont: + { + // font + xml_element_expected(parent, NS_ooxml_xlsx, XML_rPr); + std::string_view font = for_each(attrs.begin(), attrs.end(), single_attr_getter(m_pool, NS_ooxml_xlsx, XML_val)).get_value(); + mp_strings->set_segment_font_name(font); + } + break; + case XML_family: + // font family + xml_element_expected(parent, NS_ooxml_xlsx, XML_rPr); + break; + case XML_scheme: + // font scheme + xml_element_expected(parent, NS_ooxml_xlsx, XML_rPr); + break; + case XML_t: + { + // actual text stored as its content. + const xml_elem_set_t expected = { + { NS_ooxml_xlsx, XML_r }, + { NS_ooxml_xlsx, XML_rPh }, + { NS_ooxml_xlsx, XML_si }, + }; + xml_element_expected(parent, expected); + } + break; + default: + warn_unhandled(); + } +} + +bool xlsx_shared_strings_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + switch (name) + { + case XML_t: + break; + case XML_b: + mp_strings->set_segment_bold(true); + break; + case XML_i: + mp_strings->set_segment_italic(true); + break; + case XML_r: + mp_strings->append_segment(m_cur_str); + break; + case XML_si: + { + if (m_in_segments) + // commit all formatted segments. + mp_strings->commit_segments(); + else + { + // unformatted text should only have one text segment. + mp_strings->append(m_cur_str); + } + } + break; + } + return pop_stack(ns, name); +} + +void xlsx_shared_strings_context::characters(std::string_view str, bool transient) +{ + xml_token_pair_t cur_token = get_current_element(); + if (cur_token.first == NS_ooxml_xlsx && cur_token.second == XML_t) + { + m_cur_str = str; + + // In case the string contains carriage returns (CRs), remove them. + m_cell_buffer.reset(); + const char* p = m_cur_str.data(); + const char* p_end = p + m_cur_str.size(); + const char* p0 = nullptr; + + for (; p != p_end; ++p) + { + if (!p0) + p0 = p; + + if (*p == 0x0D) + { + // Append the segment up to this CR, and skip the CR. + m_cell_buffer.append(p0, std::distance(p0, p)); + p0 = nullptr; + } + } + + if (!m_cell_buffer.empty()) + { + // This string contains at least one CR. + + if (p0) + // Append the tail end. + m_cell_buffer.append(p0, std::distance(p0, p)); + + m_cur_str = m_pool.intern(m_cell_buffer.str()).first; + transient = false; + } + + if (transient) + m_cur_str = m_pool.intern(m_cur_str).first; + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_shared_strings_context.hpp b/src/liborcus/xlsx_shared_strings_context.hpp new file mode 100644 index 0000000..b10d9fd --- /dev/null +++ b/src/liborcus/xlsx_shared_strings_context.hpp @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <orcus/spreadsheet/types.hpp> +#include <orcus/string_pool.hpp> +#include <orcus/cell_buffer.hpp> + +#include "xml_context_base.hpp" +#include "xlsx_types.hpp" + +namespace orcus { + +namespace spreadsheet { namespace iface { + class import_shared_strings; +}} + +/** + * Context for xl/sharedStrings.xml part. + */ +class xlsx_shared_strings_context : public xml_context_base +{ +public: + xlsx_shared_strings_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_shared_strings* strings); + virtual ~xlsx_shared_strings_context(); + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + virtual void characters(std::string_view str, bool transient); + +private: + spreadsheet::iface::import_shared_strings* mp_strings = nullptr; + string_pool m_pool; + cell_buffer m_cell_buffer; + std::string_view m_cur_str; + bool m_in_segments; +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_sheet_context.cpp b/src/liborcus/xlsx_sheet_context.cpp new file mode 100644 index 0000000..1363c51 --- /dev/null +++ b/src/liborcus/xlsx_sheet_context.cpp @@ -0,0 +1,943 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xlsx_sheet_context.hpp" +#include "xlsx_session_data.hpp" +#include "xlsx_types.hpp" +#include "ooxml_global.hpp" +#include "ooxml_schemas.hpp" +#include "ooxml_token_constants.hpp" +#include "ooxml_namespace_types.hpp" +#include "xml_context_global.hpp" +#include "orcus/exception.hpp" +#include "orcus/spreadsheet/import_interface.hpp" +#include "orcus/spreadsheet/import_interface_view.hpp" +#include "orcus/measurement.hpp" + +#include <mdds/sorted_string_map.hpp> + +#include <algorithm> +#include <sstream> +#include <vector> +#include <optional> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace { + +namespace sheet_pane { + +using map_type = mdds::sorted_string_map<ss::sheet_pane_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "bottomLeft", ss::sheet_pane_t::bottom_left }, + { "bottomRight", ss::sheet_pane_t::bottom_right }, + { "topLeft", ss::sheet_pane_t::top_left }, + { "topRight", ss::sheet_pane_t::top_right }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::sheet_pane_t::unspecified); + return mt; +} + +} + +namespace pane_state { + +using map_type = mdds::sorted_string_map<ss::pane_state_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "frozen", ss::pane_state_t::frozen }, + { "frozenSplit", ss::pane_state_t::frozen_split }, + { "split", ss::pane_state_t::split }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::pane_state_t::unspecified); + return mt; +} + +} // namespace pane_state + +namespace formula_type { + +using map_type = mdds::sorted_string_map<ss::formula_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "array", ss::formula_t::array }, + { "dataTable", ss::formula_t::data_table }, + { "normal", ss::formula_t::normal }, + { "shared", ss::formula_t::shared }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::formula_t::unknown); + return mt; +} + +} // namespace formula_type + +} // anonymous namespace + +xlsx_sheet_context::formula::formula() : + type(ss::formula_t::unknown), + str(), + data_table_ref1(), + data_table_ref2(), + shared_id(-1), + data_table_2d(false), + data_table_row_based(false), + data_table_ref1_deleted(false), + data_table_ref2_deleted(false) +{ + ref.first.column = -1; + ref.first.row = -1; + ref.last = ref.first; +} + +void xlsx_sheet_context::formula::reset() +{ + *this = formula(); +} + +xlsx_sheet_context::xlsx_sheet_context( + session_context& session_cxt, const tokens& tokens, ss::sheet_t sheet_id, + ss::iface::import_reference_resolver& resolver, + ss::iface::import_sheet& sheet) : + xml_context_base(session_cxt, tokens), + m_resolver(resolver), + m_sheet(sheet), + m_sheet_id(sheet_id), + m_cur_row(-1), + m_cur_col(-1), + m_cur_cell_type(xlsx_ct_numeric), + m_cur_cell_xf(0), + m_cxt_autofilter(session_cxt, tokens, m_resolver), + m_cxt_cond_format(session_cxt, tokens, m_sheet.get_conditional_format()) +{ + register_child(&m_cxt_autofilter); + register_child(&m_cxt_cond_format); + + init_ooxml_context(*this); +} + +xlsx_sheet_context::~xlsx_sheet_context() +{ +} + +xml_context_base* xlsx_sheet_context::create_child_context(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_ooxml_xlsx && name == XML_autoFilter) + { + m_cxt_autofilter.reset(); + return &m_cxt_autofilter; + } + else if (ns == NS_ooxml_xlsx && name == XML_conditionalFormatting) + { + m_cxt_cond_format.reset(); + return &m_cxt_cond_format; + } + return nullptr; +} + +void xlsx_sheet_context::end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) +{ + if (!child) + return; + + if (ns == NS_ooxml_xlsx && name == XML_autoFilter) + { + ss::iface::import_auto_filter* af = m_sheet.get_auto_filter(); + if (!af) + return; + + const xlsx_autofilter_context& cxt = static_cast<const xlsx_autofilter_context&>(*child); + cxt.push_to_model(*af); + } +} + +void xlsx_sheet_context::start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + + if (ns == NS_ooxml_xlsx) + { + switch (name) + { + case XML_worksheet: + { + if (get_config().debug) + print_attrs(get_tokens(), attrs); + break; + } + case XML_cols: + xml_element_expected(parent, NS_ooxml_xlsx, XML_worksheet); + break; + case XML_col: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_cols); + start_element_col(attrs); + break; + } + case XML_dimension: + xml_element_expected(parent, NS_ooxml_xlsx, XML_worksheet); + break; + case XML_mergeCells: + xml_element_expected(parent, NS_ooxml_xlsx, XML_worksheet); + break; + case XML_mergeCell: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_mergeCells); + + ss::iface::import_sheet_properties* sheet_props = m_sheet.get_sheet_properties(); + if (sheet_props) + { + // ref contains merged range in A1 reference style. + std::string_view ref = for_each( + attrs.begin(), attrs.end(), single_attr_getter(m_pool, NS_ooxml_xlsx, XML_ref)).get_value(); + + ss::src_range_t range = m_resolver.resolve_range(ref); + sheet_props->set_merge_cell_range(to_rc_range(range)); + } + break; + } + case XML_pageMargins: + { + xml_elem_stack_t elems; + elems.push_back(xml_token_pair_t(NS_ooxml_xlsx, XML_worksheet)); + elems.push_back(xml_token_pair_t(NS_ooxml_xlsx, XML_customSheetView)); + xml_element_expected(parent, elems); + break; + } + case XML_sheetViews: + xml_element_expected(parent, NS_ooxml_xlsx, XML_worksheet); + break; + case XML_sheetView: + start_element_sheet_view(parent, attrs); + break; + case XML_selection: + start_element_selection(parent, attrs); + break; + case XML_pane: + start_element_pane(parent, attrs); + break; + case XML_sheetData: + xml_element_expected(parent, NS_ooxml_xlsx, XML_worksheet); + break; + case XML_sheetFormatPr: + xml_element_expected(parent, NS_ooxml_xlsx, XML_worksheet); + break; + case XML_row: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_sheetData); + start_element_row(attrs); + break; + } + case XML_c: + { + start_element_cell(parent, attrs); + break; + } + case XML_f: + start_element_formula(parent, attrs); + break; + case XML_v: + xml_element_expected(parent, NS_ooxml_xlsx, XML_c); + break; + case XML_tableParts: + xml_element_expected(parent, NS_ooxml_xlsx, XML_worksheet); + break; + case XML_tablePart: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_tableParts); + + // The rid string must be pooled to the session context's string + // pool as it is used long after thet sheet context is deleted. + single_attr_getter func(get_session_context().spool, NS_ooxml_r, XML_id); + std::string_view rid = for_each(attrs.begin(), attrs.end(), func).get_value(); + + std::unique_ptr<xlsx_rel_table_info> p(new xlsx_rel_table_info); + p->sheet_interface = &m_sheet; + m_rel_extras.data.insert( + opc_rel_extras_t::map_type::value_type(rid, std::move(p))); + break; + } + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool xlsx_sheet_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_ooxml_xlsx) + { + switch (name) + { + case XML_c: + end_element_cell(); + break; + case XML_f: + m_cur_formula.str = m_cur_str; + break; + case XML_v: + m_cur_value = m_cur_str; + break; + default: + ; + } + } + + m_cur_str = std::string_view{}; + return pop_stack(ns, name); +} + +void xlsx_sheet_context::characters(std::string_view str, bool transient) +{ + m_cur_str = intern_in_context(str, transient); +} + +void xlsx_sheet_context::start_element_formula(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs) +{ + const xml_elem_set_t expected = { + { NS_ooxml_xlsx, XML_c }, + { NS_mso_x14, XML_cfRule }, + }; + xml_element_expected(parent, expected); + + m_cur_formula.reset(); + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + continue; + + switch (attr.name) + { + case XML_t: + m_cur_formula.type = formula_type::get().find(attr.value); + break; + case XML_ref: + m_cur_formula.ref = to_rc_range(m_resolver.resolve_range(attr.value)); + break; + case XML_si: + m_cur_formula.shared_id = to_long(attr.value); + break; + case XML_dt2D: + m_cur_formula.data_table_2d = to_long(attr.value) != 0; + break; + case XML_dtr: + m_cur_formula.data_table_row_based = to_long(attr.value) != 0; + break; + case XML_del1: + m_cur_formula.data_table_ref1_deleted = to_long(attr.value) != 0; + break; + case XML_del2: + m_cur_formula.data_table_ref2_deleted = to_long(attr.value) != 0; + break; + case XML_r1: + m_cur_formula.data_table_ref1 = intern_in_context(attr); + break; + case XML_r2: + m_cur_formula.data_table_ref2 = intern_in_context(attr); + break; + default: + ; + } + } +} + +void xlsx_sheet_context::start_element_sheet_view( + const xml_token_pair_t& parent, const xml_token_attrs_t& attrs) +{ + xml_element_expected(parent, NS_ooxml_xlsx, XML_sheetViews); + + ss::iface::import_sheet_view* view = m_sheet.get_sheet_view(); + if (!view) + return; + + for (const xml_token_attr_t& attr : attrs) + { + if (!attr.ns || attr.ns == NS_ooxml_xlsx) + { + switch (attr.name) + { + case XML_tabSelected: + { + bool v = to_bool(attr.value); + if (v) + // This sheet is active. + view->set_sheet_active(); + break; + } + default: + ; + } + } + } +} + +void xlsx_sheet_context::start_element_selection( + const xml_token_pair_t& parent, const xml_token_attrs_t& attrs) +{ + xml_elem_stack_t elems; + elems.emplace_back(NS_ooxml_xlsx, XML_sheetView); + elems.emplace_back(NS_ooxml_xlsx, XML_customSheetView); + xml_element_expected(parent, elems); + + ss::iface::import_sheet_view* view = m_sheet.get_sheet_view(); + if (!view) + return; + + // example: <selection pane="topRight" activeCell="H2" sqref="H2:L2"/> + + ss::sheet_pane_t pane = ss::sheet_pane_t::unspecified; + ss::range_t range; + range.first.column = -1; + range.first.row = -1; + range.last = range.first; + + for (const xml_token_attr_t& attr : attrs) + { + if (!attr.ns || attr.ns == NS_ooxml_xlsx) + { + switch (attr.name) + { + case XML_pane: + { + pane = sheet_pane::get().find(attr.value); + break; + } + case XML_activeCell: + // Single cell where the cursor is. Ignore this for now. + break; + case XML_sqref: + { + // Single cell address for a non-range cursor, or range + // address if a range selection is present. + range = to_rc_range(m_resolver.resolve_range(attr.value)); + break; + } + default: + ; + } + } + } + + if (pane == ss::sheet_pane_t::unspecified) + pane = ss::sheet_pane_t::top_left; + + view->set_selected_range(pane, range); +} + +void xlsx_sheet_context::start_element_pane( + const xml_token_pair_t& parent, const xml_token_attrs_t& attrs) +{ + xml_elem_stack_t elems; + elems.emplace_back(NS_ooxml_xlsx, XML_sheetView); + elems.emplace_back(NS_ooxml_xlsx, XML_customSheetView); + xml_element_expected(parent, elems); + + ss::iface::import_sheet_view* view = m_sheet.get_sheet_view(); + if (!view) + return; + + // <pane xSplit="4" ySplit="8" topLeftCell="E9" activePane="bottomRight" state="frozen"/> + + double xsplit = 0.0, ysplit = 0.0; + ss::address_t top_left_cell; + ss::sheet_pane_t active_pane = ss::sheet_pane_t::unspecified; + ss::pane_state_t pane_state = ss::pane_state_t::unspecified; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + continue; + + switch (attr.name) + { + case XML_xSplit: + xsplit = to_double(attr.value); + break; + case XML_ySplit: + ysplit = to_double(attr.value); + break; + case XML_topLeftCell: + top_left_cell = to_rc_address(m_resolver.resolve_address(attr.value)); + break; + case XML_activePane: + active_pane = sheet_pane::get().find(attr.value); + break; + case XML_state: + pane_state = pane_state::get().find(attr.value); + break; + default: + ; + } + } + + if (active_pane == ss::sheet_pane_t::unspecified) + active_pane = ss::sheet_pane_t::top_left; + + if (pane_state == ss::pane_state_t::unspecified) + pane_state = ss::pane_state_t::split; + + switch (pane_state) + { + case ss::pane_state_t::frozen: + view->set_frozen_pane(xsplit, ysplit, top_left_cell, active_pane); + break; + case ss::pane_state_t::split: + view->set_split_pane(xsplit, ysplit, top_left_cell, active_pane); + break; + case ss::pane_state_t::frozen_split: + warn("FIXME: frozen-split state not yet handled."); + break; + default: + ; + } +} + +void xlsx_sheet_context::start_element_cell(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs) +{ + xlsx_cell_t cell_type = xlsx_ct_numeric; + ss::address_t address; + address.column = 0; + address.row = 0; + size_t xf = 0; + bool contains_address = false; + + xml_element_expected(parent, NS_ooxml_xlsx, XML_row); + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_r: + // cell address in A1 notation. + address = to_rc_address( + m_resolver.resolve_address(attr.value)); + + contains_address = true; + break; + case XML_t: + // cell type + cell_type = to_xlsx_cell_type(attr.value); + break; + case XML_s: + // cell style + xf = to_long(attr.value); + break; + } + } + + if (contains_address) + { + if (m_cur_row != address.row) + { + std::ostringstream os; + os << "row numbers differ! (current=" << m_cur_row << ")"; + throw xml_structure_error(os.str()); + } + + m_cur_col = address.column; + } + else + { + ++m_cur_col; + } + + m_cur_cell_type = cell_type; + m_cur_cell_xf = xf; +} + +void xlsx_sheet_context::start_element_col(const xml_token_attrs_t& attrs) +{ + long col_min = 0; // 1-based + long col_max = 0; // 1-based + bool col_hidden = false; + std::optional<double> col_width; + std::optional<std::size_t> xfid; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.value.empty()) + continue; + + switch (attr.name) + { + case XML_min: + col_min = to_long(attr.value); + break; + case XML_max: + col_max = to_long(attr.value); + break; + case XML_width: + col_width = to_double(attr.value); + break; + case XML_hidden: + col_hidden = to_long(attr.value); + break; + case XML_style: + xfid = to_long(attr.value); + break; + } + } + + if (!col_min || !col_max || col_min > col_max) + { + std::ostringstream os; + os << "column element has invalid column indices: (min=" << col_min << "; max=" << col_max << ")"; + warn(os.str()); + return; + } + + if (xfid) + m_sheet.set_column_format(col_min - 1, col_max - col_min + 1, *xfid); + + ss::iface::import_sheet_properties* sheet_props = m_sheet.get_sheet_properties(); + if (sheet_props) + { + if (col_width) + sheet_props->set_column_width( + col_min - 1, col_max - col_min + 1, *col_width, length_unit_t::xlsx_column_digit); + + sheet_props->set_column_hidden(col_min - 1, col_max - col_min + 1, col_hidden); + } +} + +void xlsx_sheet_context::start_element_row(const xml_token_attrs_t& attrs) +{ + std::optional<ss::row_t> row; + length_t height; + bool hidden = false; + bool custom_format = false; + std::optional<std::size_t> xfid; + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_r: + { + // row index + long this_row = to_long(attr.value); + if (!this_row) + throw xml_structure_error("row number can never be zero!"); + + this_row -= 1; // from 1-based to 0-based. + row = this_row; + break; + } + case XML_ht: + { + height.value = to_double(attr.value); + height.unit = length_unit_t::point; + break; + } + case XML_hidden: + hidden = to_long(attr.value) != 0; + break; + case XML_s: + xfid = to_long(attr.value); + break; + case XML_customFormat: + custom_format = to_bool(attr.value); + break; + } + } + + if (row) + m_cur_row = *row; + else + ++m_cur_row; + + m_cur_col = -1; + + if (custom_format && xfid) + // The specs say we only honor this style id only when the custom format is set. + m_sheet.set_row_format(m_cur_row, *xfid); + + ss::iface::import_sheet_properties* sheet_props = m_sheet.get_sheet_properties(); + if (sheet_props) + { + if (height.unit != length_unit_t::unknown) + sheet_props->set_row_height(m_cur_row, height.value, height.unit); + + sheet_props->set_row_hidden(m_cur_row, hidden); + } +} + +void xlsx_sheet_context::end_element_cell() +{ + session_context& cxt = get_session_context(); + auto& session_data = cxt.get_data<xlsx_session_data>(); + + bool array_formula_result = handle_array_formula_result(session_data); + + if (array_formula_result) + { + // Do nothing. + } + else if (!m_cur_formula.str.empty()) + { + if (m_cur_formula.type == ss::formula_t::shared && m_cur_formula.shared_id >= 0) + { + // shared formula expression + session_data.m_shared_formulas.push_back( + std::make_unique<xlsx_session_data::shared_formula>( + m_sheet_id, m_cur_row, m_cur_col, m_cur_formula.shared_id, + m_cur_formula.str + ) + ); + + xlsx_session_data::shared_formula& f = *session_data.m_shared_formulas.back(); + push_raw_cell_result(f.result, session_data); + } + else if (m_cur_formula.type == ss::formula_t::array) + { + // array formula expression + session_data.m_array_formulas.push_back( + std::make_unique<xlsx_session_data::array_formula>( + m_sheet_id, m_cur_formula.ref, m_cur_formula.str + ) + ); + + xlsx_session_data::array_formula& af = *session_data.m_array_formulas.back(); + push_raw_cell_result(*af.results, 0, 0, session_data); + m_array_formula_results.push_back(std::make_pair(m_cur_formula.ref, af.results)); + } + else + { + // normal (non-shared) formula expression + session_data.m_formulas.push_back( + std::make_unique<xlsx_session_data::formula>( + m_sheet_id, m_cur_row, m_cur_col, m_cur_formula.str + ) + ); + + xlsx_session_data::formula& f = *session_data.m_formulas.back(); + push_raw_cell_result(f.result, session_data); + } + } + else if (m_cur_formula.type == ss::formula_t::shared && m_cur_formula.shared_id >= 0) + { + // shared formula without formula expression + session_data.m_shared_formulas.push_back( + std::make_unique<xlsx_session_data::shared_formula>( + m_sheet_id, m_cur_row, m_cur_col, m_cur_formula.shared_id)); + + xlsx_session_data::shared_formula& f = *session_data.m_shared_formulas.back(); + push_raw_cell_result(f.result, session_data); + } + else if (m_cur_formula.type == ss::formula_t::data_table) + { + // Import data table. + ss::iface::import_data_table* dt = m_sheet.get_data_table(); + if (dt) + { + if (m_cur_formula.data_table_2d) + { + dt->set_type(ss::data_table_type_t::both); + dt->set_range(m_cur_formula.ref); + dt->set_first_reference( + m_cur_formula.data_table_ref1, + m_cur_formula.data_table_ref1_deleted); + dt->set_second_reference( + m_cur_formula.data_table_ref2, + m_cur_formula.data_table_ref2_deleted); + } + else if (m_cur_formula.data_table_row_based) + { + dt->set_type(ss::data_table_type_t::row); + dt->set_range(m_cur_formula.ref); + dt->set_first_reference( + m_cur_formula.data_table_ref1, + m_cur_formula.data_table_ref1_deleted); + } + else + { + dt->set_type(ss::data_table_type_t::column); + dt->set_range(m_cur_formula.ref); + dt->set_first_reference( + m_cur_formula.data_table_ref1, + m_cur_formula.data_table_ref1_deleted); + } + dt->commit(); + } + + push_raw_cell_value(); + } + else if (!m_cur_value.empty()) + { + push_raw_cell_value(); + } + + if (m_cur_cell_xf) + m_sheet.set_format(m_cur_row, m_cur_col, m_cur_cell_xf); + + // reset cell related parameters. + m_cur_value = std::string_view{}; + m_cur_formula.reset(); + m_cur_cell_xf = 0; + m_cur_cell_type = xlsx_ct_numeric; +} + +void xlsx_sheet_context::push_raw_cell_value() +{ + if (m_cur_value.empty()) + return; + + switch (m_cur_cell_type) + { + case xlsx_ct_shared_string: + { + // string cell + size_t str_id = to_long(m_cur_value); + m_sheet.set_string(m_cur_row, m_cur_col, str_id); + } + break; + case xlsx_ct_numeric: + { + // value cell + double val = to_double(m_cur_value); + m_sheet.set_value(m_cur_row, m_cur_col, val); + } + break; + case xlsx_ct_boolean: + { + // boolean cell + bool val = to_long(m_cur_value) != 0; + m_sheet.set_bool(m_cur_row, m_cur_col, val); + } + break; + default: + warn("unhanlded cell content type"); + } +} + +void xlsx_sheet_context::push_raw_cell_result( + range_formula_results& res, size_t row_offset, size_t col_offset, xlsx_session_data& /*session_data*/) const +{ + if (m_cur_value.empty()) + return; + + switch (m_cur_cell_type) + { + case xlsx_ct_numeric: + { + // value cell + double val = to_double(m_cur_value); + res.set(row_offset, col_offset, val); + break; + } + case xlsx_ct_boolean: + { + // boolean cell + bool val = to_long(m_cur_value) != 0; + res.set(row_offset, col_offset, val); + break; + } + default: + warn("unhanlded cell content type"); + } +} + +void xlsx_sheet_context::push_raw_cell_result(formula_result& res, xlsx_session_data& session_data) const +{ + switch (m_cur_cell_type) + { + case xlsx_ct_numeric: + res.type = formula_result::result_type::numeric; + res.value_numeric = to_double(m_cur_value); + break; + case xlsx_ct_formula_string: + { + std::string_view interned = session_data.m_formula_result_strings.intern(m_cur_value).first; + res.type = formula_result::result_type::string; + res.value_string.p = interned.data(); + res.value_string.n = interned.size(); + break; + } + default: + { + std::ostringstream os; + os << "unhandled cached formula result (type=" << m_cur_cell_type << ")"; + warn(os.str().data()); + } + } +} + +bool xlsx_sheet_context::handle_array_formula_result(xlsx_session_data& session_data) +{ + // See if the current cell is within an array formula range. + auto it = m_array_formula_results.begin(), ite = m_array_formula_results.end(); + + while (it != ite) + { + const ss::range_t& ref = it->first; + + if (ref.last.row < m_cur_row) + { + // If this result range lies above the current row, delete it as + // we no longer have use for it. + + m_array_formula_results.erase(it++); + continue; + } + + if (m_cur_col < ref.first.column || ref.last.column < m_cur_col || m_cur_row < ref.first.row || ref.last.row < m_cur_row) + { + // This cell is not within this array formula range. Move on to + // the next one. + ++it; + continue; + } + + size_t row_offset = m_cur_row - ref.first.row; + size_t col_offset = m_cur_col - ref.first.column; + range_formula_results& res = *it->second; + push_raw_cell_result(res, row_offset, col_offset, session_data); + + return true; + } + + return false; +} + +std::string_view xlsx_sheet_context::intern_in_context(const xml_token_attr_t& attr) +{ + return intern_in_context(attr.value, attr.transient); +} + +std::string_view xlsx_sheet_context::intern_in_context(const std::string_view& str, bool transient) +{ + if (transient) + return m_pool.intern(str).first; + + return str; +} + +void xlsx_sheet_context::pop_rel_extras(opc_rel_extras_t& other) +{ + m_rel_extras.swap(other); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_sheet_context.hpp b/src/liborcus/xlsx_sheet_context.hpp new file mode 100644 index 0000000..c91382d --- /dev/null +++ b/src/liborcus/xlsx_sheet_context.hpp @@ -0,0 +1,141 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_XLSX_SHEET_CONTEXT_HPP +#define ORCUS_XLSX_SHEET_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "ooxml_types.hpp" +#include "xlsx_types.hpp" +#include "xlsx_autofilter_context.hpp" +#include "xlsx_conditional_format_context.hpp" + +#include "orcus/spreadsheet/types.hpp" +#include "orcus/string_pool.hpp" + +#include <list> + +namespace orcus { + +struct session_context; +struct formula_result; +struct xlsx_session_data; +class range_formula_results; + +namespace spreadsheet { namespace iface { + +class import_sheet; +class import_reference_resolver; + +}} + +/** + * Top-level context for xl/worksheets/sheet<num>.xml. + */ +class xlsx_sheet_context : public xml_context_base +{ +public: + + struct formula + { + spreadsheet::formula_t type; + spreadsheet::range_t ref; /// formula reference range + std::string_view str; /// formula expression string + std::string_view data_table_ref1; + std::string_view data_table_ref2; + int shared_id; + bool data_table_2d:1; + bool data_table_row_based:1; + bool data_table_ref1_deleted:1; + bool data_table_ref2_deleted:1; + formula(); + + void reset(); + }; + + using array_formula_pair_type = std::pair<spreadsheet::range_t, std::shared_ptr<range_formula_results>>; + using array_formula_results_type = std::list<array_formula_pair_type>; + + xlsx_sheet_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::sheet_t sheet_id, + spreadsheet::iface::import_reference_resolver& resolver, + spreadsheet::iface::import_sheet& sheet); + virtual ~xlsx_sheet_context(); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child); + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + virtual void characters(std::string_view str, bool transient); + + void pop_rel_extras(opc_rel_extras_t& other); + +private: + void start_element_formula(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs); + void start_element_sheet_view(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs); + void start_element_selection(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs); + void start_element_pane(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs); + void start_element_cell(const xml_token_pair_t& parent, const xml_token_attrs_t& attrs); + void start_element_col(const xml_token_attrs_t& attrs); + void start_element_row(const xml_token_attrs_t& attrs); + + void end_element_cell(); + void push_raw_cell_value(); + void push_raw_cell_result(range_formula_results& res, size_t row_offset, size_t col_offset, xlsx_session_data& session_data) const; + void push_raw_cell_result(formula_result& res, xlsx_session_data& session_data) const; + + /** + * See if the current cell is a part of an array formula, and if so, store + * its value as a cached result. + * + * @return true if this is part of an array formula, false otherwise. + */ + bool handle_array_formula_result(xlsx_session_data& session_data); + + /** + * Potentially intern a transient attribute string value for the duration + * of the current sheet context. + */ + std::string_view intern_in_context(const xml_token_attr_t& attr); + + /** + * Potentially intern a transient string value for the duration of the + * current sheet context. + */ + std::string_view intern_in_context(const std::string_view& str, bool transient); + +private: + spreadsheet::iface::import_reference_resolver& m_resolver; + spreadsheet::iface::import_sheet& m_sheet; /// sheet model instance for the loaded document. + string_pool m_pool; + spreadsheet::sheet_t m_sheet_id; /// ID of this sheet. + spreadsheet::row_t m_cur_row; + spreadsheet::col_t m_cur_col; + xlsx_cell_t m_cur_cell_type; + size_t m_cur_cell_xf; + std::string_view m_cur_str; + std::string_view m_cur_value; + formula m_cur_formula; + + array_formula_results_type m_array_formula_results; + + /** + * Extra data to pass on to subsequent parts via relations. + */ + opc_rel_extras_t m_rel_extras; + + xlsx_autofilter_context m_cxt_autofilter; + xlsx_conditional_format_context m_cxt_cond_format; +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_sheet_context_test.cpp b/src/liborcus/xlsx_sheet_context_test.cpp new file mode 100644 index 0000000..20492b5 --- /dev/null +++ b/src/liborcus/xlsx_sheet_context_test.cpp @@ -0,0 +1,281 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "mock_spreadsheet.hpp" +#include "ooxml_namespace_types.hpp" +#include "ooxml_tokens.hpp" +#include "ooxml_schemas.hpp" +#include "xlsx_sheet_context.hpp" +#include "ooxml_token_constants.hpp" +#include "xlsx_session_data.hpp" +#include "orcus/types.hpp" +#include "orcus/config.hpp" + +using namespace orcus; +using namespace std; +using namespace orcus::spreadsheet; +using namespace orcus::spreadsheet::mock; + +namespace { + +class mock_ref_resolver : public import_reference_resolver +{ + virtual src_address_t resolve_address(std::string_view) override + { + src_address_t ret; + ret.sheet = 0; + ret.row = 0; + ret.column = 0; + + return ret; + } + + virtual src_range_t resolve_range(std::string_view) override + { + src_range_t ret; + ret.first.sheet = 0; + ret.first.row = 0; + ret.first.column = 0; + ret.last.sheet = 0; + ret.last.row = 0; + ret.last.column = 0; + + return ret; + } +}; + +class mock_array_formula : public import_array_formula +{ +public: + virtual void set_range(const range_t& range) override + { + assert(range.first.row == 2); + assert(range.first.column == 1); + assert(range.last.row == 3); + assert(range.last.column == 1); + } + + virtual void set_formula(formula_grammar_t grammar, std::string_view formula) override + { + assert(grammar == formula_grammar_t::xlsx); + assert(formula == "A1:A2"); + } + + virtual void set_result_bool(row_t, col_t, bool) override + { + } + + virtual void set_result_empty(row_t, col_t) override + { + } + + virtual void set_result_string(row_t, col_t, std::string_view) override + { + } + + virtual void set_result_value(row_t, col_t, double) override + { + } + + virtual void commit() override + { + } +}; + +class mock_sheet : public import_sheet +{ + mock_array_formula m_array_formula; + +public: + virtual void set_value(row_t row, col_t col, double val) override + { + assert(row == -1); + assert(col == 0); + assert(val == 5.0); + } + + virtual void set_bool(row_t row, col_t col, bool val) override + { + assert(row == -1); + assert(col == 0); + assert(val == true); + } + + virtual iface::import_array_formula* get_array_formula() override + { + return &m_array_formula; + } +}; + +class mock_sheet_properties : public import_sheet_properties +{ +public: + void set_column_hidden(col_t col, col_t col_span, bool hidden) + { + assert(col == 1); + assert(col_span == 1); + assert(hidden); + } + + void set_row_hidden(row_t row, bool hidden) + { + assert(row == 3); + assert(hidden); + } +}; + +class mock_sheet2 : public import_sheet +{ +public: + virtual import_sheet_properties* get_sheet_properties() + { + return &m_sheet_prop; + } + +private: + mock_sheet_properties m_sheet_prop; +}; + +void test_cell_value() +{ + mock_sheet sheet; + mock_ref_resolver resolver; + session_context cxt(std::make_unique<xlsx_session_data>()); + config opt(format_t::xlsx); + opt.structure_check = false; + + orcus::xlsx_sheet_context context(cxt, orcus::ooxml_tokens, 0, resolver, sheet); + context.set_config(opt); + + orcus::xmlns_id_t ns = NS_ooxml_xlsx; + orcus::xml_token_t elem = XML_c; + orcus::xml_token_attrs_t attrs; + context.start_element(ns, elem, attrs); + + { + xml_token_attrs_t val_attrs; + context.start_element(ns, XML_v, val_attrs); + context.characters("5", false); + context.end_element(ns, XML_v); + } + + context.end_element(ns, elem); +} + +void test_cell_bool() +{ + mock_sheet sheet; + mock_ref_resolver resolver; + session_context cxt(std::make_unique<xlsx_session_data>()); + config opt(format_t::xlsx); + opt.structure_check = false; + + orcus::xlsx_sheet_context context(cxt, orcus::ooxml_tokens, 0, resolver, sheet); + context.set_config(opt); + + orcus::xmlns_id_t ns = NS_ooxml_xlsx; + orcus::xml_token_t elem = XML_c; + orcus::xml_token_attrs_t attrs; + attrs.push_back(xml_token_attr_t(NS_ooxml_xlsx, XML_t, "b", false)); + context.start_element(ns, elem, attrs); + + { + xml_token_attrs_t val_attrs; + context.start_element(ns, XML_v, val_attrs); + context.characters("1", false); + context.end_element(ns, XML_v); + } + + context.end_element(ns, elem); +} + +void test_array_formula() +{ + mock_sheet sheet; + mock_ref_resolver resolver; + session_context cxt(std::make_unique<xlsx_session_data>()); + config opt(format_t::xlsx); + opt.structure_check = false; + + orcus::xlsx_sheet_context context(cxt, orcus::ooxml_tokens, 0, resolver, sheet); + context.set_config(opt); + + orcus::xmlns_id_t ns = NS_ooxml_xlsx; + orcus::xml_token_t elem = XML_c; + orcus::xml_token_attrs_t attrs; + context.start_element(ns, elem, attrs); + + { + xml_token_attrs_t formula_attrs; + formula_attrs.push_back(xml_token_attr_t(NS_ooxml_xlsx, XML_t, "array", false)); + formula_attrs.push_back(xml_token_attr_t(NS_ooxml_xlsx, XML_ref, "B3:B4", false)); + context.start_element(ns, XML_f, formula_attrs); + context.characters("A1:A2", false); + context.end_element(ns, XML_f); + } + { + xml_token_attrs_t val_attrs; + context.start_element(ns, XML_v, val_attrs); + context.characters("5", false); + context.end_element(ns, XML_v); + } + + context.end_element(ns, elem); +} + +void test_hidden_col() +{ + mock_sheet2 sheet; + mock_ref_resolver resolver; + session_context cxt(std::make_unique<xlsx_session_data>()); + config opt(format_t::xlsx); + opt.structure_check = false; + + orcus::xlsx_sheet_context context(cxt, orcus::ooxml_tokens, 0, resolver, sheet); + context.set_config(opt); + + orcus::xmlns_id_t ns = NS_ooxml_xlsx; + orcus::xml_token_t elem = XML_col; + orcus::xml_token_attrs_t attrs; + attrs.push_back(orcus::xml_token_attr_t(ns, XML_min, "2", false)); + attrs.push_back(orcus::xml_token_attr_t(ns, XML_max, "2", false)); + attrs.push_back(orcus::xml_token_attr_t(ns, XML_hidden, "1", false)); + context.start_element(ns, elem, attrs); + context.end_element(ns, elem); +} + +void test_hidden_row() +{ + mock_sheet2 sheet; + mock_ref_resolver resolver; + session_context cxt(std::make_unique<xlsx_session_data>()); + config opt(format_t::xlsx); + opt.structure_check = false; + + orcus::xlsx_sheet_context context(cxt, orcus::ooxml_tokens, 0, resolver, sheet); + context.set_config(opt); + + orcus::xmlns_id_t ns = NS_ooxml_xlsx; + orcus::xml_token_t elem = XML_row; + orcus::xml_token_attrs_t attrs; + attrs.push_back(orcus::xml_token_attr_t(ns, XML_r, "4", false)); + attrs.push_back(orcus::xml_token_attr_t(ns, XML_hidden, "1", false)); + context.start_element(ns, elem, attrs); + context.end_element(ns, elem); +} + +} + +int main() +{ + test_cell_value(); + test_cell_bool(); + test_array_formula(); + test_hidden_col(); + test_hidden_row(); + return 0; +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_styles_context.cpp b/src/liborcus/xlsx_styles_context.cpp new file mode 100644 index 0000000..29454b1 --- /dev/null +++ b/src/liborcus/xlsx_styles_context.cpp @@ -0,0 +1,1055 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xlsx_styles_context.hpp" +#include "impl_utils.hpp" +#include "ooxml_namespace_types.hpp" +#include "ooxml_token_constants.hpp" +#include "xlsx_helper.hpp" +#include "xml_context_global.hpp" + +#include <orcus/tokens.hpp> +#include <orcus/measurement.hpp> +#include <orcus/spreadsheet/import_interface_styles.hpp> + +#include <mdds/sorted_string_map.hpp> +#include <mdds/global.hpp> + +#include <optional> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace { + +namespace border_style { + +using map_type = mdds::sorted_string_map<ss::border_style_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "dashDot", ss::border_style_t::dash_dot }, + { "dashDotDot", ss::border_style_t::dash_dot_dot }, + { "dashed", ss::border_style_t::dashed }, + { "dotted", ss::border_style_t::dotted }, + { "double", ss::border_style_t::double_border }, + { "hair", ss::border_style_t::hair }, + { "medium", ss::border_style_t::medium }, + { "mediumDashDot", ss::border_style_t::medium_dash_dot }, + { "mediumDashDotDot", ss::border_style_t::medium_dash_dot_dot }, + { "mediumDashed", ss::border_style_t::medium_dashed }, + { "none", ss::border_style_t::none }, + { "slantDashDot", ss::border_style_t::slant_dash_dot }, + { "thick", ss::border_style_t::thick }, + { "thin", ss::border_style_t::thin } +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::border_style_t::none); + return mt; +} + +} // border_style namespace + +namespace fill_pattern { + +using map_type = mdds::sorted_string_map<ss::fill_pattern_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "darkDown", ss::fill_pattern_t::dark_down }, + { "darkGray", ss::fill_pattern_t::dark_gray }, + { "darkGrid", ss::fill_pattern_t::dark_grid }, + { "darkHorizontal", ss::fill_pattern_t::dark_horizontal }, + { "darkTrellis", ss::fill_pattern_t::dark_trellis }, + { "darkUp", ss::fill_pattern_t::dark_up }, + { "darkVertical", ss::fill_pattern_t::dark_vertical }, + { "gray0625", ss::fill_pattern_t::gray_0625 }, + { "gray125", ss::fill_pattern_t::gray_125 }, + { "lightDown", ss::fill_pattern_t::light_down }, + { "lightGray", ss::fill_pattern_t::light_gray }, + { "lightGrid", ss::fill_pattern_t::light_grid }, + { "lightHorizontal", ss::fill_pattern_t::light_horizontal }, + { "lightTrellis", ss::fill_pattern_t::light_trellis }, + { "lightUp", ss::fill_pattern_t::light_up }, + { "lightVertical", ss::fill_pattern_t::light_vertical }, + { "mediumGray", ss::fill_pattern_t::medium_gray }, + { "none", ss::fill_pattern_t::none }, + { "solid", ss::fill_pattern_t::solid }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::fill_pattern_t::none); + return mt; +} + +} // fill_pattern namespace + +namespace underline { + +using map_type = mdds::sorted_string_map<ss::underline_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "double", ss::underline_t::double_line }, + { "doubleAccounting", ss::underline_t::double_accounting }, + { "none", ss::underline_t::none }, + { "single", ss::underline_t::single_line }, + { "singleAccounting", ss::underline_t::single_accounting }, +}; + +const map_type& get() +{ + static const map_type mt(entries, std::size(entries), ss::underline_t::none); + return mt; +} + +} // namespace underline + +class border_attr_parser +{ + ss::border_direction_t m_dir; + ss::iface::import_border_style& m_border_style; +public: + border_attr_parser(ss::border_direction_t dir, ss::iface::import_border_style& style) : + m_dir(dir), m_border_style(style) {} + + void operator() (const xml_token_attr_t& attr) + { + switch (attr.name) + { + case XML_style: + { + m_border_style.set_style(m_dir, + border_style::get().find(attr.value.data(), attr.value.size())); + break; + } + } + } +}; + +std::optional<std::size_t> extract_count(const xml_token_attrs_t& attrs) +{ + std::optional<std::size_t> count; + + for (const auto& attr : attrs) + { + if (attr.ns) + continue; + + switch (attr.name) + { + case XML_count: + { + const char* p_end = nullptr; + long v = to_long(attr.value, &p_end); + if (attr.value.data() < p_end && v >= 0) + count = v; + break; + } + } + } + + return count; +} + +} // anonymous namespace + +xlsx_styles_context::xlsx_styles_context(session_context& session_cxt, const tokens& tokens, ss::iface::import_styles* styles) : + xml_context_base(session_cxt, tokens), + mp_styles(styles), + m_diagonal_up(false), m_diagonal_down(false), + m_cur_border_dir(ss::border_direction_t::unknown) +{ + static const xml_element_validator::rule rules[] = { + // parent element -> child element + { XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN, NS_ooxml_xlsx, XML_styleSheet }, // root element + { NS_ooxml_xlsx, XML_border, NS_ooxml_xlsx, XML_bottom }, + { NS_ooxml_xlsx, XML_border, NS_ooxml_xlsx, XML_diagonal }, + { NS_ooxml_xlsx, XML_border, NS_ooxml_xlsx, XML_left }, + { NS_ooxml_xlsx, XML_border, NS_ooxml_xlsx, XML_right }, + { NS_ooxml_xlsx, XML_border, NS_ooxml_xlsx, XML_top }, + { NS_ooxml_xlsx, XML_borders, NS_ooxml_xlsx, XML_border }, + { NS_ooxml_xlsx, XML_bottom, NS_ooxml_xlsx, XML_color }, + { NS_ooxml_xlsx, XML_cellStyleXfs, NS_ooxml_xlsx, XML_xf }, + { NS_ooxml_xlsx, XML_cellStyles, NS_ooxml_xlsx, XML_cellStyle }, + { NS_ooxml_xlsx, XML_cellXfs, NS_ooxml_xlsx, XML_xf }, + { NS_ooxml_xlsx, XML_diagonal, NS_ooxml_xlsx, XML_color }, + { NS_ooxml_xlsx, XML_dx, NS_ooxml_xlsx, XML_fill }, + { NS_ooxml_xlsx, XML_dxf, NS_ooxml_xlsx, XML_alignment }, + { NS_ooxml_xlsx, XML_dxf, NS_ooxml_xlsx, XML_border }, + { NS_ooxml_xlsx, XML_dxf, NS_ooxml_xlsx, XML_font }, + { NS_ooxml_xlsx, XML_dxf, NS_ooxml_xlsx, XML_numFmt }, + { NS_ooxml_xlsx, XML_dxf, NS_ooxml_xlsx, XML_protection }, + { NS_ooxml_xlsx, XML_end, NS_ooxml_xlsx, XML_color }, + { NS_ooxml_xlsx, XML_fill, NS_ooxml_xlsx, XML_patternFill }, + { NS_ooxml_xlsx, XML_fills, NS_ooxml_xlsx, XML_fill }, + { NS_ooxml_xlsx, XML_font, NS_ooxml_xlsx, XML_b }, + { NS_ooxml_xlsx, XML_font, NS_ooxml_xlsx, XML_color }, + { NS_ooxml_xlsx, XML_font, NS_ooxml_xlsx, XML_family }, + { NS_ooxml_xlsx, XML_font, NS_ooxml_xlsx, XML_i }, + { NS_ooxml_xlsx, XML_font, NS_ooxml_xlsx, XML_name }, + { NS_ooxml_xlsx, XML_font, NS_ooxml_xlsx, XML_scheme }, + { NS_ooxml_xlsx, XML_font, NS_ooxml_xlsx, XML_sz }, + { NS_ooxml_xlsx, XML_font, NS_ooxml_xlsx, XML_u }, + { NS_ooxml_xlsx, XML_fonts, NS_ooxml_xlsx, XML_font }, + { NS_ooxml_xlsx, XML_horizontal, NS_ooxml_xlsx, XML_color }, + { NS_ooxml_xlsx, XML_left, NS_ooxml_xlsx, XML_color }, + { NS_ooxml_xlsx, XML_mruColors, NS_ooxml_xlsx, XML_color }, + { NS_ooxml_xlsx, XML_numFmts, NS_ooxml_xlsx, XML_numFmt }, + { NS_ooxml_xlsx, XML_patternFill, NS_ooxml_xlsx, XML_bgColor }, + { NS_ooxml_xlsx, XML_patternFill, NS_ooxml_xlsx, XML_fgColor }, + { NS_ooxml_xlsx, XML_right, NS_ooxml_xlsx, XML_color }, + { NS_ooxml_xlsx, XML_start, NS_ooxml_xlsx, XML_color }, + { NS_ooxml_xlsx, XML_stop, NS_ooxml_xlsx, XML_color }, + { NS_ooxml_xlsx, XML_styleSheet, NS_ooxml_xlsx, XML_borders }, + { NS_ooxml_xlsx, XML_styleSheet, NS_ooxml_xlsx, XML_cellStyleXfs }, + { NS_ooxml_xlsx, XML_styleSheet, NS_ooxml_xlsx, XML_cellStyles }, + { NS_ooxml_xlsx, XML_styleSheet, NS_ooxml_xlsx, XML_cellXfs }, + { NS_ooxml_xlsx, XML_styleSheet, NS_ooxml_xlsx, XML_dxfs }, + { NS_ooxml_xlsx, XML_styleSheet, NS_ooxml_xlsx, XML_fills }, + { NS_ooxml_xlsx, XML_styleSheet, NS_ooxml_xlsx, XML_fonts }, + { NS_ooxml_xlsx, XML_styleSheet, NS_ooxml_xlsx, XML_numFmts }, + { NS_ooxml_xlsx, XML_top, NS_ooxml_xlsx, XML_color }, + { NS_ooxml_xlsx, XML_vertical, NS_ooxml_xlsx, XML_color }, + { NS_ooxml_xlsx, XML_xf, NS_ooxml_xlsx, XML_alignment }, + { NS_ooxml_xlsx, XML_xf, NS_ooxml_xlsx, XML_protection }, + }; + + init_element_validator(rules, std::size(rules)); +} + +xlsx_styles_context::~xlsx_styles_context() = default; + +void xlsx_styles_context::start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + + if (ns == NS_ooxml_xlsx) + { + switch (name) + { + case XML_styleSheet: + { + // root element + if (get_config().debug) + print_attrs(get_tokens(), attrs); + break; + } + case XML_fonts: + { + std::string_view ps = for_each( + attrs.begin(), attrs.end(), single_attr_getter(m_pool, NS_ooxml_xlsx, XML_count)).get_value(); + size_t font_count = to_long(ps); + mp_styles->set_font_count(font_count); + m_font_ids.reserve(font_count); + break; + } + case XML_font: + { + mp_font = mp_styles->start_font_style(); + ENSURE_INTERFACE(mp_font, import_font_style); + break; + } + case XML_b: + assert(mp_font); + mp_font->set_bold(true); + break; + case XML_i: + assert(mp_font); + mp_font->set_italic(true); + break; + case XML_u: + { + assert(mp_font); + ss::underline_t v = ss::underline_t::single_line; // default value + + for (const auto& attr : attrs) + { + switch (name) + { + case XML_val: + v = underline::get().find(attr.value); + break; + } + } + + mp_font->set_underline(v); + break; + } + case XML_sz: + { + assert(mp_font); + std::optional<double> font_size; + + for (const auto& attr : attrs) + { + switch (attr.name) + { + case XML_val: + { + const char* p_end = nullptr; + double v = to_double(attr.value, &p_end); + if (attr.value.data() < p_end) + font_size = v; + break; + } + } + } + + if (font_size) + mp_font->set_size(*font_size); + + break; + } + case XML_color: + { + if (parent.first == NS_ooxml_xlsx) + { + switch (parent.second) + { + case XML_top: + case XML_bottom: + case XML_left: + case XML_right: + case XML_diagonal: + // This color is for a border. + start_border_color(attrs); + break; + case XML_font: + start_font_color(attrs); + default: + ; + } + } + break; + } + case XML_name: + { + std::string_view ps = for_each( + attrs.begin(), attrs.end(), single_attr_getter(m_pool, NS_ooxml_xlsx, XML_val)).get_value(); + mp_font->set_name(ps); + break; + } + case XML_fills: + { + std::string_view ps = for_each( + attrs.begin(), attrs.end(), single_attr_getter(m_pool, NS_ooxml_xlsx, XML_count)).get_value(); + size_t fill_count = to_long(ps); + mp_styles->set_fill_count(fill_count); + m_fill_ids.reserve(fill_count); + break; + } + case XML_fill: + { + mp_fill = mp_styles->start_fill_style(); + ENSURE_INTERFACE(mp_fill, import_fill_style); + + break; + } + case XML_patternFill: + { + std::string_view ps = for_each( + attrs.begin(), attrs.end(), single_attr_getter(m_pool, NS_ooxml_xlsx, XML_patternType)).get_value(); + assert(mp_fill); + mp_fill->set_pattern_type(fill_pattern::get().find(ps.data(), ps.size())); + break; + } + case XML_fgColor: + { + assert(mp_fill); + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_rgb: + { + ss::color_elem_t alpha; + ss::color_elem_t red; + ss::color_elem_t green; + ss::color_elem_t blue; + if (!to_rgb(attr.value, alpha, red, green, blue)) + // invalid RGB color format. + continue; + + mp_fill->set_fg_color(alpha, red, green, blue); + break; + } + case XML_indexed: + break; + default: + if (get_config().debug) + std::cerr << "warning: unknown attribute [ " << get_tokens().get_token_name(attr.name) << " ]" << std::endl; + } + } + + break; + } + case XML_bgColor: + { + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_rgb: + { + ss::color_elem_t alpha; + ss::color_elem_t red; + ss::color_elem_t green; + ss::color_elem_t blue; + if (!to_rgb(attr.value, alpha, red, green, blue)) + // invalid RGB color format. + continue; + + mp_fill->set_bg_color(alpha, red, green, blue); + break; + } + case XML_indexed: + break; + default: + if (get_config().debug) + std::cerr << "warning: unknown attribute [ " << get_tokens().get_token_name(attr.name) << " ]" << std::endl; + } + } + + break; + } + case XML_borders: + { + std::string_view ps = for_each( + attrs.begin(), attrs.end(), single_attr_getter(m_pool, NS_ooxml_xlsx, XML_count)).get_value(); + size_t border_count = to_long(ps); + mp_styles->set_border_count(border_count); + m_border_ids.reserve(border_count); + break; + } + case XML_border: + { + start_element_border(attrs); + + mp_border = mp_styles->start_border_style(); + ENSURE_INTERFACE(mp_border, import_border_style); + + break; + } + case XML_top: + { + assert(mp_border); + m_cur_border_dir = ss::border_direction_t::top; + border_attr_parser func(ss::border_direction_t::top, *mp_border); + for_each(attrs.begin(), attrs.end(), func); + break; + } + case XML_bottom: + { + assert(mp_border); + m_cur_border_dir = ss::border_direction_t::bottom; + border_attr_parser func(ss::border_direction_t::bottom, *mp_border); + for_each(attrs.begin(), attrs.end(), func); + break; + } + case XML_left: + { + assert(mp_border); + m_cur_border_dir = ss::border_direction_t::left; + border_attr_parser func(ss::border_direction_t::left, *mp_border); + for_each(attrs.begin(), attrs.end(), func); + break; + } + case XML_right: + { + assert(mp_border); + m_cur_border_dir = ss::border_direction_t::right; + border_attr_parser func(ss::border_direction_t::right, *mp_border); + for_each(attrs.begin(), attrs.end(), func); + break; + } + case XML_diagonal: + { + start_element_diagonal(attrs); + break; + } + case XML_cellStyleXfs: + { + if (std::optional<std::size_t> count = extract_count(attrs); count) + { + mp_styles->set_xf_count(ss::xf_category_t::cell_style, *count); + m_cell_style_xf_ids.reserve(*count); + } + + mp_xf = mp_styles->start_xf(ss::xf_category_t::cell_style); + ENSURE_INTERFACE(mp_xf, import_xf); + m_xf_type = ss::xf_category_t::cell_style; + break; + } + case XML_cellXfs: + { + if (std::optional<std::size_t> count = extract_count(attrs); count) + mp_styles->set_xf_count(ss::xf_category_t::cell, *count); + + mp_xf = mp_styles->start_xf(ss::xf_category_t::cell); + ENSURE_INTERFACE(mp_xf, import_xf); + m_xf_type = ss::xf_category_t::cell; + break; + } + case XML_dxfs: + { + if (std::optional<std::size_t> count = extract_count(attrs); count) + mp_styles->set_xf_count(ss::xf_category_t::differential, *count); + + mp_xf = mp_styles->start_xf(ss::xf_category_t::differential); + ENSURE_INTERFACE(mp_xf, import_xf); + m_xf_type = ss::xf_category_t::differential; + break; + } + case XML_cellStyles: + { + std::string_view ps = for_each( + attrs.begin(), attrs.end(), single_attr_getter(m_pool, NS_ooxml_xlsx, XML_count)).get_value(); + if (!ps.empty()) + { + size_t n = strtoul(ps.data(), nullptr, 10); + mp_styles->set_cell_style_count(n); + } + mp_cell_style = mp_styles->start_cell_style(); + ENSURE_INTERFACE(mp_cell_style, import_cell_style); + break; + } + case XML_cellStyle: + { + // named cell style, some of which are built-in such as 'Normal'. + assert(mp_cell_style); + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_name: + mp_cell_style->set_name(attr.value); + break; + case XML_xfId: + { + // reference ID to an xf entry in cellStyleXfs + const char* p_end = nullptr; + size_t n = to_long(attr.value, &p_end); + if (attr.value.data() < p_end) + { + if (n < m_cell_style_xf_ids.size()) + mp_cell_style->set_xf(m_cell_style_xf_ids[n]); + else + { + std::ostringstream os; + os << "out-of-bound cellStyle@xfId: id=" << n << "; count=" << m_cell_style_xf_ids.size(); + warn(os.str()); + } + } + break; + } + case XML_builtinId: + { + size_t n = to_long(attr.value); + mp_cell_style->set_builtin(n); + } + break; + } + } + break; + } + case XML_xf: + { + start_xf(attrs); + break; + } + case XML_protection: + { + mp_protection = mp_styles->start_cell_protection(); + ENSURE_INTERFACE(mp_protection, import_cell_protection); + + for (const auto& attr : attrs) + { + switch (attr.name) + { + case XML_hidden: + { + bool b = to_long(attr.value) != 0; + mp_protection->set_hidden(b); + break; + } + case XML_locked: + { + bool b = to_long(attr.value) != 0; + mp_protection->set_locked(b); + break; + } + } + } + + break; + } + case XML_alignment: + { + assert(mp_xf); + + // NB: default vertical alignment is 'bottom'. + ss::hor_alignment_t hor_align = ss::hor_alignment_t::unknown; + ss::ver_alignment_t ver_align = ss::ver_alignment_t::bottom; + bool wrap_text = false; + bool shrink_to_fit = false; + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_horizontal: + { + if (attr.value == "center") + hor_align = ss::hor_alignment_t::center; + else if (attr.value == "right") + hor_align = ss::hor_alignment_t::right; + else if (attr.value == "left") + hor_align = ss::hor_alignment_t::left; + else if (attr.value == "justify") + hor_align = ss::hor_alignment_t::justified; + else if (attr.value == "distributed") + hor_align = ss::hor_alignment_t::distributed; + break; + } + case XML_vertical: + { + if (attr.value == "top") + ver_align = ss::ver_alignment_t::top; + else if (attr.value == "center") + ver_align = ss::ver_alignment_t::middle; + else if (attr.value == "bottom") + ver_align = ss::ver_alignment_t::bottom; + else if (attr.value == "justify") + ver_align = ss::ver_alignment_t::justified; + else if (attr.value == "distributed") + ver_align = ss::ver_alignment_t::distributed; + break; + } + case XML_wrapText: + wrap_text = to_bool(attr.value); + break; + case XML_shrinkToFit: + shrink_to_fit = to_bool(attr.value); + break; + } + } + + mp_xf->set_horizontal_alignment(hor_align); + mp_xf->set_vertical_alignment(ver_align); + mp_xf->set_wrap_text(wrap_text); + mp_xf->set_shrink_to_fit(shrink_to_fit); + break; + } + case XML_numFmts: + { + std::string_view val = + for_each( + attrs.begin(), attrs.end(), + single_attr_getter(m_pool, NS_ooxml_xlsx, XML_count)).get_value(); + if (!val.empty()) + { + size_t n = to_long(val); + mp_styles->set_number_format_count(n); + } + break; + } + case XML_numFmt: + start_number_format(attrs); + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool xlsx_styles_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + switch (name) + { + case XML_font: + { + assert(mp_font); + std::size_t id = mp_font->commit(); + m_font_ids.push_back(id); + mp_font = nullptr; + break; + } + case XML_fill: + { + assert(mp_fill); + std::size_t id = mp_fill->commit(); + m_fill_ids.push_back(id); + mp_fill = nullptr; + break; + } + case XML_border: + { + assert(mp_border); + std::size_t id = mp_border->commit(); + m_border_ids.push_back(id); + mp_border = nullptr; + break; + } + case XML_cellStyle: + assert(mp_cell_style); + mp_cell_style->commit(); + break; + case XML_cellStyles: + assert(mp_cell_style); + mp_cell_style = nullptr; + break; + case XML_cellStyleXfs: + case XML_cellXfs: + case XML_dxfs: + assert(mp_xf); + mp_xf = nullptr; + m_xf_type = ss::xf_category_t::unknown; + break; + case XML_xf: + case XML_dxf: + { + assert(mp_xf); + std::size_t id = mp_xf->commit(); + switch (m_xf_type) + { + break; + case ss::xf_category_t::cell_style: + // only cell style xf ID is referenced. + m_cell_style_xf_ids.push_back(id); + break; + case ss::xf_category_t::cell: + case ss::xf_category_t::differential: + // not used + break; + case ss::xf_category_t::unknown: + warn("xf entry committed while the current xf category is unknown"); + break; + } + break; + } + case XML_protection: + { + assert(mp_protection); + size_t prot_id = mp_protection->commit(); + assert(mp_xf); + mp_xf->set_protection(prot_id); + break; + } + case XML_numFmt: + end_number_format(); + break; + } + return pop_stack(ns, name); +} + +void xlsx_styles_context::characters(std::string_view /*str*/, bool /*transient*/) +{ + // not used in the styles.xml part. +} + +void xlsx_styles_context::start_number_format(const xml_token_attrs_t& attrs) +{ + if (!mp_styles) + return; + + mp_numfmt = mp_styles->start_number_format(); + ENSURE_INTERFACE(mp_numfmt, import_number_format); + + m_cur_numfmt_id.reset(); + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns) + continue; + + switch (attr.name) + { + case XML_numFmtId: + { + const char* p_end = nullptr; + long id = to_long(attr.value, &p_end); + if (attr.value.data() < p_end && id >= 0) + { + mp_numfmt->set_identifier(id); + m_cur_numfmt_id = id; + } + break; + } + case XML_formatCode: + { + mp_numfmt->set_code(attr.value); + break; + } + } + } +} + +void xlsx_styles_context::start_element_border(const xml_token_attrs_t& attrs) +{ + bool diagonal_up = false; + bool diagonal_down = false; + + std::for_each(attrs.begin(), attrs.end(), + [&diagonal_up,&diagonal_down](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_diagonalDown: + // top-left to bottom-right. + diagonal_down = to_long(attr.value) != 0; + break; + case XML_diagonalUp: + // bottom-left to top-right. + diagonal_up = to_long(attr.value) != 0; + break; + default: + ; + } + } + ); + + m_diagonal_up = diagonal_up; + m_diagonal_down = diagonal_down; +} + +void xlsx_styles_context::start_element_diagonal(const xml_token_attrs_t& attrs) +{ + assert(mp_border); + + m_cur_border_dir = ss::border_direction_t::unknown; + + if (m_diagonal_up) + { + m_cur_border_dir = m_diagonal_down ? + ss::border_direction_t::diagonal : + ss::border_direction_t::diagonal_bl_tr; + } + else + { + m_cur_border_dir = m_diagonal_down ? + ss::border_direction_t::diagonal_tl_br : + ss::border_direction_t::unknown; + } + + if (m_cur_border_dir == ss::border_direction_t::unknown) + return; + + border_attr_parser func(m_cur_border_dir, *mp_border); + for_each(attrs.begin(), attrs.end(), func); +} + +void xlsx_styles_context::start_border_color(const xml_token_attrs_t& attrs) +{ + assert(mp_border); + + std::optional<std::string_view> rgb; + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_rgb: + rgb = attr.value; + break; + case XML_theme: + // TODO : handle this. + break; + } + } + + if (rgb) + { + ss::color_elem_t alpha; + ss::color_elem_t red; + ss::color_elem_t green; + ss::color_elem_t blue; + + if (to_rgb(*rgb, alpha, red, green, blue)) + mp_border->set_color(m_cur_border_dir, alpha, red, green, blue); + } +} + +void xlsx_styles_context::start_font_color(const xml_token_attrs_t& attrs) +{ + assert(mp_font); + + std::optional<std::string_view> rgb; + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_rgb: + rgb = attr.value; + break; + case XML_theme: + // TODO : handle this. + break; + } + } + + if (rgb) + { + ss::color_elem_t alpha; + ss::color_elem_t red; + ss::color_elem_t green; + ss::color_elem_t blue; + if (to_rgb(*rgb, alpha, red, green, blue)) + mp_font->set_color(alpha, red, green, blue); + } +} + +void xlsx_styles_context::start_xf(const xml_token_attrs_t& attrs) +{ + assert(mp_xf); + + for (const xml_token_attr_t& attr : attrs) + { + switch (attr.name) + { + case XML_borderId: + { + const char* p_end = nullptr; + size_t n = to_long(attr.value, &p_end); + if (attr.value.data() < p_end) + { + if (n < m_border_ids.size()) + mp_xf->set_border(m_border_ids[n]); + else + { + std::ostringstream os; + os << "out-of-bound borderId: id=" << n << "; count=" << m_border_ids.size(); + warn(os.str()); + } + } + break; + } + case XML_fillId: + { + const char* p_end = nullptr; + size_t n = to_long(attr.value, &p_end); + if (attr.value.data() < p_end) + { + if (n < m_fill_ids.size()) + mp_xf->set_fill(m_fill_ids[n]); + else + { + std::ostringstream os; + os << "out-of-bound fillId: id=" << n << "; count=" << m_fill_ids.size(); + warn(os.str()); + } + } + break; + } + case XML_fontId: + { + const char* p_end = nullptr; + size_t n = to_long(attr.value, &p_end); + if (attr.value.data() < p_end) + { + if (n < m_font_ids.size()) + mp_xf->set_font(m_font_ids[n]); + else + { + std::ostringstream os; + os << "out-of-bound fontId: id=" << n << "; count=" << m_font_ids.size(); + warn(os.str()); + } + } + break; + } + case XML_numFmtId: + { + const char* p_end = nullptr; + long n = to_long(attr.value, &p_end); + if (attr.value.data() < p_end && n >= 0) + { + auto it = m_numfmt_ids.find(n); + if (it == m_numfmt_ids.end()) + { + std::ostringstream os; + os << "no entry for xf@numFmtId = " << n; + warn(os.str()); + } + else + mp_xf->set_number_format(it->second); + } + break; + } + case XML_xfId: + { + // reference ID to an xf entry in cellStyleXfs + const char* p_end = nullptr; + size_t n = to_long(attr.value, &p_end); + if (attr.value.data() < p_end) + { + if (n < m_cell_style_xf_ids.size()) + mp_xf->set_style_xf(m_cell_style_xf_ids[n]); + else + { + std::ostringstream os; + os << "out-of-bound xf@xfId: id=" << n << "; count=" << m_cell_style_xf_ids.size(); + warn(os.str()); + } + } + break; + } + case XML_applyBorder: + break; + case XML_applyFill: + break; + case XML_applyFont: + break; + case XML_applyNumberFormat: + break; + case XML_applyAlignment: + { + bool b = to_long(attr.value) != 0; + mp_xf->set_apply_alignment(b); + break; + } + } + } +} + +void xlsx_styles_context::end_number_format() +{ + if (!mp_styles) + return; + + assert(mp_numfmt); + std::size_t id = mp_numfmt->commit(); + mp_numfmt = nullptr; + + if (m_cur_numfmt_id) + { + auto res = m_numfmt_ids.insert_or_assign(*m_cur_numfmt_id, id); + if (!res.second) + { + // assigned to an existing key + std::ostringstream os; + os << "number format id of " << *m_cur_numfmt_id << " referenced multiple times"; + warn(os.str()); + } + } +} + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_styles_context.hpp b/src/liborcus/xlsx_styles_context.hpp new file mode 100644 index 0000000..3cd8310 --- /dev/null +++ b/src/liborcus/xlsx_styles_context.hpp @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "xml_context_base.hpp" +#include "xlsx_types.hpp" + +#include <orcus/string_pool.hpp> + +#include <vector> +#include <unordered_map> +#include <optional> + +namespace orcus { + +namespace spreadsheet { namespace iface { + class import_styles; + class import_font_style; + class import_fill_style; + class import_border_style; + class import_cell_protection; + class import_number_format; + class import_xf; + class import_cell_style; +}} + +/** + * Context for xl/styles.xml part. This part contains various styles used + * in the sheets. + */ +class xlsx_styles_context : public xml_context_base +{ +public: + xlsx_styles_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_styles* import_styles); + virtual ~xlsx_styles_context(); + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + virtual void characters(std::string_view str, bool transient); + +private: + void start_number_format(const xml_token_attrs_t& attrs); + + void start_element_border(const xml_token_attrs_t& attrs); + void start_element_diagonal(const xml_token_attrs_t& attrs); + void start_border_color(const xml_token_attrs_t& attrs); + void start_font_color(const xml_token_attrs_t& attrs); + void start_xf(const xml_token_attrs_t& attrs); + + void end_number_format(); + +private: + spreadsheet::iface::import_styles* mp_styles = nullptr; + spreadsheet::iface::import_font_style* mp_font = nullptr; + spreadsheet::iface::import_fill_style* mp_fill = nullptr; + spreadsheet::iface::import_border_style* mp_border = nullptr; + spreadsheet::iface::import_cell_protection* mp_protection = nullptr; + spreadsheet::iface::import_number_format* mp_numfmt = nullptr; + spreadsheet::iface::import_xf* mp_xf = nullptr; + spreadsheet::iface::import_cell_style* mp_cell_style = nullptr; + spreadsheet::xf_category_t m_xf_type = spreadsheet::xf_category_t::unknown; + + string_pool m_pool; + bool m_diagonal_up; + bool m_diagonal_down; + spreadsheet::border_direction_t m_cur_border_dir; + + std::vector<std::size_t> m_font_ids; + std::vector<std::size_t> m_fill_ids; + std::vector<std::size_t> m_border_ids; + std::vector<std::size_t> m_cell_style_xf_ids; + // numFmt@numFmtId values as keys + std::unordered_map<std::size_t, std::size_t> m_numfmt_ids; + std::optional<std::size_t> m_cur_numfmt_id; +}; + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_table_context.cpp b/src/liborcus/xlsx_table_context.cpp new file mode 100644 index 0000000..06f16ce --- /dev/null +++ b/src/liborcus/xlsx_table_context.cpp @@ -0,0 +1,319 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xlsx_table_context.hpp" +#include "xlsx_autofilter_context.hpp" +#include "ooxml_namespace_types.hpp" +#include "ooxml_token_constants.hpp" +#include "ooxml_global.hpp" +#include "session_context.hpp" +#include "xml_context_global.hpp" + +#include "orcus/measurement.hpp" +#include "orcus/spreadsheet/import_interface.hpp" + +#include <iostream> +#include <optional> + +namespace ss = orcus::spreadsheet; + +namespace orcus { + +namespace { + +class table_column_attr_parser +{ + string_pool* m_pool; + + long m_id; + std::string_view m_name; + std::string_view m_totals_row_label; + spreadsheet::totals_row_function_t m_totals_row_func; + +public: + table_column_attr_parser(string_pool* pool) : + m_pool(pool), m_id(-1), m_totals_row_func(spreadsheet::totals_row_function_t::none) {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_id: + m_id = to_long(attr.value); + break; + case XML_name: + m_name = attr.value; + if (attr.transient) + m_name = m_pool->intern(m_name).first; + break; + case XML_totalsRowLabel: + m_totals_row_label = attr.value; + if (attr.transient) + m_totals_row_label = m_pool->intern(m_totals_row_label).first; + break; + case XML_totalsRowFunction: + m_totals_row_func = spreadsheet::to_totals_row_function_enum(attr.value); + break; + default: + ; + } + } + + long get_id() const { return m_id; } + std::string_view get_name() const { return m_name; } + std::string_view get_totals_row_label() const { return m_totals_row_label; } + spreadsheet::totals_row_function_t get_totals_row_function() const { return m_totals_row_func; } +}; + +class table_style_info_attr_parser +{ + spreadsheet::iface::import_table* mp_table; + bool m_debug; + +public: + table_style_info_attr_parser(spreadsheet::iface::import_table* table, bool debug) : + mp_table(table), m_debug(debug) {} + + void operator() (const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + bool b = false; + + switch (attr.name) + { + case XML_name: + mp_table->set_style_name(attr.value); + if (m_debug) + std::cout << " * table style info (name=" << attr.value << ")" << std::endl; + break; + case XML_showFirstColumn: + b = to_bool(attr.value); + mp_table->set_style_show_first_column(b); + if (m_debug) + std::cout << " * show first column: " << b << std::endl; + break; + case XML_showLastColumn: + b = to_bool(attr.value); + mp_table->set_style_show_last_column(b); + if (m_debug) + std::cout << " * show last column: " << b << std::endl; + break; + case XML_showRowStripes: + b = to_bool(attr.value); + mp_table->set_style_show_row_stripes(b); + if (m_debug) + std::cout << " * show row stripes: " << b << std::endl; + break; + case XML_showColumnStripes: + b = to_bool(attr.value); + mp_table->set_style_show_column_stripes(b); + if (m_debug) + std::cout << " * show column stripes: " << b << std::endl; + break; + default: + ; + } + } +}; + +} + +xlsx_table_context::xlsx_table_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_table& table, + spreadsheet::iface::import_reference_resolver& resolver) : + xml_context_base(session_cxt, tokens), m_table(table), m_resolver(resolver), + m_cxt_autofilter(session_cxt, tokens, resolver) +{ + register_child(&m_cxt_autofilter); + + init_ooxml_context(*this); +} + +xlsx_table_context::~xlsx_table_context() {} + +xml_context_base* xlsx_table_context::create_child_context(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_ooxml_xlsx && name == XML_autoFilter) + { + m_cxt_autofilter.reset(); + return &m_cxt_autofilter; + } + return nullptr; +} + +void xlsx_table_context::end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child) +{ + if (ns == NS_ooxml_xlsx && name == XML_autoFilter) + { + assert(child == &m_cxt_autofilter); + + spreadsheet::iface::import_auto_filter* af = m_table.get_auto_filter(); + if (!af) + return; + + const xlsx_autofilter_context& cxt = static_cast<const xlsx_autofilter_context&>(*child); + cxt.push_to_model(*af); + } +} + +void xlsx_table_context::start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + if (ns != NS_ooxml_xlsx) + return; + + std::string_view str; + + switch (name) + { + case XML_table: + { + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + start_element_table(attrs); + break; + } + case XML_tableColumns: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_table); + single_long_attr_getter func(NS_ooxml_xlsx, XML_count); + long column_count = for_each(attrs.begin(), attrs.end(), func).get_value(); + if (get_config().debug) + std::cout << " * column count: " << column_count << std::endl; + + m_table.set_column_count(column_count); + } + break; + case XML_tableColumn: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_tableColumns); + table_column_attr_parser func(&get_session_context().spool); + func = for_each(attrs.begin(), attrs.end(), func); + if (get_config().debug) + { + std::cout << " * table column (id=" << func.get_id() << "; name=" << func.get_name() << ")" << std::endl; + std::cout << " * totals row label: " << func.get_totals_row_label() << std::endl; + std::cout << " * totals func: " << static_cast<int>(func.get_totals_row_function()) << std::endl; + } + + m_table.set_column_identifier(func.get_id()); + str = func.get_name(); + m_table.set_column_name(str); + str = func.get_totals_row_label(); + m_table.set_column_totals_row_label(str); + m_table.set_column_totals_row_function(func.get_totals_row_function()); + } + break; + case XML_tableStyleInfo: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_table); + table_style_info_attr_parser func(&m_table, get_config().debug); + for_each(attrs.begin(), attrs.end(), func); + } + break; + default: + warn_unhandled(); + } + +} + +bool xlsx_table_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_ooxml_xlsx) + { + switch (name) + { + case XML_table: + m_table.commit(); + break; + case XML_tableColumn: + m_table.commit_column(); + break; + default: + ; + } + } + + return pop_stack(ns, name); +} + +void xlsx_table_context::start_element_table(const xml_token_attrs_t& attrs) +{ + long id = -1; + long totals_row_count = -1; + + std::optional<std::string_view> name; + std::optional<std::string_view> display_name; + std::optional<std::string_view> ref; + + for (const xml_token_attr_t& attr : attrs) + { + if (attr.ns) + continue; + + switch (attr.name) + { + case XML_id: + id = to_long(attr.value); + break; + case XML_totalsRowCount: + totals_row_count = to_long(attr.value); + break; + case XML_name: + name = attr.value; + break; + case XML_displayName: + display_name = attr.value; + break; + case XML_ref: + ref = attr.value; + break; + } + } + + if (get_config().debug) + { + auto str_or_not = [](const auto& v) -> std::string_view + { + return v ? *v : "-"; + }; + + std::cout << "* table (range=" << str_or_not(ref) + << "; id=" << id + << "; name=" << str_or_not(name) + << "; display name=" << str_or_not(display_name) << ")" << std::endl; + + std::cout << " * totals row count: " << totals_row_count << std::endl; + } + + if (id >= 0) + m_table.set_identifier(id); + + if (ref) + { + ss::range_t range = to_rc_range(m_resolver.resolve_range(*ref)); + m_table.set_range(range); + } + + if (name) + m_table.set_name(*name); + + if (display_name) + m_table.set_display_name(*display_name); + + if (totals_row_count >= 0) + m_table.set_totals_row_count(totals_row_count); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_table_context.hpp b/src/liborcus/xlsx_table_context.hpp new file mode 100644 index 0000000..8b3e629 --- /dev/null +++ b/src/liborcus/xlsx_table_context.hpp @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_XLSX_TABLE_CONTEXT_HPP +#define ORCUS_XLSX_TABLE_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "xlsx_autofilter_context.hpp" + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_table; +class import_reference_resolver; + +}} + +class xlsx_table_context : public xml_context_base +{ +public: + xlsx_table_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_table& table, + spreadsheet::iface::import_reference_resolver& resolver); + virtual ~xlsx_table_context(); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child); + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + +private: + void start_element_table(const xml_token_attrs_t& attrs); + +private: + spreadsheet::iface::import_table& m_table; + spreadsheet::iface::import_reference_resolver& m_resolver; + + xlsx_autofilter_context m_cxt_autofilter; +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_types.cpp b/src/liborcus/xlsx_types.cpp new file mode 100644 index 0000000..3c0ba2a --- /dev/null +++ b/src/liborcus/xlsx_types.cpp @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xlsx_types.hpp" + +#include <mdds/sorted_string_map.hpp> + +namespace orcus { + +namespace { + +constexpr std::string_view str_unknown = "unknown"; + +namespace cell_type { + +using map_type = mdds::sorted_string_map<xlsx_cell_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "b", xlsx_ct_boolean }, + { "e", xlsx_ct_error }, + { "inlineStr", xlsx_ct_inline_string }, + { "n", xlsx_ct_numeric }, + { "s", xlsx_ct_shared_string }, + { "str", xlsx_ct_formula_string } +}; + +const map_type& get() +{ + static const map_type map(entries, std::size(entries), xlsx_ct_unknown); + return map; +} + +} // namespace cell_type + +namespace rca { + +using map_type = mdds::sorted_string_map<xlsx_rev_row_column_action_t, mdds::string_view_map_entry>; + +// Keys must be sorted. +constexpr map_type::entry entries[] = { + { "deleteCol", xlsx_rev_rca_delete_column }, + { "deleteRow", xlsx_rev_rca_delete_row }, + { "insertCol", xlsx_rev_rca_insert_column }, + { "insertRow", xlsx_rev_rca_insert_row } +}; + +const map_type& get() +{ + static const map_type map(entries, std::size(entries), xlsx_rev_rca_unknown); + return map; +} + +} // namespace rca + +} // anonymous namespace + +xlsx_cell_t to_xlsx_cell_type(std::string_view s) +{ + return cell_type::get().find(s); +} + +std::string_view to_string(xlsx_cell_t type) +{ + switch (type) + { + case xlsx_ct_boolean: + return cell_type::entries[0].key; + case xlsx_ct_error: + return cell_type::entries[1].key; + case xlsx_ct_inline_string: + return cell_type::entries[2].key; + case xlsx_ct_numeric: + return cell_type::entries[3].key; + case xlsx_ct_shared_string: + return cell_type::entries[4].key; + case xlsx_ct_formula_string: + return cell_type::entries[5].key; + default: + ; + } + return str_unknown; +} + +xlsx_rev_row_column_action_t to_xlsx_rev_row_column_action_type(std::string_view s) +{ + return rca::get().find(s); +} + +std::string_view to_string(xlsx_rev_row_column_action_t type) +{ + switch (type) + { + case xlsx_rev_rca_delete_column: + return rca::entries[0].key; + case xlsx_rev_rca_delete_row: + return rca::entries[1].key; + case xlsx_rev_rca_insert_column: + return rca::entries[2].key; + case xlsx_rev_rca_insert_row: + return rca::entries[3].key; + case xlsx_rev_rca_unknown: + default: + ; + } + + return str_unknown; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_types.hpp b/src/liborcus/xlsx_types.hpp new file mode 100644 index 0000000..6d61e1f --- /dev/null +++ b/src/liborcus/xlsx_types.hpp @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef __ORCUS_XLSX_TYPES_HPP__ +#define __ORCUS_XLSX_TYPES_HPP__ + +#include "ooxml_types.hpp" +#include "orcus/spreadsheet/types.hpp" + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_sheet; + +}} + +struct xlsx_rel_sheet_info : public opc_rel_extra +{ + std::string_view name; + size_t id; + + xlsx_rel_sheet_info() : id(0) {} + + virtual ~xlsx_rel_sheet_info() override {} +}; + +struct xlsx_rel_pivot_cache_info : public opc_rel_extra +{ + spreadsheet::pivot_cache_id_t id; + + xlsx_rel_pivot_cache_info(spreadsheet::pivot_cache_id_t _id) : id(_id) {} + + virtual ~xlsx_rel_pivot_cache_info() override {} +}; + +/** + * Data to pass to the pivot cache record handler. + */ +struct xlsx_rel_pivot_cache_record_info : public opc_rel_extra +{ + spreadsheet::pivot_cache_id_t id; + + xlsx_rel_pivot_cache_record_info(spreadsheet::pivot_cache_id_t _id) : id(_id) {} + + virtual ~xlsx_rel_pivot_cache_record_info() override {} +}; + +struct xlsx_rel_table_info : public opc_rel_extra +{ + spreadsheet::iface::import_sheet* sheet_interface; + + xlsx_rel_table_info() : sheet_interface(nullptr) {} + + virtual ~xlsx_rel_table_info() override {} +}; + +enum xlsx_cell_t +{ + xlsx_ct_unknown = 0, + xlsx_ct_boolean, + xlsx_ct_error, + xlsx_ct_numeric, + xlsx_ct_inline_string, + xlsx_ct_shared_string, + xlsx_ct_formula_string, +}; + +xlsx_cell_t to_xlsx_cell_type(std::string_view s); + +std::string_view to_string(xlsx_cell_t type); + +enum xlsx_rev_row_column_action_t +{ + xlsx_rev_rca_unknown = 0, + xlsx_rev_rca_delete_column, + xlsx_rev_rca_delete_row, + xlsx_rev_rca_insert_column, + xlsx_rev_rca_insert_row +}; + +xlsx_rev_row_column_action_t to_xlsx_rev_row_column_action_type(std::string_view s); + +std::string_view to_string(xlsx_rev_row_column_action_t type); + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_workbook_context.cpp b/src/liborcus/xlsx_workbook_context.cpp new file mode 100644 index 0000000..4980418 --- /dev/null +++ b/src/liborcus/xlsx_workbook_context.cpp @@ -0,0 +1,253 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xlsx_workbook_context.hpp" +#include "ooxml_global.hpp" +#include "ooxml_schemas.hpp" +#include "ooxml_token_constants.hpp" +#include "ooxml_namespace_types.hpp" +#include "session_context.hpp" +#include "xlsx_session_data.hpp" + +#include "orcus/measurement.hpp" +#include "orcus/spreadsheet/import_interface.hpp" + +namespace orcus { + +xlsx_workbook_context::xlsx_workbook_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_factory& factory) : + xml_context_base(session_cxt, tokens), + m_defined_name_scope(-1), + m_sheet_count(0), + m_factory(factory), + mp_named_exp(factory.get_named_expression()) +{ + init_ooxml_context(*this); +} + +xlsx_workbook_context::~xlsx_workbook_context() = default; + +xml_context_base* xlsx_workbook_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void xlsx_workbook_context::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void xlsx_workbook_context::start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + session_context& cxt = get_session_context(); + string_pool& sp = cxt.spool; + + if (ns == NS_ooxml_xlsx) + { + switch (name) + { + case XML_workbook: + { + xml_element_expected(parent, XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN); + if (get_config().debug) + print_attrs(get_tokens(), attrs); + + break; + } + case XML_sheets: + xml_element_expected(parent, NS_ooxml_xlsx, XML_workbook); + break; + case XML_sheet: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_sheets); + + std::string_view rid; + xlsx_rel_sheet_info sheet; + + std::for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (!attr.ns || attr.ns == NS_ooxml_xlsx) + { + switch (attr.name) + { + case XML_name: + sheet.name = sp.intern(attr.value).first; + break; + case XML_sheetId: + { + if (!attr.value.empty()) + sheet.id = to_long(attr.value); + break; + } + default: + ; + } + } + else if (attr.ns == NS_ooxml_r && attr.name == XML_id) + { + rid = sp.intern(attr.value).first; + } + } + ); + + if (sheet.name.empty()) + throw xml_structure_error("workbook.xml: sheet element must have a valid name element."); + + // Insert the sheet here so that we have all the sheets available + // prior to parsing global named expressions. + m_factory.append_sheet(m_sheet_count++, sheet.name); + + m_workbook_info.data.insert( + opc_rel_extras_t::map_type::value_type( + rid, std::make_unique<xlsx_rel_sheet_info>(sheet))); + + break; + } + case XML_definedNames: + xml_element_expected(parent, NS_ooxml_xlsx, XML_workbook); + break; + case XML_definedName: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_definedNames); + + std::for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (attr.ns && attr.ns != NS_ooxml_xlsx) + return; + + switch (attr.name) + { + case XML_name: + { + m_defined_name = attr.value; + if (attr.transient) + { + m_defined_name = + cxt.spool.intern(m_defined_name).first; + } + break; + } + case XML_localSheetId: + m_defined_name_scope = to_long(attr.value); + break; + default: + ; + } + } + ); + + break; + } + case XML_pivotCaches: + xml_element_expected(parent, NS_ooxml_xlsx, XML_workbook); + break; + case XML_pivotCache: + { + xml_element_expected(parent, NS_ooxml_xlsx, XML_pivotCaches); + + std::string_view rid; + long cache_id = -1; + std::for_each(attrs.begin(), attrs.end(), + [&](const xml_token_attr_t& attr) + { + if (!attr.ns || attr.ns == NS_ooxml_xlsx) + { + switch (attr.name) + { + case XML_cacheId: + cache_id = to_long(attr.value); + break; + default: + ; + } + } + else if (attr.ns == NS_ooxml_r) + { + switch (attr.name) + { + case XML_id: + rid = attr.value; + break; + default: + ; + } + } + } + ); + + m_workbook_info.data.insert( + opc_rel_extras_t::map_type::value_type( + rid, std::make_unique<xlsx_rel_pivot_cache_info>(cache_id))); + + break; + } + default: + warn_unhandled(); + } + } +} + +bool xlsx_workbook_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + if (ns == NS_ooxml_xlsx) + { + if (name == XML_definedName) + { + push_defined_name(); + + m_defined_name = std::string_view{}; + m_defined_name_exp = std::string_view{}; + m_defined_name_scope = -1; + } + } + return pop_stack(ns, name); +} + +void xlsx_workbook_context::characters(std::string_view str, bool transient) +{ + std::string_view sv(str); + xml_token_pair_t cur = get_current_element(); + string_pool& sp = get_session_context().spool; + + if (cur.first == NS_ooxml_xlsx) + { + if (cur.second == XML_definedName) + m_defined_name_exp = transient ? sp.intern(sv).first : sv; + } +} + +void xlsx_workbook_context::pop_workbook_info(opc_rel_extras_t& workbook_data) +{ + m_workbook_info.swap(workbook_data); +} + +void xlsx_workbook_context::push_defined_name() +{ + spreadsheet::iface::import_named_expression* named_exp = mp_named_exp; + + if (m_defined_name_scope >= 0) + { + // sheet local scope. + spreadsheet::iface::import_sheet* sheet = m_factory.get_sheet(m_defined_name_scope); + if (!sheet) + return; + + named_exp = sheet->get_named_expression(); + } + + if (named_exp) + { + named_exp->set_named_expression(m_defined_name, m_defined_name_exp); + named_exp->commit(); + } +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xlsx_workbook_context.hpp b/src/liborcus/xlsx_workbook_context.hpp new file mode 100644 index 0000000..71d1958 --- /dev/null +++ b/src/liborcus/xlsx_workbook_context.hpp @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_XLSX_WORKBOOK_CONTEXT_HPP +#define INCLUDED_ORCUS_XLSX_WORKBOOK_CONTEXT_HPP + +#include "xml_context_base.hpp" +#include "orcus/spreadsheet/types.hpp" +#include "xlsx_types.hpp" + +#include <unordered_map> + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_factory; +class import_named_expression; + +}} + +/** + * Context for xl/workbook.xml. + */ +class xlsx_workbook_context : public xml_context_base +{ +public: + typedef std::unordered_map<std::string_view, xlsx_rel_sheet_info> sheet_info_type; + + xlsx_workbook_context( + session_context& session_cxt, const tokens& tokens, + spreadsheet::iface::import_factory& factory); + + virtual ~xlsx_workbook_context(); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child); + + virtual void start_element(xmlns_id_t ns, xml_token_t name, const xml_token_attrs_t& attrs); + virtual bool end_element(xmlns_id_t ns, xml_token_t name); + virtual void characters(std::string_view str, bool transient); + + void pop_workbook_info(opc_rel_extras_t& sheets); + +private: + void push_defined_name(); + +private: + opc_rel_extras_t m_workbook_info; + std::string_view m_defined_name; + std::string_view m_defined_name_exp; + spreadsheet::sheet_t m_defined_name_scope; + size_t m_sheet_count; + spreadsheet::iface::import_factory& m_factory; + spreadsheet::iface::import_named_expression* mp_named_exp; +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_context_base.cpp b/src/liborcus/xml_context_base.cpp new file mode 100644 index 0000000..4d61926 --- /dev/null +++ b/src/liborcus/xml_context_base.cpp @@ -0,0 +1,348 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xml_context_base.hpp" +#include "session_context.hpp" + +#include "orcus/exception.hpp" +#include "orcus/tokens.hpp" + +#include <iostream> +#include <sstream> + +using namespace std; + +namespace orcus { + +namespace { + +void print_stack(const tokens& tokens, const xml_elem_stack_t& elem_stack, const xmlns_context* ns_cxt) +{ + cerr << "[ "; + xml_elem_stack_t::const_iterator itr, itr_beg = elem_stack.begin(), itr_end = elem_stack.end(); + for (itr = itr_beg; itr != itr_end; ++itr) + { + if (itr != itr_beg) + cerr << " -> "; + + xmlns_id_t ns = itr->first; + if (ns_cxt) + { + std::string_view alias = ns_cxt->get_alias(ns); + if (!alias.empty()) + cerr << alias << ":"; + } + else + cerr << ns << ":"; + + cerr << tokens.get_token_name(itr->second); + } + cerr << " ]"; +} + +} + +xml_context_base::xml_context_base(session_context& session_cxt, const tokens& tokens) : + m_config(format_t::unknown), + mp_ns_cxt(nullptr), m_session_cxt(session_cxt), m_tokens(tokens), + m_elem_printer(m_tokens) +{ +} + +xml_context_base::~xml_context_base() +{ +} + +void xml_context_base::declaration(const xml_declaration_t& /*decl*/) +{ +} + +xml_context_base* xml_context_base::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void xml_context_base::end_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void xml_context_base::characters(std::string_view /*str*/, bool /*transient*/) +{ +} + +bool xml_context_base::evaluate_child_element(xmlns_id_t ns, xml_token_t name) const +{ + const xml_token_pair_t parent = get_current_element(); + + if (xml_element_always_allowed(parent)) + return true; + + const xml_token_pair_t child(ns, name); + + xml_element_validator::result res = m_elem_validator.validate(parent, child); + + if (get_config().debug) + { + switch (res) + { + case xml_element_validator::result::child_invalid: + { + std::ostringstream os; + print_element(os, child); + os << " cannot be a child element of "; + print_element(os, parent); + warn(os.str()); + break; + } + case xml_element_validator::result::parent_unknown: + { + std::ostringstream os; + os << "parent "; + print_element(os, parent); + os << " does not have any rules defined (child: "; + print_element(os, child); + os << ')'; + warn(os.str()); + break; + } + case xml_element_validator::result::child_valid: + break; + } + } + + return res != xml_element_validator::result::child_invalid; +} + +void xml_context_base::set_ns_context(const xmlns_context* p) +{ + mp_ns_cxt = p; + m_elem_printer.set_ns_context(p); + + for (auto* child : m_child_contexts) + child->set_ns_context(p); +} + +void xml_context_base::set_config(const config& opt) +{ + m_config = opt; + + for (auto* child : m_child_contexts) + child->set_config(opt); +} + +void xml_context_base::set_always_allowed_elements(xml_elem_set_t elems) +{ + m_always_allowed_elements = std::move(elems); +} + +void xml_context_base::init_element_validator( + const xml_element_validator::rule* rules, std::size_t n_rules) +{ + m_elem_validator.init(rules, n_rules); +} + +session_context& xml_context_base::get_session_context() +{ + return m_session_cxt; +} + +const session_context& xml_context_base::get_session_context() const +{ + return m_session_cxt; +} + +const tokens& xml_context_base::get_tokens() const +{ + return m_tokens; +} + +xml_token_pair_t xml_context_base::push_stack(xmlns_id_t ns, xml_token_t name) +{ + xml_token_pair_t parent = get_current_element(); + m_stack.emplace_back(ns, name); + return parent; +} + +bool xml_context_base::pop_stack(xmlns_id_t ns, xml_token_t name) +{ + const xml_token_pair_t& r = m_stack.back(); + + if (ns != r.first || name != r.second) + throw general_error("mismatched element name"); + + m_stack.pop_back(); + return m_stack.empty(); +} + +xml_token_pair_t xml_context_base::get_current_element() const +{ + return m_stack.empty() ? xml_token_pair_t(XMLNS_UNKNOWN_ID, XML_UNKNOWN_TOKEN) : m_stack.back(); +} + +const xml_token_pair_t& xml_context_base::get_parent_element() const +{ + if (m_stack.size() < 2) + throw general_error("element stack has no parent element"); + + return m_stack[m_stack.size() - 2]; +} + +void xml_context_base::warn_unhandled() const +{ + if (!m_config.debug) + return; + + cerr << "warning: unhandled element "; + print_stack(m_tokens, m_stack, mp_ns_cxt); + cerr << endl; +} + +void xml_context_base::warn_unexpected() const +{ + if (!m_config.debug) + return; + + cerr << "warning: unexpected element "; + print_stack(m_tokens, m_stack, mp_ns_cxt); + cerr << endl; +} + +void xml_context_base::warn(std::string_view msg) const +{ + if (!m_config.debug) + return; + + cerr << "warning: " << msg << endl; +} + +void xml_context_base::xml_element_expected( + const xml_token_pair_t& elem, xmlns_id_t ns, xml_token_t name, + const string* error) const +{ + if (!m_config.structure_check) + return; + + if (elem.first == ns && elem.second == name) + // This is an expected element. Good. + return; + + if (m_always_allowed_elements.count(elem)) + return; + + if (error) + { + throw xml_structure_error(*error); + } + + // Create a generic error message. + std::ostringstream os; + os << "element "; + print_element(os, {ns, name}); + os << " expected, but "; + print_element(os, elem); + os << " encountered." << std::endl << std::endl; + + print_current_element_stack(os); + throw xml_structure_error(os.str()); +} + +void xml_context_base::xml_element_expected( + const xml_token_pair_t& elem, const xml_elem_stack_t& expected_elems) const +{ + if (!m_config.structure_check) + return; + + for (const xml_token_pair_t& e : expected_elems) + { + if (elem == e) + return; + } + + if (m_always_allowed_elements.count(elem)) + return; + + throw_unknown_element_error(elem); +} + +void xml_context_base::xml_element_expected( + const xml_token_pair_t& elem, const xml_elem_set_t& expected_elems) const +{ + if (!m_config.structure_check) + return; + + if (expected_elems.count(elem)) + return; + + if (m_always_allowed_elements.count(elem)) + return; + + throw_unknown_element_error(elem); +} + +bool xml_context_base::xml_element_always_allowed(const xml_token_pair_t& elem) const +{ + return m_always_allowed_elements.count(elem) > 0; +} + +void xml_context_base::print_namespace(std::ostream& os, xmlns_id_t ns) const +{ + m_elem_printer.print_namespace(os, ns); +} + +void xml_context_base::print_element(std::ostream& os, const xml_token_pair_t& elem) const +{ + m_elem_printer.print_element(os, elem.first, elem.second); +} + +void xml_context_base::print_current_element_stack(std::ostream& os) const +{ + os << "current element stack:" << std::endl << std::endl; + + for (const auto& [ns, name] : m_stack) + { + os << " - "; + print_element(os, {ns, name}); + os << std::endl; + } +} + +void xml_context_base::throw_unknown_element_error(const xml_token_pair_t& elem) const +{ + // Create a generic error message. + std::ostringstream os; + os << "unexpected element encountered: "; + print_element(os, elem); + os << std::endl << std::endl; + + print_current_element_stack(os); + throw xml_structure_error(os.str()); +} + +const config& xml_context_base::get_config() const +{ + return m_config; +} + +std::string_view xml_context_base::intern(const xml_token_attr_t& attr) +{ + return m_session_cxt.intern(attr); +} + +std::string_view xml_context_base::intern(std::string_view s) +{ + return m_session_cxt.intern(s); +} + +void xml_context_base::register_child(xml_context_base* child) +{ + assert(child); + m_child_contexts.push_back(child); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_context_base.hpp b/src/liborcus/xml_context_base.hpp new file mode 100644 index 0000000..6956806 --- /dev/null +++ b/src/liborcus/xml_context_base.hpp @@ -0,0 +1,192 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_XML_CONTEXT_BASE_HPP +#define INCLUDED_ORCUS_XML_CONTEXT_BASE_HPP + +#include "xml_element_validator.hpp" +#include "xml_stream_handler.hpp" +#include "xml_util.hpp" + +namespace orcus { + +struct session_context; +class tokens; +class xmlns_context; +class xml_element_validator; + +class xml_context_base +{ +public: + xml_context_base(const xml_context_base&) = delete; + xml_context_base& operator=(const xml_context_base&) = delete; + + xml_context_base(session_context& session_cxt, const tokens& tokens); + virtual ~xml_context_base() = 0; + + /** + * This gets called at the end of the initial XML declaration block i.e. + * <?xml ... ?>. Obviously this gets called only on the root context. + * + * @param decl XML declaration attributes + */ + virtual void declaration(const xml_declaration_t& decl); + + /** + * This method gets called by the stream handler to fetch a child context + * object if applicable. If the current context can handle the specified + * element, it should return nullptr. If the current context should spawn a + * new context to handle the specified element and its sub structure, then + * it should return a pointer to a child context. + * + * @note The caller is not responsible for managing the life cycle of the + * returned context object; the current context object must manage the life + * cycle of the context object it returns. + * + * @param ns namespace value for the element. + * @param name name of the element. + * + * @return pointer to the context object that should handle the specified + * element, or nullptr if the current context can handle the + * element. + */ + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name); + + /** + * This method gets called when the child context is about to get phased + * out, to give the parent context object to communicate with the child + * context object before it gets phased out. + * + * @param ns namespace value for the element. + * @param name name of the element. + * @param child pointer to the child context object that is about to get + * phased out. + */ + virtual void end_child_context(xmlns_id_t ns, xml_token_t name, xml_context_base* child); + + /** + * Called on the opening of each element. The implementor should call + * push_stack() at the beginning of this method to have the base class keep + * track of the element stack. Be sure to also call pop_stack() in + * end_element() to maintain correct element stack. + * + * @param ns namespace token + * @param name element name + * @param attrs attributes + */ + virtual void start_element(xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) = 0; + + /** + * Called on the closing of each element. + * + * @param ns namespace token + * @param name element name + * + * @return true if the element that's closing is the root element of the + * context, else return false. The implementor should simply call + * pop_stack() and use the returned value from it as this method's + * return value. + */ + virtual bool end_element(xmlns_id_t ns, xml_token_t name) = 0; + + /** + * Called when passing xml content. When the content value is transient, + * the value is not expected to survive beyond the scope of the callback. + * + * @param str content value. + * @param transient whether or not the value is transient. + */ + virtual void characters(std::string_view str, bool transient); + + bool evaluate_child_element(xmlns_id_t ns, xml_token_t name) const; + + void set_ns_context(const xmlns_context* p); + + const config& get_config() const; + + void set_config(const config& opt); + + void set_always_allowed_elements(xml_elem_set_t elems); + +protected: + void init_element_validator(const xml_element_validator::rule* rules, std::size_t n_rules); + + session_context& get_session_context(); + const session_context& get_session_context() const; + const tokens& get_tokens() const; + xml_token_pair_t push_stack(xmlns_id_t ns, xml_token_t name); + bool pop_stack(xmlns_id_t ns, xml_token_t name); + xml_token_pair_t get_current_stack(xmlns_id_t ns, xml_token_t name); + xml_token_pair_t get_current_element() const; + + /** + * @warning Don't call this at the root element, or it will throw an + * exception. + */ + const xml_token_pair_t& get_parent_element() const; + void warn_unhandled() const; + void warn_unexpected() const; + void warn(std::string_view msg) const; + + /** + * Check if observed element equals expected element. If not, it throws an + * xml_structure_error exception. + * + * @param elem element observed. + * @param ns namespace of expected element. + * @param name name of expected element. + * @param error custom error message if needed. + */ + void xml_element_expected( + const xml_token_pair_t& elem, xmlns_id_t ns, xml_token_t name, + const ::std::string* error = nullptr) const; + + void xml_element_expected( + const xml_token_pair_t& elem, const xml_elem_stack_t& expected_elems) const; + + void xml_element_expected( + const xml_token_pair_t& elem, const xml_elem_set_t& expected_elems) const; + + bool xml_element_always_allowed(const xml_token_pair_t& elem) const; + + void print_namespace(std::ostream& os, xmlns_id_t ns) const; + + void print_element(std::ostream& os, const xml_token_pair_t& elem) const; + + void print_current_element_stack(std::ostream& os) const; + + /** + * Throw a viewer-friendly XML structure error with the information about an + * unknown element encountered. + * + * @param elem unknown element encountered. + */ + void throw_unknown_element_error(const xml_token_pair_t& elem) const; + + std::string_view intern(const xml_token_attr_t& attr); + std::string_view intern(std::string_view s); + + void register_child(xml_context_base* child); + +private: + std::vector<xml_context_base*> m_child_contexts; + + config m_config; + const xmlns_context* mp_ns_cxt; + session_context& m_session_cxt; + const tokens& m_tokens; + xml_element_printer m_elem_printer; + xml_element_validator m_elem_validator; + xml_elem_stack_t m_stack; + xml_elem_set_t m_always_allowed_elements; +}; + + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_context_global.cpp b/src/liborcus/xml_context_global.cpp new file mode 100644 index 0000000..5c98f07 --- /dev/null +++ b/src/liborcus/xml_context_global.cpp @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xml_context_global.hpp" +#include "orcus/string_pool.hpp" +#include "orcus/measurement.hpp" + +#include <algorithm> + +namespace orcus { + +single_attr_getter::single_attr_getter(string_pool& pool, xmlns_id_t ns, xml_token_t name) : + m_pool(&pool), m_ns(ns), m_name(name) {} + +single_attr_getter::single_attr_getter(xmlns_id_t ns, xml_token_t name) : + m_pool(nullptr), m_ns(ns), m_name(name) {} + +void single_attr_getter::operator() (const xml_token_attr_t& attr) +{ + if (attr.name != m_name) + return; + + if (attr.ns && attr.ns != m_ns) + return; + + m_value = attr.value; + if (attr.transient && m_pool) + m_value = m_pool->intern(m_value).first; +} + +std::string_view single_attr_getter::get_value() const +{ + return m_value; +} + +std::string_view single_attr_getter::get( + const std::vector<xml_token_attr_t>& attrs, xmlns_id_t ns, xml_token_t name) +{ + single_attr_getter func(ns, name); + return std::for_each(attrs.begin(), attrs.end(), func).get_value(); +} + +std::string_view single_attr_getter::get( + const std::vector<xml_token_attr_t>& attrs, string_pool& pool, xmlns_id_t ns, xml_token_t name) +{ + single_attr_getter func(pool, ns, name); + return std::for_each(attrs.begin(), attrs.end(), func).get_value(); +} + +single_long_attr_getter::single_long_attr_getter(xmlns_id_t ns, xml_token_t name) : + m_value(-1), m_ns(ns), m_name(name) {} + +void single_long_attr_getter::operator() (const xml_token_attr_t& attr) +{ + if (attr.name != m_name) + return; + + if (attr.ns && attr.ns != m_ns) + return; + + m_value = to_long(attr.value); +} + +long single_long_attr_getter::get_value() const +{ + return m_value; +} + +long single_long_attr_getter::get(const std::vector<xml_token_attr_t>& attrs, xmlns_id_t ns, xml_token_t name) +{ + single_long_attr_getter func(ns, name); + return std::for_each(attrs.begin(), attrs.end(), func).get_value(); +} + +single_double_attr_getter::single_double_attr_getter(xmlns_id_t ns, xml_token_t name) : + m_value(-1.0), m_ns(ns), m_name(name) {} + +void single_double_attr_getter::operator() (const xml_token_attr_t& attr) +{ + if (attr.name != m_name) + return; + + if (attr.ns && attr.ns != m_ns) + return; + + m_value = to_double(attr.value); +} + +double single_double_attr_getter::get_value() const +{ + return m_value; +} + +double single_double_attr_getter::get(const std::vector<xml_token_attr_t>& attrs, xmlns_id_t ns, xml_token_t name) +{ + single_double_attr_getter func(ns, name); + return std::for_each(attrs.begin(), attrs.end(), func).get_value(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_context_global.hpp b/src/liborcus/xml_context_global.hpp new file mode 100644 index 0000000..b05dd28 --- /dev/null +++ b/src/liborcus/xml_context_global.hpp @@ -0,0 +1,71 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_XML_CONTEXT_GLOBAL_HPP +#define ORCUS_XML_CONTEXT_GLOBAL_HPP + +#include <orcus/types.hpp> + +#include <functional> + +namespace orcus { + +class string_pool; + +/** + * Use this just to get the value of a single attribute for a given element. + */ +class single_attr_getter +{ + string_pool* m_pool; + std::string_view m_value; + xmlns_id_t m_ns; + xml_token_t m_name; + +public: + single_attr_getter(xmlns_id_t ns, xml_token_t name); + single_attr_getter(string_pool& pool, xmlns_id_t ns, xml_token_t name); + + void operator() (const xml_token_attr_t& attr); + std::string_view get_value() const; + + static std::string_view get(const std::vector<xml_token_attr_t>& attrs, xmlns_id_t ns, xml_token_t name); + static std::string_view get(const std::vector<xml_token_attr_t>& attrs, string_pool& pool, xmlns_id_t ns, xml_token_t name); +}; + +class single_long_attr_getter +{ + long m_value; + xmlns_id_t m_ns; + xml_token_t m_name; + +public: + single_long_attr_getter(xmlns_id_t ns, xml_token_t name); + void operator() (const xml_token_attr_t& attr); + long get_value() const; + + static long get(const std::vector<xml_token_attr_t>& attrs, xmlns_id_t ns, xml_token_t name); +}; + +class single_double_attr_getter +{ + double m_value; + xmlns_id_t m_ns; + xml_token_t m_name; + +public: + single_double_attr_getter(xmlns_id_t ns, xml_token_t name); + void operator() (const xml_token_attr_t& attr); + double get_value() const; + + static double get(const std::vector<xml_token_attr_t>& attrs, xmlns_id_t ns, xml_token_t name); +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_element_types.cpp b/src/liborcus/xml_element_types.cpp new file mode 100644 index 0000000..967b4d4 --- /dev/null +++ b/src/liborcus/xml_element_types.cpp @@ -0,0 +1,19 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xml_element_types.hpp" + +namespace orcus { + +size_t xml_token_pair_hash::operator()(const xml_token_pair_t& v) const +{ + return std::hash<const char*>()(v.first) ^ std::hash<size_t>()(v.second); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_element_types.hpp b/src/liborcus/xml_element_types.hpp new file mode 100644 index 0000000..2e7bc15 --- /dev/null +++ b/src/liborcus/xml_element_types.hpp @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <orcus/types.hpp> + +namespace orcus { + +/** + * Holds a pair of XML namespace identifier and an element token. Typically + * used when managing the element stack inside element context classes. + */ +using xml_token_pair_t = std::pair<xmlns_id_t, xml_token_t>; + +struct xml_token_pair_hash +{ + size_t operator()(const xml_token_pair_t& v) const; +}; + +using xml_elem_stack_t = std::vector<xml_token_pair_t>; +using xml_elem_set_t = std::unordered_set<xml_token_pair_t, xml_token_pair_hash>; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_element_validator.cpp b/src/liborcus/xml_element_validator.cpp new file mode 100644 index 0000000..ceb632c --- /dev/null +++ b/src/liborcus/xml_element_validator.cpp @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xml_element_validator.hpp" + +namespace orcus { + +xml_element_validator::xml_element_validator() +{ +} + +xml_element_validator::xml_element_validator(const rule* rules, std::size_t n_rules) +{ + init(rules, n_rules); +} + +void xml_element_validator::init(const rule* rules, std::size_t n_rules) +{ + const rule* end_rules = rules + n_rules; + + for (; rules != end_rules; ++rules) + { + const xml_token_pair_t parent(rules->ns_parent, rules->name_parent); + const xml_token_pair_t child(rules->ns_child, rules->name_child); + + auto it = m_rules.find(parent); + if (it == m_rules.end()) + { + auto res = m_rules.emplace(parent, xml_elem_set_t{}); + it = res.first; + } + + xml_elem_set_t& children = it->second; + children.insert(child); + } +} + +xml_element_validator::result xml_element_validator::validate( + const xml_token_pair_t& parent, const xml_token_pair_t& child) const +{ + if (m_rules.empty()) + // No rules are defined. Allow everything. + return result::child_valid; + + auto it = m_rules.find(parent); + if (it == m_rules.end()) + // No rules for this parent. + return result::parent_unknown; + + const xml_elem_set_t& rules = it->second; + return rules.count(child) > 0 ? result::child_valid : result::child_invalid; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_element_validator.hpp b/src/liborcus/xml_element_validator.hpp new file mode 100644 index 0000000..43a44e0 --- /dev/null +++ b/src/liborcus/xml_element_validator.hpp @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "xml_element_types.hpp" + +#include <unordered_map> + +namespace orcus { + +class xml_element_validator +{ + using rule_map_type = std::unordered_map<xml_token_pair_t, xml_elem_set_t, xml_token_pair_hash>; + rule_map_type m_rules; + +public: + + /** represents a single parent to child mapping rule. It must be a POD. */ + struct rule + { + const xmlns_id_t ns_parent; + const xml_token_t name_parent; + const xmlns_id_t ns_child; + const xml_token_t name_child; + }; + + /** validation result */ + enum class result + { + parent_unknown, //< no rules defined for this parent + child_valid, //< parent allows this child + child_invalid //< parent does not allow this child + }; + + xml_element_validator(); + xml_element_validator(const rule* rules, std::size_t n_rules); + + void init(const rule* rules, std::size_t n_rules); + + result validate(const xml_token_pair_t& parent, const xml_token_pair_t& child) const; +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_empty_context.cpp b/src/liborcus/xml_empty_context.cpp new file mode 100644 index 0000000..f39636b --- /dev/null +++ b/src/liborcus/xml_empty_context.cpp @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xml_empty_context.hpp" + +namespace orcus { + +xml_empty_context::xml_empty_context(session_context& session_cxt, const tokens& tokens) : + xml_context_base(session_cxt, tokens) +{ +} + +xml_context_base* xml_empty_context::create_child_context(xmlns_id_t /*ns*/, xml_token_t /*name*/) +{ + return nullptr; +} + +void xml_empty_context::end_child_context( + xmlns_id_t /*ns*/, xml_token_t /*name*/, xml_context_base* /*child*/) +{ +} + +void xml_empty_context::start_element( + xmlns_id_t ns, xml_token_t name, const::std::vector<xml_token_attr_t>& /*attrs*/) +{ + push_stack(ns, name); +} + +bool xml_empty_context::end_element(xmlns_id_t ns, xml_token_t name) +{ + return pop_stack(ns, name); +} + +void xml_empty_context::characters(std::string_view /*str*/, bool /*transient*/) +{ +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_empty_context.hpp b/src/liborcus/xml_empty_context.hpp new file mode 100644 index 0000000..502e199 --- /dev/null +++ b/src/liborcus/xml_empty_context.hpp @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "xml_context_base.hpp" + +namespace orcus { + +/** + * This context only tracks the scopes of all encountered elements but does + * nothing else. It is to be used when you need to ignore a whole sub + * structure of an XML document. + */ +class xml_empty_context : public xml_context_base +{ +public: + xml_empty_context(session_context& session_cxt, const tokens& tokens); + + virtual xml_context_base* create_child_context(xmlns_id_t ns, xml_token_t name) override; + + virtual void end_child_context( + xmlns_id_t ns, xml_token_t name, xml_context_base* child) override; + + virtual void start_element( + xmlns_id_t ns, xml_token_t name, const std::vector<xml_token_attr_t>& attrs) override; + + virtual bool end_element(xmlns_id_t ns, xml_token_t name) override; + + virtual void characters(std::string_view str, bool transient) override; +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_map_tree.cpp b/src/liborcus/xml_map_tree.cpp new file mode 100644 index 0000000..5d2ea72 --- /dev/null +++ b/src/liborcus/xml_map_tree.cpp @@ -0,0 +1,772 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xml_map_tree.hpp" +#include "xpath_parser.hpp" + +#define ORCUS_DEBUG_XML_MAP_TREE 0 + +#if ORCUS_DEBUG_XML_MAP_TREE +#include <iostream> +#endif + +#include <cassert> +#include <algorithm> +#include <iostream> +#include <sstream> + +namespace orcus { + +namespace { + +template<typename T> +void print_element_stack(std::ostream& os, const T& elem_stack) +{ + for (const auto& elem : elem_stack) + os << '/' << elem->name.name; +} + +} // anonymous namespace + +xml_map_tree::range_field_link::range_field_link(std::string_view _xpath, std::string_view _label) : + xpath(_xpath), label(_label) {} + +xml_map_tree::element_position::element_position() : + open_begin(0), open_end(0), close_begin(0), close_end(0) {} + +xml_map_tree::cell_reference::cell_reference() {} + +xml_map_tree::range_reference::range_reference(const cell_position& _pos) : + pos(_pos), row_position(0) {} + +xml_map_tree::linkable::linkable( + xml_map_tree& parent, const xml_name_t& _name, linkable_node_type _node_type, reference_type _ref_type) : + name(_name), node_type(_node_type), ref_type(_ref_type) +{ + parent.create_ref_store(*this); +} + +xml_map_tree::attribute::attribute(args_type args) : + linkable(std::get<0>(args), xml_name_t(std::get<1>(args)), linkable_node_type::attribute, std::get<2>(args)) {} + +xml_map_tree::attribute::~attribute() {} + +xml_map_tree::element::element(args_type args) : + linkable(std::get<0>(args), std::get<1>(args), linkable_node_type::element, std::get<3>(args)), + elem_type(std::get<2>(args)), + child_elements(nullptr), + range_parent(nullptr), + row_group(nullptr), + row_group_position(0) +{ + xml_map_tree& parent = std::get<0>(args); + + if (elem_type == element_type::unlinked) + { + child_elements = parent.m_element_store_pool.construct(); + return; + } + + assert(elem_type == element_type::linked); +} + +xml_map_tree::element::~element() {} + +xml_map_tree::element* xml_map_tree::element::get_child(const xml_name_t& _name) +{ + if (elem_type != element_type::unlinked) + return nullptr; + + assert(child_elements); + + auto it = std::find_if( + child_elements->begin(), child_elements->end(), + [&_name](const element* p) -> bool + { + return p->name == _name; + } + ); + + return it == child_elements->end() ? nullptr : *it; +} + +xml_map_tree::element* xml_map_tree::element::get_or_create_child( + xml_map_tree& parent, const xml_name_t& _name) +{ + auto it = std::find_if( + child_elements->begin(), child_elements->end(), + [&_name](const element* p) -> bool + { + return p->name == _name; + } + ); + + if (it != child_elements->end()) + return *it; + + string_pool& sp = parent.m_names; + + // Insert a new element of this name. + auto const nm = sp.intern(_name.name).first; // work around LLVM < 7 libc++ bug + child_elements->push_back( + parent.m_element_pool.construct( + element::args_type( + parent, + xml_name_t(_name.ns, nm), + element_type::unlinked, + reference_type::unknown + ) + ) + ); + + return child_elements->back(); +} + +xml_map_tree::element* xml_map_tree::element::get_or_create_linked_child( + xml_map_tree& parent, const xml_name_t& _name, reference_type _ref_type) +{ + if (!child_elements) + { + assert(elem_type == element_type::linked); + std::ostringstream os; + constexpr xml_name_t::to_string_type type = xml_name_t::use_alias; + + os << "You can't add a child element under an already linked element (this='" + << name.to_string(parent.m_xmlns_cxt, type) << "'; child='" + << _name.to_string(parent.m_xmlns_cxt, type) << "')"; + + throw invalid_map_error(os.str()); + } + + auto it = std::find_if( + child_elements->begin(), child_elements->end(), + [&_name](const element* p) -> bool + { + return p->name == _name; + } + ); + + if (it != child_elements->end()) + { + // Specified child element already exists. Make sure it's unlinked. + element* elem = *it; + if (elem->ref_type != reference_type::unknown || elem->elem_type != element_type::unlinked) + throw xpath_error("This element is already linked. You can't link the same element twice."); + + elem->link_reference(parent, _ref_type); + return elem; + } + + string_pool& sp = parent.m_names; + + // Insert a new linked element of this name. + auto const nm = sp.intern(_name.name).first; // work around LLVM < 7 libc++ bug + child_elements->push_back( + parent.m_element_pool.construct( + element::args_type( + parent, + xml_name_t(_name.ns, nm), + element_type::linked, + _ref_type + ) + ) + ); + + return child_elements->back(); +} + +void xml_map_tree::element::link_reference(xml_map_tree& parent, reference_type _ref_type) +{ + if (elem_type == element_type::unlinked) + parent.m_element_store_pool.destroy(child_elements); + + elem_type = element_type::linked; + ref_type = _ref_type; + parent.create_ref_store(*this); +} + +bool xml_map_tree::element::unlinked_attribute_anchor() const +{ + return elem_type == element_type::unlinked && ref_type == reference_type::unknown && !attributes.empty(); +} + +xml_map_tree::walker::walker(const xml_map_tree& parent) : + m_parent(parent) {} +xml_map_tree::walker::walker(const xml_map_tree::walker& r) : + m_parent(r.m_parent), m_stack(r.m_stack), m_unlinked_stack(r.m_unlinked_stack) {} + +void xml_map_tree::walker::reset() +{ + m_stack.clear(); + m_unlinked_stack.clear(); +} + +xml_map_tree::element* xml_map_tree::walker::push_element(const xml_name_t& name) +{ + if (!m_unlinked_stack.empty()) + { + // We're still in the unlinked region. + m_unlinked_stack.push_back(name); + return nullptr; + } + + if (m_stack.empty()) + { + if (!m_parent.mp_root) + { + // Tree is empty. + m_unlinked_stack.push_back(name); + return nullptr; + } + + element* p = m_parent.mp_root; + if (p->name != name) + { + // Names differ. + m_unlinked_stack.push_back(name); + return nullptr; + } + + m_stack.push_back(p); + return p; + } + + if (m_stack.back()->elem_type == element_type::unlinked) + { + // Check if the current element has a child of the same name. + element* p = m_stack.back()->get_child(name); + if (p) + { + m_stack.push_back(p); + return p; + } + } + + m_unlinked_stack.push_back(name); + return nullptr; +} + +xml_map_tree::element* xml_map_tree::walker::pop_element(const xml_name_t& name) +{ + if (!m_unlinked_stack.empty()) + { + // We're in the unlinked region. Pop element from the unlinked stack. + if (m_unlinked_stack.back() != name) + throw general_error("Closing element has a different name than the opening element. (unlinked stack)"); + + m_unlinked_stack.pop_back(); + + if (!m_unlinked_stack.empty()) + // We are still in the unlinked region. + return nullptr; + + return m_stack.empty() ? nullptr : m_stack.back(); + } + + if (m_stack.empty()) + throw general_error("Element was popped while the stack was empty."); + + if (m_stack.back()->name != name) + throw general_error("Closing element has a different name than the opening element. (linked stack)"); + + m_stack.pop_back(); + return m_stack.empty() ? nullptr : m_stack.back(); +} + +xml_map_tree::xml_map_tree(xmlns_repository& xmlns_repo) : + m_xmlns_cxt(xmlns_repo.create_context()), + mp_root(nullptr), + m_default_ns(XMLNS_UNKNOWN_ID) {} + +xml_map_tree::~xml_map_tree() {} + +void xml_map_tree::set_namespace_alias(std::string_view alias, std::string_view uri, bool default_ns) +{ +#if ORCUS_DEBUG_XML_MAP_TREE + cout << "xml_map_tree::set_namespace_alias: alias='" << alias << "', uri='" << uri << "', default=" << default_ns << endl; +#endif + // We need to turn the alias string persistent because the xmlns context + // doesn't intern the alias strings. + std::string_view alias_safe = m_names.intern(alias).first; + xmlns_id_t ns = m_xmlns_cxt.push(alias_safe, uri); + + if (default_ns) + m_default_ns = ns; +} + +xmlns_id_t xml_map_tree::get_namespace(std::string_view alias) const +{ + return m_xmlns_cxt.get(alias); +} + +void xml_map_tree::set_cell_link(std::string_view xpath, const cell_position& ref) +{ + if (xpath.empty()) + return; + +#if ORCUS_DEBUG_XML_MAP_TREE + cout << "xml_map_tree::set_cell_link: xpath='" << xpath << "' (ref=" << ref << ")" << endl; +#endif + + linked_node_type linked_node = get_linked_node(xpath, reference_type::cell); + assert(linked_node.node); + assert(!linked_node.elem_stack.empty()); + cell_reference* cell_ref = nullptr; + switch (linked_node.node->node_type) + { + case linkable_node_type::element: + assert(static_cast<element*>(linked_node.node)->cell_ref); + cell_ref = static_cast<element*>(linked_node.node)->cell_ref; + break; + case linkable_node_type::attribute: + assert(static_cast<attribute*>(linked_node.node)->cell_ref); + cell_ref = static_cast<attribute*>(linked_node.node)->cell_ref; + break; + default: + throw general_error("unknown node type returned from get_element_stack call in xml_map_tree::set_cell_link()."); + } + + cell_ref->pos = ref; +} + +void xml_map_tree::start_range(const cell_position& pos) +{ + m_cur_range_field_links.clear(); + m_cur_range_pos = pos; +} + +void xml_map_tree::append_range_field_link(std::string_view xpath, std::string_view label) +{ + if (xpath.empty()) + return; + + m_cur_range_field_links.emplace_back(xpath, label); +} + +void xml_map_tree::insert_range_field_link( + range_reference& range_ref, element_list_type& range_parent, const range_field_link& field) +{ + linked_node_type linked_node = get_linked_node(field.xpath, reference_type::range_field); + if (linked_node.elem_stack.size() < 2) + throw xpath_error("Path of a range field link must be at least 2 levels."); + + if (linked_node.node->node_type == linkable_node_type::unknown) + throw xpath_error("Unrecognized node type"); + + if (linked_node.anchor_elem) + linked_node.anchor_elem->linked_range_fields.push_back(range_ref.field_nodes.size()); + + if (!field.label.empty()) + linked_node.node->label = intern_string(field.label); + + switch (linked_node.node->node_type) + { + case linkable_node_type::element: + { + element* p = static_cast<element*>(linked_node.node); + assert(p && p->ref_type == reference_type::range_field && p->field_ref); + p->field_ref->ref = &range_ref; + p->field_ref->column_pos = range_ref.field_nodes.size(); + + range_ref.field_nodes.push_back(p); + break; + } + case linkable_node_type::attribute: + { + attribute* p = static_cast<attribute*>(linked_node.node); + assert(p && p->ref_type == reference_type::range_field && p->field_ref); + p->field_ref->ref = &range_ref; + p->field_ref->column_pos = range_ref.field_nodes.size(); + + range_ref.field_nodes.push_back(p); + break; + } + default: + ; + } + + // Determine the deepest common element for all field link elements in the + // current range reference. + if (range_parent.empty()) + { + // First field link in this range. Find the first row-group element + // going up from the linked node. + auto rit = linked_node.elem_stack.rbegin(); + while (rit != linked_node.elem_stack.rend() && !(*rit)->row_group) + ++rit; + + ++rit; // parent of the raw group + auto it_end = rit.base(); + + range_parent.assign(linked_node.elem_stack.begin(), it_end); + } + else + { + // Determine the deepest common element between the two. + element_list_type::iterator it_elem = linked_node.elem_stack.begin(), it_elem_end = linked_node.elem_stack.end(); + element_list_type::iterator it_cur = range_parent.begin(), it_cur_end = range_parent.end(); + if (*it_elem != *it_cur) + throw xpath_error("Two field links in the same range reference start with different root elements."); + + ++it_elem; + ++it_cur; + + for (; it_elem != it_elem_end && it_cur != it_cur_end; ++it_elem, ++it_cur) + { + if (*it_elem == *it_cur) + continue; + + // The two elements differ. Take their parent element as the new common element. + range_parent.assign(linked_node.elem_stack.begin(), it_elem); // current elemnt excluded. + break; + } + + if (range_parent.empty()) + throw xpath_error("Two field links in the same range reference must at least share the first level of their paths."); + } + +#if ORCUS_DEBUG_XML_MAP_TREE + print_element_stack(std::cout, range_parent); + std::cout << std::endl; +#endif +} + +void xml_map_tree::set_range_row_group(std::string_view xpath) +{ + if (xpath.empty()) + return; + + range_reference* range_ref = get_range_reference(m_cur_range_pos); + assert(range_ref); + + element* elem = get_element(xpath); + assert(elem); + elem->row_group = range_ref; +} + +void xml_map_tree::commit_range() +{ + if (m_cur_range_field_links.empty()) + // Nothing to commit. + return; + + range_reference* range_ref = get_range_reference(m_cur_range_pos); + assert(range_ref); + + // commont parent element for this range. + element_list_type range_parent; + + for (const range_field_link& field : m_cur_range_field_links) + insert_range_field_link(*range_ref, range_parent, field); + +#if ORCUS_DEBUG_XML_MAP_TREE + cout << "parent element path for this range: "; + for (const element* elem : range_parent) + cout << "/" << elem->name.to_string(m_xmlns_cxt, xml_name_t::use_alias); + cout << endl; +#endif + + assert(!range_parent.empty()); + // Mark the range parent element. + range_parent.back()->range_parent = range_ref; + + // Set the current position invalid. + m_cur_range_pos.row = -1; + m_cur_range_pos.col = -1; +} + +const xml_map_tree::linkable* xml_map_tree::get_link(std::string_view xpath) const +{ + if (!mp_root) + return nullptr; + + if (xpath.empty()) + return nullptr; + +#if ORCUS_DEBUG_XML_MAP_TREE + cout << "xml_map_tree::get_link: xpath = '" << xpath << "'" << endl; +#endif + const linkable* cur_node = mp_root; + + xpath_parser parser(m_xmlns_cxt, xpath.data(), xpath.size(), m_default_ns); + + // Check the root element first. + xpath_parser::token token = parser.next(); + if (cur_node->name.ns != token.ns || cur_node->name.name != token.name) + // Root element name doesn't match. + return nullptr; + +#if ORCUS_DEBUG_XML_MAP_TREE + cout << "xml_map_tree::get_link: root = (ns=" << token.ns << ", name=" << token.name << ")" << endl; +#endif + for (token = parser.next(); !token.name.empty(); token = parser.next()) + { + if (token.attribute) + { + // The current node should be an element and should have an attribute of the same name. + if (cur_node->node_type != linkable_node_type::element) + return nullptr; + + const element* elem = static_cast<const element*>(cur_node); + const attribute_store_type& attrs = elem->attributes; + auto it = std::find_if( + attrs.begin(), attrs.end(), + [&token](const attribute* p) -> bool + { + return p->name.ns == token.ns && p->name.name == token.name; + } + ); + + if (it == attrs.end()) + // No such attribute exists. + return nullptr; + + return *it; + } + + // See if an element of this name exists below the current element. + + if (cur_node->node_type != linkable_node_type::element) + return nullptr; + + const element* elem = static_cast<const element*>(cur_node); + if (elem->elem_type != element_type::unlinked) + return nullptr; + + if (!elem->child_elements) + return nullptr; + + auto it = std::find_if( + elem->child_elements->begin(), elem->child_elements->end(), + [&token](const element* p) -> bool + { + return p->name.ns == token.ns && p->name.name == token.name; + } + ); + + if (it == elem->child_elements->end()) + // No such child element exists. + return nullptr; + + cur_node = *it; + } + + if (cur_node->node_type != linkable_node_type::element || static_cast<const element*>(cur_node)->elem_type == element_type::unlinked) + // Non-leaf elements are not links. + return nullptr; + + return cur_node; +} + +xml_map_tree::walker xml_map_tree::get_tree_walker() const +{ + return walker(*this); +} + +xml_map_tree::range_ref_map_type& xml_map_tree::get_range_references() +{ + return m_field_refs; +} + +std::string_view xml_map_tree::intern_string(std::string_view str) const +{ + return m_names.intern(str).first; +} + +xml_map_tree::range_reference* xml_map_tree::get_range_reference(const cell_position& pos) +{ + range_ref_map_type::iterator it = m_field_refs.lower_bound(pos); + if (it == m_field_refs.end() || m_field_refs.key_comp()(pos, it->first)) + { + // This reference does not exist yet. Insert a new one. + + // Make sure the sheet name string is persistent. + cell_position pos_safe = pos; + pos_safe.sheet = m_names.intern(pos.sheet).first; + + it = m_field_refs.insert( + it, range_ref_map_type::value_type( + pos_safe, + m_range_reference_pool.construct(pos_safe))); + } + + return it->second; +} + +void xml_map_tree::create_ref_store(linkable& node) +{ + switch (node.ref_type) + { + case xml_map_tree::reference_type::cell: + node.cell_ref = m_cell_reference_pool.construct(); + break; + case xml_map_tree::reference_type::range_field: + node.field_ref = m_field_in_range_pool.construct(); + break; + case xml_map_tree::reference_type::unknown: + break; + } +} + +xml_map_tree::linked_node_type xml_map_tree::get_linked_node(std::string_view xpath, reference_type ref_type) +{ + linked_node_type ret; + + assert(!xpath.empty()); + xpath_parser parser(m_xmlns_cxt, xpath.data(), xpath.size(), m_default_ns); + + // Get the root element first. + xpath_parser::token token = parser.next(); + if (mp_root) + { + // Make sure the root element's names are the same. + if (mp_root->name.ns != token.ns || mp_root->name.name != token.name) + throw xpath_error("path begins with inconsistent root level name."); + } + else + { + // First time the root element is encountered. + if (token.attribute) + throw xpath_error("root element cannot be an attribute."); + + auto const nm = m_names.intern(token.name).first; // work around LLVM < 7 libc++ bug + mp_root = m_element_pool.construct( + element::args_type( + *this, + xml_name_t(token.ns, nm), + element_type::unlinked, + reference_type::unknown + ) + ); + } + + ret.elem_stack.push_back(mp_root); + element* cur_element = ret.elem_stack.back(); + assert(cur_element); + assert(cur_element->child_elements); + + element* row_group_elem = nullptr; + + token = parser.next(); + for (xpath_parser::token token_next = parser.next(); !token_next.name.empty(); token_next = parser.next()) + { + // Check if the current element contains a child element of the same name. + if (token.attribute) + throw xpath_error("attribute must always be at the end of the path."); + + cur_element = cur_element->get_or_create_child(*this, {token.ns, token.name}); + ret.elem_stack.push_back(cur_element); + token = token_next; + + if (cur_element->row_group) + row_group_elem = cur_element; + } + + assert(cur_element); + + // Insert a leaf node. + + if (token.attribute) + { + // This is an attribute. Insert it into the current element. + attribute_store_type& attrs = cur_element->attributes; + + // Check if an attribute of the same name already exists. + auto it = std::find_if( + attrs.begin(), attrs.end(), + [&token](const attribute* p) -> bool + { + return p->name.ns == token.ns && p->name.name == token.name; + } + ); + + if (it != attrs.end()) + throw xpath_error("This attribute is already linked. You can't link the same attribute twice."); + + auto const nm = m_names.intern(token.name).first; // work around LLVM < 7 libc++ bug + attribute* p = m_attribute_pool.construct( + attribute::args_type( + *this, + xml_name_t(token.ns, nm), + ref_type + ) + ); + + attrs.push_back(p); + ret.node = attrs.back(); + } + else + { + element* elem = cur_element->get_or_create_linked_child(*this, {token.ns, token.name}, ref_type); + ret.elem_stack.push_back(elem); + ret.node = elem; + + if (elem->row_group) + row_group_elem = elem; + } + + ret.anchor_elem = row_group_elem; + return ret; +} + +xml_map_tree::element* xml_map_tree::get_element(std::string_view xpath) +{ + assert(!xpath.empty()); + xpath_parser parser(m_xmlns_cxt, xpath.data(), xpath.size(), m_default_ns); + + // Get the root element first. + xpath_parser::token token = parser.next(); + if (mp_root) + { + // Make sure the root element's names are the same. + if (mp_root->name.ns != token.ns || mp_root->name.name != token.name) + throw xpath_error("path begins with inconsistent root level name."); + } + else + { + // First time the root element is encountered. + if (token.attribute) + throw xpath_error("root element cannot be an attribute."); + + auto const nm = m_names.intern(token.name).first; // work around LLVM < 7 libc++ bug + mp_root = m_element_pool.construct( + element::args_type( + *this, + xml_name_t(token.ns, nm), + element_type::unlinked, + reference_type::unknown + ) + ); + } + + element* cur_element = mp_root; + assert(cur_element->child_elements); + + for (token = parser.next(); !token.name.empty(); token = parser.next()) + { + // Check if the current element contains a child element of the same name. + if (token.attribute) + throw xpath_error("attribute was not expected."); + + cur_element = cur_element->get_or_create_child(*this, {token.ns, token.name}); + } + + assert(cur_element); + return cur_element; +} + +std::ostream& operator<< (std::ostream& os, const xml_map_tree::linkable& link) +{ + if (!link.ns_alias.empty()) + os << link.ns_alias << ':'; + os << link.name.name; + return os; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_map_tree.hpp b/src/liborcus/xml_map_tree.hpp new file mode 100644 index 0000000..841df0d --- /dev/null +++ b/src/liborcus/xml_map_tree.hpp @@ -0,0 +1,316 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_XML_MAP_TREE_HPP +#define INCLUDED_ORCUS_XML_MAP_TREE_HPP + +#include "orcus/spreadsheet/types.hpp" +#include "orcus/exception.hpp" +#include "orcus/types.hpp" +#include "orcus/xml_namespace.hpp" +#include "orcus/string_pool.hpp" + +#include "spreadsheet_impl_types.hpp" + +#include <ostream> +#include <map> +#include <vector> +#include <deque> +#include <memory> + +#include <boost/pool/object_pool.hpp> + +namespace orcus { + +class xmlns_repository; + +/** + * Tree structure representing XML-to-sheet mapping rules for mapped XML + * import. This structure only contains linked elements and attributes and + * their parent elements; it does not contain the entire structure of the + * imported XML. + */ +class xml_map_tree +{ + struct range_field_link + { + std::string_view xpath; + std::string_view label; + + range_field_link(std::string_view _xpath, std::string_view _label); + }; + +public: + /** + * A single cell position. Used both for single cell as well as range + * links. For a range link, this represents the upper-left cell of a + * range. + */ + using cell_position = spreadsheet::detail::cell_position_t; + + /** + * Positions of opening and closing elements in xml stream. + */ + struct element_position + { + std::ptrdiff_t open_begin; + std::ptrdiff_t open_end; + std::ptrdiff_t close_begin; + std::ptrdiff_t close_end; + + element_position(); + }; + + struct cell_reference + { + cell_position pos; + + cell_reference(const cell_reference&) = delete; + cell_reference& operator=(const cell_reference&) = delete; + + cell_reference(); + }; + + struct element; + struct linkable; + using element_store_type = std::deque<element*>; + using element_list_type = std::vector<element*>; + using const_element_list_type = std::vector<const element*>; + + struct range_reference + { + cell_position pos; + + /** + * List of elements comprising the fields, in order of appearance from + * left to right. + */ + std::vector<const linkable*> field_nodes; + + /** + * Total number of rows comprising data. This does not include the + * label row at the top. + */ + spreadsheet::row_t row_position; + + range_reference(const range_reference&) = delete; + range_reference& operator=(const range_reference&) = delete; + + range_reference(const cell_position& _pos); + + void reset(); + }; + + struct field_in_range + { + range_reference* ref = nullptr; + spreadsheet::col_t column_pos = -1; + }; + + typedef std::map<cell_position, range_reference*> range_ref_map_type; + + enum class linkable_node_type { unknown, element, attribute }; + enum class reference_type { unknown, cell, range_field }; + enum class element_type { unknown, linked, unlinked }; + + struct linkable + { + xml_name_t name; + linkable_node_type node_type; + reference_type ref_type; + + union + { + cell_reference* cell_ref = nullptr; + field_in_range* field_ref; + }; + + std::string_view label; // custom header label + mutable std::string_view ns_alias; // namespace alias used in the content stream. + + linkable(const linkable&) = delete; + linkable& operator=(const linkable&) = delete; + + linkable(xml_map_tree& parent, const xml_name_t& _name, linkable_node_type _node_type, reference_type _ref_type); + }; + + struct attribute : public linkable + { + using args_type = std::tuple<xml_map_tree&, const xml_name_t&, reference_type>; + + attribute(args_type args); + ~attribute(); + }; + + using attribute_store_type = std::deque<attribute*>; + + struct element : public linkable + { + element_type elem_type; + element_store_type* child_elements; + + mutable element_position stream_pos; // position of this element in the content stream + + attribute_store_type attributes; + + /** + * Points to a range reference instance of which this element is a + * parent. nullptr if this element is not a parent element of any range + * reference. + */ + range_reference* range_parent; + + /** + * The element is a row-group element (element that defines a row + * boundary) if this value is not null. If this is not null, it + * points to the range_reference instance it belongs to. + */ + range_reference* row_group; + + spreadsheet::row_t row_group_position; + + std::vector<spreadsheet::col_t> linked_range_fields; + + using args_type = std::tuple<xml_map_tree&, const xml_name_t&, element_type, reference_type>; + + element(args_type args); + ~element(); + + element* get_child(const xml_name_t& _name); + + element* get_or_create_child( + xml_map_tree& parent, const xml_name_t& _name); + + element* get_or_create_linked_child( + xml_map_tree& parent, const xml_name_t& _name, reference_type _ref_type); + + void link_reference(xml_map_tree& parent, reference_type _ref_type); + + /** + * Unlinked attribute anchor is an element that's not linked but has + * one or more attributes that are linked. + * + * @return true if the element is an unlinked attribute anchor, false + * otherwise. + */ + bool unlinked_attribute_anchor() const; + }; + + friend struct linkable; + +public: + + /** + * Wrapper class to allow walking through the element tree. + */ + class walker + { + typedef std::vector<element*> ref_element_stack_type; + typedef std::vector<xml_name_t> name_stack_type; + const xml_map_tree& m_parent; + ref_element_stack_type m_stack; + name_stack_type m_unlinked_stack; + public: + walker(const xml_map_tree& parent); + walker(const walker& r); + + void reset(); + element* push_element(const xml_name_t& name); + element* pop_element(const xml_name_t& name); + }; + + xml_map_tree() = delete; + xml_map_tree(const xml_map_tree&) = delete; + xml_map_tree& operator=(const xml_map_tree&) = delete; + + xml_map_tree(xmlns_repository& xmlns_repo); + ~xml_map_tree(); + + void set_namespace_alias(std::string_view alias, std::string_view uri, bool default_ns); + xmlns_id_t get_namespace(std::string_view alias) const; + + void set_cell_link(std::string_view xpath, const cell_position& ref); + + void start_range(const cell_position& pos); + void append_range_field_link(std::string_view xpath, std::string_view label); + void set_range_row_group(std::string_view xpath); + void commit_range(); + + const linkable* get_link(std::string_view xpath) const; + + walker get_tree_walker() const; + + range_ref_map_type& get_range_references(); + + std::string_view intern_string(std::string_view str) const; + +private: + void insert_range_field_link( + range_reference& range_ref, element_list_type& range_parent, const range_field_link& field); + + range_reference* get_range_reference(const cell_position& pos); + + void create_ref_store(linkable& node); + + struct linked_node_type + { + element_list_type elem_stack; + linkable* node = nullptr; + element* anchor_elem = nullptr; + }; + + /** + * Get a linked node (element or attribute) referenced by the specified + * xpath. + * + * @param xpath path to the linked node. + * @param type type of reference, either a cell or a range field. + */ + linked_node_type get_linked_node(std::string_view xpath, reference_type type); + + element* get_element(std::string_view xpath); + +private: + + using range_field_links = std::vector<range_field_link>; + + xmlns_context m_xmlns_cxt; + + /** + * Stores field links to insert into the current range reference. + */ + range_field_links m_cur_range_field_links; + + cell_position m_cur_range_pos; + + /** + * All range references present in the tree. This container manages the + * life cycles of stored range references. + */ + range_ref_map_type m_field_refs; + + /** pool of element names. */ + mutable string_pool m_names; + + boost::object_pool<element_store_type> m_element_store_pool; + boost::object_pool<cell_reference> m_cell_reference_pool; + boost::object_pool<range_reference> m_range_reference_pool; + boost::object_pool<field_in_range> m_field_in_range_pool; + boost::object_pool<attribute> m_attribute_pool; + boost::object_pool<element> m_element_pool; + + element* mp_root; + + xmlns_id_t m_default_ns; +}; + +std::ostream& operator<< (std::ostream& os, const xml_map_tree::linkable& link); + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_map_tree_test.cpp b/src/liborcus/xml_map_tree_test.cpp new file mode 100644 index 0000000..f3523f1 --- /dev/null +++ b/src/liborcus/xml_map_tree_test.cpp @@ -0,0 +1,274 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "test_global.hpp" +#include "xml_map_tree.hpp" +#include "orcus/xml_namespace.hpp" + +#include <cstdlib> +#include <cassert> +#include <iostream> + +using namespace orcus; + +void test_path_insertion() +{ + ORCUS_TEST_FUNC_SCOPE; + + xmlns_repository repo; + xml_map_tree tree(repo); + xml_map_tree::cell_position ref; + ref.sheet = std::string_view{"test"}; + ref.row = 2; + ref.col = 1; + + // Single cell links + tree.set_cell_link("/data/elem1", ref); + const xml_map_tree::linkable* p0 = tree.get_link("/data/elem1"); + assert(p0 && p0->node_type == xml_map_tree::linkable_node_type::element); + const xml_map_tree::element* p = static_cast<const xml_map_tree::element*>(p0); + assert(p->ref_type == xml_map_tree::reference_type::cell); + assert(p->cell_ref->pos.sheet == "test"); + assert(p->cell_ref->pos.row == 2); + assert(p->cell_ref->pos.col == 1); + + const xml_map_tree::element* elem1 = p; + + ref.row = 3; + ref.col = 2; + tree.set_cell_link("/data/elem2", ref); + p0 = tree.get_link("/data/elem2"); + assert(p0 && p0->node_type == xml_map_tree::linkable_node_type::element); + p = static_cast<const xml_map_tree::element*>(p0); + assert(p && p->ref_type == xml_map_tree::reference_type::cell); + assert(p->cell_ref->pos.sheet == "test"); + assert(p->cell_ref->pos.row == 3); + assert(p->cell_ref->pos.col == 2); + + // The link in elem1 should be unchanged. + p0 = tree.get_link("/data/elem1"); + assert(p0 == elem1); + + ref.sheet = std::string_view{"test2"}; + ref.row = 10; + ref.col = 5; + tree.set_cell_link("/data/meta/title", ref); + p0 = tree.get_link("/data/meta/title"); + assert(p0 && p0->node_type == xml_map_tree::linkable_node_type::element); + p = static_cast<const xml_map_tree::element*>(p0); + assert(p && p->ref_type == xml_map_tree::reference_type::cell); + assert(p->cell_ref->pos.sheet == "test2"); + assert(p->cell_ref->pos.row == 10); + assert(p->cell_ref->pos.col == 5); + + // Range field links + ref.row = 5; + ref.col = 0; + ref.sheet = std::string_view{"test3"}; + tree.start_range(ref); + tree.append_range_field_link("/data/entries/entry/id", std::string_view{}); + tree.append_range_field_link("/data/entries/entry/name", std::string_view{}); + tree.append_range_field_link("/data/entries/entry/score", std::string_view{}); + tree.set_range_row_group("/data/entries/entry"); + tree.commit_range(); + p0 = tree.get_link("/data/entries/entry/id"); + assert(p0 && p0->node_type == xml_map_tree::linkable_node_type::element); + p = static_cast<const xml_map_tree::element*>(p0); + assert(p && p->ref_type == xml_map_tree::reference_type::range_field); + assert(p->field_ref->ref->pos.sheet == "test3"); + assert(p->field_ref->ref->pos.row == 5); + assert(p->field_ref->ref->pos.col == 0); + assert(p->field_ref->column_pos == 0); + + p0 = tree.get_link("/data/entries/entry/name"); + assert(p0 && p0->node_type == xml_map_tree::linkable_node_type::element); + p = static_cast<const xml_map_tree::element*>(p0); + assert(p && p->ref_type == xml_map_tree::reference_type::range_field); + assert(p->field_ref->ref->pos.sheet == "test3"); + assert(p->field_ref->ref->pos.row == 5); + assert(p->field_ref->ref->pos.col == 0); + assert(p->field_ref->column_pos == 1); + + p0 = tree.get_link("/data/entries/entry/score"); + assert(p0 && p0->node_type == xml_map_tree::linkable_node_type::element); + p = static_cast<const xml_map_tree::element*>(p0); + assert(p && p->ref_type == xml_map_tree::reference_type::range_field); + assert(p->field_ref->ref->pos.sheet == "test3"); + assert(p->field_ref->ref->pos.row == 5); + assert(p->field_ref->ref->pos.col == 0); + assert(p->field_ref->column_pos == 2); +} + +void test_attr_path_insertion() +{ + ORCUS_TEST_FUNC_SCOPE; + + xmlns_repository repo; + xml_map_tree tree(repo); + xml_map_tree::cell_position ref; + ref.sheet = std::string_view{"test"}; + ref.row = 2; + ref.col = 3; + + // 'attr1' is an attribute of 'elem'. + tree.set_cell_link("/root/elem/@attr1", ref); + const xml_map_tree::linkable* p = tree.get_link("/root/elem/@attr1"); + assert(p && p->node_type == xml_map_tree::linkable_node_type::attribute); + const xml_map_tree::attribute* attr = static_cast<const xml_map_tree::attribute*>(p); + assert(attr->ref_type == xml_map_tree::reference_type::cell); + assert(attr->cell_ref->pos.sheet == "test"); + assert(attr->cell_ref->pos.row == 2); + assert(attr->cell_ref->pos.col == 3); + + // Insert another attribute in the same element. + ref.sheet = std::string_view{"test2"}; + ref.row = 11; + ref.col = 4; + tree.set_cell_link("/root/elem/@attr2", ref); + p = tree.get_link("/root/elem/@attr2"); + assert(p && p->node_type == xml_map_tree::linkable_node_type::attribute); + attr = static_cast<const xml_map_tree::attribute*>(p); + assert(attr->ref_type == xml_map_tree::reference_type::cell); + assert(attr->cell_ref->pos.sheet == "test2"); + assert(attr->cell_ref->pos.row == 11); + assert(attr->cell_ref->pos.col == 4); + + // At this point, /root/elem is not linked. + p = tree.get_link("/root/elem"); + assert(!p); + + // Now, link /root/elem. + ref.sheet = std::string_view{"test3"}; + ref.row = 4; + ref.col = 6; + tree.set_cell_link("/root/elem", ref); + p = tree.get_link("/root/elem"); + assert(p && p->node_type == xml_map_tree::linkable_node_type::element); + const xml_map_tree::element* elem = static_cast<const xml_map_tree::element*>(p); + assert(elem->elem_type == xml_map_tree::element_type::linked); + assert(elem->ref_type == xml_map_tree::reference_type::cell); + assert(elem->cell_ref->pos.sheet == "test3"); + assert(elem->cell_ref->pos.row == 4); + assert(elem->cell_ref->pos.col == 6); +} + +void test_tree_walk() +{ + ORCUS_TEST_FUNC_SCOPE; + + xmlns_repository repo; + xml_map_tree tree(repo); + xml_map_tree::cell_position ref; + ref.sheet = std::string_view{"test"}; + ref.row = 2; + ref.col = 1; + + tree.set_cell_link("/data/header/title", ref); + xml_map_tree::walker walker = tree.get_tree_walker(); + walker.reset(); + + // Root element. + const xml_map_tree::element* elem = walker.push_element({XMLNS_UNKNOWN_ID, "data"}); + assert(elem); + assert(elem->name.name == "data"); + assert(elem->elem_type == xml_map_tree::element_type::unlinked); + + elem = walker.push_element({XMLNS_UNKNOWN_ID, "header"}); + assert(elem); + assert(elem->name.name == "header"); + assert(elem->elem_type == xml_map_tree::element_type::unlinked); + + elem = walker.push_element({XMLNS_UNKNOWN_ID, "title"}); + assert(elem); + assert(elem->name.name == "title"); + assert(elem->ref_type == xml_map_tree::reference_type::cell); + + elem = walker.pop_element({XMLNS_UNKNOWN_ID, "title"}); + assert(elem); + assert(elem->name.name == "header"); + assert(elem->elem_type == xml_map_tree::element_type::unlinked); + + elem = walker.pop_element({XMLNS_UNKNOWN_ID, "header"}); + assert(elem); + assert(elem->name.name == "data"); + assert(elem->elem_type == xml_map_tree::element_type::unlinked); + + elem = walker.pop_element({XMLNS_UNKNOWN_ID, "data"}); + assert(!elem); +} + +void test_tree_walk_namespace() +{ + ORCUS_TEST_FUNC_SCOPE; + + xmlns_repository repo; + xml_map_tree tree(repo); + xml_map_tree::cell_position ref; + ref.sheet = std::string_view{"data"}; + ref.row = 1; + ref.col = 2; + + tree.set_namespace_alias("a", "http://some-namespace", false); + tree.set_namespace_alias("skip", "http://namespace-to-skip", false); + tree.set_cell_link("/a:table/a:title", ref); + tree.start_range(ref); + ref.row = 2; + ref.col = 0; + tree.append_range_field_link("/a:table/a:rows/a:row/a:city", std::string_view{}); + ++ref.col; + tree.append_range_field_link("/a:table/a:rows/a:row/a:population", std::string_view{}); + ++ref.col; + tree.append_range_field_link("/a:table/a:rows/a:row/a:year", std::string_view{}); + tree.set_range_row_group("/a:table/a:rows/a:row"); + tree.commit_range(); + + xmlns_id_t ns_a = tree.get_namespace("a"); + assert(ns_a != XMLNS_UNKNOWN_ID); + xmlns_id_t ns_skip = tree.get_namespace("skip"); + assert(ns_skip != XMLNS_UNKNOWN_ID); + + xml_map_tree::walker walker = tree.get_tree_walker(); + walker.reset(); + + // Root element. This is not linked. + const xml_map_tree::element* elem = walker.push_element({ns_a, "table"}); + assert(elem); + assert(elem->name.ns == ns_a); + assert(elem->name.name == "table"); + assert(elem->node_type == xml_map_tree::linkable_node_type::element); + assert(elem->elem_type == xml_map_tree::element_type::unlinked); + assert(elem->ref_type == xml_map_tree::reference_type::unknown); + + // Intentionally push a foreign element. + const xml_map_tree::element* elem_old = elem; + elem = walker.push_element({ns_skip, "foo"}); + assert(!elem); + elem = walker.pop_element({ns_skip, "foo"}); + assert(elem == elem_old); + + // Push a foreign element and a valid element under it. A valid element + // placed under a foreign element should be invalid. + elem_old = elem; + elem = walker.push_element({ns_skip, "foo"}); + assert(!elem); + elem = walker.push_element({ns_a, "title"}); + assert(!elem); + elem = walker.pop_element({ns_a, "title"}); + assert(!elem); + elem = walker.pop_element({ns_skip, "foo"}); + assert(elem == elem_old); +} + +int main() +{ + test_path_insertion(); + test_attr_path_insertion(); + test_tree_walk(); + test_tree_walk_namespace(); + return EXIT_SUCCESS; +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_simple_stream_handler.cpp b/src/liborcus/xml_simple_stream_handler.cpp new file mode 100644 index 0000000..1ee7c1d --- /dev/null +++ b/src/liborcus/xml_simple_stream_handler.cpp @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xml_simple_stream_handler.hpp" +#include "xml_context_base.hpp" + +#include <cassert> + +namespace orcus { + +xml_simple_stream_handler::xml_simple_stream_handler( + session_context& session_cxt, const tokens& t, std::unique_ptr<xml_context_base> context) : + xml_stream_handler(session_cxt, t, std::move(context)) +{ +} + +xml_simple_stream_handler::~xml_simple_stream_handler() +{ +} + +xml_context_base& xml_simple_stream_handler::get_context() +{ + return get_current_context(); +} + +void xml_simple_stream_handler::start_document() +{ +} + +void xml_simple_stream_handler::end_document() +{ +} + +void xml_simple_stream_handler::start_element(const xml_token_element_t& elem) +{ + get_current_context().start_element(elem.ns, elem.name, elem.attrs); +} + +void xml_simple_stream_handler::end_element(const xml_token_element_t& elem) +{ + get_current_context().end_element(elem.ns, elem.name); +} + +void xml_simple_stream_handler::characters(std::string_view str, bool transient) +{ + get_current_context().characters(str, transient); +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_simple_stream_handler.hpp b/src/liborcus/xml_simple_stream_handler.hpp new file mode 100644 index 0000000..186e7d3 --- /dev/null +++ b/src/liborcus/xml_simple_stream_handler.hpp @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef __ORCUS_XML_SIMPLE_HANDLER_HPP__ +#define __ORCUS_XML_SIMPLE_HANDLER_HPP__ + +#include "xml_stream_handler.hpp" + +namespace orcus { + +class xml_context_base; + +/** + * Simple stream handler that only uses a single context instance. + */ +class xml_simple_stream_handler : public xml_stream_handler +{ +public: + xml_simple_stream_handler( + session_context& session_cxt, const tokens& t, std::unique_ptr<xml_context_base> context); + virtual ~xml_simple_stream_handler() override; + + xml_context_base& get_context(); + + virtual void start_document() override; + virtual void end_document() override; + + virtual void start_element(const xml_token_element_t& elem) override; + virtual void end_element(const xml_token_element_t& elem) override; + virtual void characters(std::string_view str, bool transient) override; +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_stream_handler.cpp b/src/liborcus/xml_stream_handler.cpp new file mode 100644 index 0000000..859a08f --- /dev/null +++ b/src/liborcus/xml_stream_handler.cpp @@ -0,0 +1,139 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xml_stream_handler.hpp" +#include "xml_context_base.hpp" +#include "xml_empty_context.hpp" + +#include "orcus/exception.hpp" + +#include <iostream> + +namespace orcus { + +xml_stream_handler::xml_stream_handler( + session_context& session_cxt, const tokens& t, std::unique_ptr<xml_context_base> root_context) : + m_session_cxt(session_cxt), + m_tokens(t), + m_config(format_t::unknown), + m_elem_printer(m_tokens), + mp_root_context(std::move(root_context)), + mp_invalid_context(std::make_unique<xml_empty_context>(session_cxt, t)) +{ + assert(mp_root_context); + m_context_stack.push_back(mp_root_context.get()); +} + +xml_stream_handler::~xml_stream_handler() +{ +} + +void xml_stream_handler::start_document() +{ +} + +void xml_stream_handler::end_document() +{ +} + +void xml_stream_handler::declaration(const xml_declaration_t& decl) +{ + get_current_context().declaration(decl); +} + +void xml_stream_handler::start_element(const xml_token_element_t& elem) +{ + xml_context_base& cur = get_current_context(); + if (cur.evaluate_child_element(elem.ns, elem.name)) + { + // new child element is valid against parent element. + xml_context_base* p = cur.create_child_context(elem.ns, elem.name); + if (p) + m_context_stack.push_back(p); + } + else + { + // new child element is not valid for the current element. Ignore the + // whole sub structure. + m_context_stack.push_back(&get_invalid_context()); + + if (m_config.debug) + { + // TODO: print the top element of the sub structure being ignored. + std::cerr << "warning: ignoring the whole sub-structure below "; + m_elem_printer.print_element(std::cerr, elem.ns, elem.name); + std::cerr << std::endl; + } + } + + get_current_context().start_element(elem.ns, elem.name, elem.attrs); +} + +void xml_stream_handler::end_element(const xml_token_element_t& elem) +{ + bool ended = get_current_context().end_element(elem.ns, elem.name); + + if (ended) + { + size_t n = m_context_stack.size(); + + if (n > 1) + { + // Call end_child_context of the parent context to provide a way for + // the two adjacent contexts to communicate with each other. + context_stack_type::reverse_iterator itr_cur = m_context_stack.rbegin(); + context_stack_type::reverse_iterator itr_par = itr_cur + 1; + (*itr_par)->end_child_context(elem.ns, elem.name, *itr_cur); + } + + m_context_stack.pop_back(); + } +} + +void xml_stream_handler::characters(std::string_view str, bool transient) +{ + get_current_context().characters(str, transient); +} + +void xml_stream_handler::set_ns_context(const xmlns_context* p) +{ + for (auto* context : m_context_stack) + context->set_ns_context(p); + + mp_invalid_context->set_ns_context(p); + m_elem_printer.set_ns_context(p); +} + +void xml_stream_handler::set_config(const config& opt) +{ + m_config = opt; + for (auto* context : m_context_stack) + context->set_config(m_config); + + mp_invalid_context->set_config(m_config); +} + +xml_context_base& xml_stream_handler::get_current_context() +{ + if (m_context_stack.empty()) + return *mp_root_context; + + return *m_context_stack.back(); +} + +xml_context_base& xml_stream_handler::get_root_context() +{ + return *mp_root_context; +} + +xml_context_base& xml_stream_handler::get_invalid_context() +{ + return *mp_invalid_context; +} + +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_stream_handler.hpp b/src/liborcus/xml_stream_handler.hpp new file mode 100644 index 0000000..2b09c95 --- /dev/null +++ b/src/liborcus/xml_stream_handler.hpp @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef ORCUS_XML_STREAM_HANDLER_HPP +#define ORCUS_XML_STREAM_HANDLER_HPP + +#include <orcus/sax_token_parser.hpp> +#include <orcus/config.hpp> + +#include "xml_util.hpp" + +#include <cstdlib> +#include <string> +#include <vector> +#include <memory> + +namespace orcus { + +class xml_context_base; +class xmlns_context; +struct session_context; + +class xml_stream_handler +{ + session_context& m_session_cxt; + const tokens& m_tokens; + + config m_config; + xml_element_printer m_elem_printer; + std::unique_ptr<xml_context_base> mp_root_context; + std::unique_ptr<xml_context_base> mp_invalid_context; + typedef std::vector<xml_context_base*> context_stack_type; + context_stack_type m_context_stack; + +public: + xml_stream_handler() = delete; + xml_stream_handler(const xml_stream_handler&) = delete; + + xml_stream_handler(session_context& session_cxt, const tokens& t, std::unique_ptr<xml_context_base> root_context); + virtual ~xml_stream_handler(); + + virtual void start_document(); + virtual void end_document(); + + virtual void declaration(const xml_declaration_t& decl); + virtual void start_element(const xml_token_element_t& elem); + virtual void end_element(const xml_token_element_t& elem); + virtual void characters(std::string_view str, bool transient); + + void set_ns_context(const xmlns_context* p); + void set_config(const config& opt); + +protected: + xml_context_base& get_current_context(); + xml_context_base& get_root_context(); + xml_context_base& get_invalid_context(); +}; + +} + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_stream_parser.cpp b/src/liborcus/xml_stream_parser.cpp new file mode 100644 index 0000000..895821c --- /dev/null +++ b/src/liborcus/xml_stream_parser.cpp @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xml_stream_parser.hpp" +#include "xml_stream_handler.hpp" + +#include "orcus/tokens.hpp" + +#include "orcus/threaded_sax_token_parser.hpp" +#include "orcus/sax_token_parser.hpp" + +#include <iostream> +#include <vector> +#include <sstream> + +using namespace std; + +namespace orcus { + +xml_stream_parser_base::xml_stream_parser_base( + const config& opt, + xmlns_repository& ns_repo, const tokens& tokens, const char* content, size_t size) : + m_config(opt), + m_ns_cxt(ns_repo.create_context()), + m_tokens(tokens), + mp_handler(nullptr), + m_content(content), + m_size(size) +{ +} + +xml_stream_parser_base::~xml_stream_parser_base() +{ +} + +void xml_stream_parser_base::set_handler(xml_stream_handler* handler) +{ + mp_handler = handler; + if (mp_handler) + { + mp_handler->set_ns_context(&m_ns_cxt); + mp_handler->set_config(m_config); + } +} + +xml_stream_handler* xml_stream_parser_base::get_handler() const +{ + return mp_handler; +} + +xml_stream_parser::xml_stream_parser( + const config& opt, + xmlns_repository& ns_repo, const tokens& tokens, const char* content, size_t size) : + xml_stream_parser_base(opt, ns_repo, tokens, content, size) {} + +xml_stream_parser::~xml_stream_parser() {} + +void xml_stream_parser::parse() +{ + if (!mp_handler) + return; + + sax_token_parser<xml_stream_handler> sax({m_content, m_size}, m_tokens, m_ns_cxt, *mp_handler); + sax.parse(); +} + +threaded_xml_stream_parser::threaded_xml_stream_parser( + const config& opt, + xmlns_repository& ns_repo, const tokens& tokens, const char* content, size_t size) : + xml_stream_parser_base(opt, ns_repo, tokens, content, size) {} + +threaded_xml_stream_parser::~threaded_xml_stream_parser() {} + +void threaded_xml_stream_parser::parse() +{ + if (!mp_handler) + return; + + threaded_sax_token_parser<xml_stream_handler> sax(m_content, m_size, m_tokens, m_ns_cxt, *mp_handler, 1000); + sax.parse(); + + sax.swap_string_pool(m_pool); +} + +void threaded_xml_stream_parser::swap_string_pool(string_pool& pool) +{ + m_pool.swap(pool); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_stream_parser.hpp b/src/liborcus/xml_stream_parser.hpp new file mode 100644 index 0000000..0b75222 --- /dev/null +++ b/src/liborcus/xml_stream_parser.hpp @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_XMLPARSER_HPP +#define INCLUDED_ORCUS_XMLPARSER_HPP + +#include <cstdlib> +#include <string> +#include <exception> + +#include "orcus/xml_namespace.hpp" +#include "orcus/string_pool.hpp" + +namespace orcus { + +struct config; + +class xml_stream_handler; +class tokens; + +/** + * This class does NOT store the stream content which is just a pointer to + * the first char of the content stream. Make sure you finish parsing while + * the content pointer is valid. + */ +class xml_stream_parser_base +{ +public: + xml_stream_parser_base() = delete; + + virtual void parse() = 0; + + void set_handler(xml_stream_handler* handler); + xml_stream_handler* get_handler() const; + +protected: + xml_stream_parser_base( + const config& opt, + xmlns_repository& ns_repo, const tokens& tokens, const char* content, size_t size); + virtual ~xml_stream_parser_base(); + + const config& m_config; + xmlns_context m_ns_cxt; + const tokens& m_tokens; + xml_stream_handler* mp_handler; + const char* m_content; + size_t m_size; +}; + +class xml_stream_parser : public xml_stream_parser_base +{ +public: + xml_stream_parser( + const config& opt, + xmlns_repository& ns_repo, const tokens& tokens, const char* content, size_t size); + virtual ~xml_stream_parser() override; + + virtual void parse() override; +}; + +class threaded_xml_stream_parser : public xml_stream_parser_base +{ + string_pool m_pool; + +public: + threaded_xml_stream_parser( + const config& opt, + xmlns_repository& ns_repo, const tokens& tokens, const char* content, size_t size); + virtual ~threaded_xml_stream_parser() override; + + virtual void parse() override; + + void swap_string_pool(string_pool& pool); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_structure_mapper.cpp b/src/liborcus/xml_structure_mapper.cpp new file mode 100644 index 0000000..1242947 --- /dev/null +++ b/src/liborcus/xml_structure_mapper.cpp @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xml_structure_mapper.hpp" + +namespace orcus { namespace detail { + +xml_structure_mapper::xml_structure_mapper( + xml_structure_tree::range_handler_type rh, const xml_structure_tree::walker& walker) : + m_range_handler(std::move(rh)), + m_walker(walker), + m_repeat_count(0) +{ +} + +void xml_structure_mapper::run() +{ + reset(); + traverse(); +} + +void xml_structure_mapper::reset() +{ + m_cur_elem = m_walker.root(); + m_repeat_count = 0; +} + +void xml_structure_mapper::traverse() +{ + auto elem = m_cur_elem; + const bool row_group = elem.repeat; + + if (row_group) + { + ++m_repeat_count; + m_current_range.row_groups.push_back(m_walker.get_path()); + } + + xml_structure_tree::entity_names_type children = m_walker.get_children(); + + if (m_repeat_count) + { + std::string path = m_walker.get_path(); + + xml_structure_tree::entity_names_type attr_names = m_walker.get_attributes(); + for (const auto& attr_name : attr_names) + { + std::string attr_path = path + "/@" + m_walker.to_string(attr_name); + m_current_range.paths.push_back(attr_path); + } + + if (children.empty() && elem.has_content) + // Only add leaf elements to the range, and only those with contents. + m_current_range.paths.push_back(path); + } + + for (const auto& child_name : children) + { + m_cur_elem = m_walker.descend(child_name); + traverse(); + m_cur_elem = m_walker.ascend(); + } + + if (row_group) + { + --m_repeat_count; + + if (!m_repeat_count) + push_range(); + } +} + +void xml_structure_mapper::push_range() +{ + m_range_handler(std::move(m_current_range)); +} + +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_structure_mapper.hpp b/src/liborcus/xml_structure_mapper.hpp new file mode 100644 index 0000000..aae4bfa --- /dev/null +++ b/src/liborcus/xml_structure_mapper.hpp @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_XML_STRUCTURE_MAPPER_HPP +#define INCLUDED_XML_STRUCTURE_MAPPER_HPP + +#include "orcus/xml_structure_tree.hpp" + +namespace orcus { namespace detail { + +class xml_structure_mapper +{ + xml_table_range_t m_current_range; + + xml_structure_tree::range_handler_type m_range_handler; + xml_structure_tree::walker m_walker; + xml_structure_tree::element m_cur_elem; + size_t m_repeat_count; + + void reset(); + + void traverse(); + + void push_range(); + +public: + xml_structure_mapper(xml_structure_tree::range_handler_type rh, const xml_structure_tree::walker& walker); + + void run(); +}; + +}} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_structure_tree.cpp b/src/liborcus/xml_structure_tree.cpp new file mode 100644 index 0000000..dbdb029 --- /dev/null +++ b/src/liborcus/xml_structure_tree.cpp @@ -0,0 +1,625 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/xml_structure_tree.hpp> +#include <orcus/sax_ns_parser.hpp> +#include <orcus/xml_namespace.hpp> +#include <orcus/exception.hpp> +#include <orcus/string_pool.hpp> + +#include "string_helper.hpp" +#include "xml_structure_mapper.hpp" + +#include <iostream> +#include <sstream> +#include <vector> +#include <cstdio> +#include <memory> + +#include <unordered_map> +#include <unordered_set> + +namespace orcus { + +namespace { + +/** Element properties. */ +struct elem_prop +{ + using element_store_type = std::unordered_map< + xml_structure_tree::entity_name, std::unique_ptr<elem_prop>, xml_structure_tree::entity_name::hash>; + + using attribute_names_type = std::unordered_set< + xml_structure_tree::entity_name, xml_structure_tree::entity_name::hash>; + + element_store_type child_elements; + attribute_names_type attributes; + + /** Store child element names in order of appearance. */ + xml_structure_tree::entity_names_type child_element_names; + + /** Store attribute names in order of appearance. */ + xml_structure_tree::entity_names_type attribute_names; + + size_t appearance_order; + + size_t in_scope_count; + + /** + * When true, this element is the base element of repeated structures. + * This flag is set only with the base element; none of the child + * elements below the base element have this flag set. + */ + bool repeat; + + bool has_content; + + elem_prop(const elem_prop&) = delete; + elem_prop& operator=(const elem_prop&) = delete; + + elem_prop() : + appearance_order(0), + in_scope_count(1), + repeat(false), + has_content(false) {} + + elem_prop(size_t _appearance_order) : + appearance_order(_appearance_order), + in_scope_count(1), + repeat(false), + has_content(false) {} +}; + +struct root +{ + xml_structure_tree::entity_name name; + elem_prop prop; +}; + +struct element_ref +{ + xml_structure_tree::entity_name name; + elem_prop* prop; + + element_ref() : prop(nullptr) {} + element_ref(xml_structure_tree::entity_name _name, elem_prop* _prop) : + name(_name), prop(_prop) {} +}; + +typedef std::vector<element_ref> elements_type; + +class xml_sax_handler +{ + string_pool& m_pool; + std::unique_ptr<root> mp_root; + elements_type m_stack; + xml_structure_tree::entity_names_type m_attrs; + +private: + void merge_attributes(elem_prop& prop) + { + xml_structure_tree::entity_names_type::const_iterator it = m_attrs.begin(), it_end = m_attrs.end(); + for (; it != it_end; ++it) + { + if (prop.attributes.find(*it) == prop.attributes.end()) + { + // New attribute. Insert it. + prop.attributes.insert(*it); + prop.attribute_names.push_back(*it); + } + } + + m_attrs.clear(); + } + +public: + xml_sax_handler(string_pool& pool) : + m_pool(pool), mp_root(nullptr) {} + + void doctype(const sax::doctype_declaration&) {} + + void start_declaration(std::string_view /*name*/) + { + } + + void end_declaration(std::string_view /*name*/) + { + m_attrs.clear(); + } + + void start_element(const sax_ns_parser_element& elem) + { + if (!mp_root) + { + // This is a root element. + mp_root.reset(new root); + mp_root->name.ns = elem.ns; + mp_root->name.name = m_pool.intern(elem.name).first; + element_ref ref(mp_root->name, &mp_root->prop); + merge_attributes(mp_root->prop); + m_stack.push_back(ref); + return; + } + + // See if the current element already has a child element of the same name. + assert(!m_stack.empty()); + element_ref& current = m_stack.back(); + xml_structure_tree::entity_name key(elem.ns, elem.name); + auto it = current.prop->child_elements.find(key); + if (it != current.prop->child_elements.end()) + { + // Recurring element. Set its repeat flag only when it occurs + // multiple times in the same scope. + ++it->second->in_scope_count; + if (it->second->in_scope_count > 1) + it->second->repeat = true; + + element_ref ref(it->first, it->second.get()); + merge_attributes(*it->second); + m_stack.push_back(ref); + return; + } + + // New element. + size_t order = current.prop->child_elements.size(); + key.name = m_pool.intern(key.name).first; + auto r = current.prop->child_elements.insert( + std::make_pair(key, std::make_unique<elem_prop>(order))); + + if (!r.second) + throw general_error("Insertion failed"); + + current.prop->child_element_names.push_back(key); + + it = r.first; + element_ref ref(it->first, it->second.get()); + merge_attributes(*it->second); + m_stack.push_back(ref); + } + + void end_element(const sax_ns_parser_element& /*elem*/) + { + if (m_stack.empty()) + throw general_error("Element stack is empty."); + + const element_ref& current = m_stack.back(); + + // Reset the in-scope count of all child elements to 0 before ending + // the current scope. + for (auto& [name, p] : current.prop->child_elements) + p->in_scope_count = 0; + + m_stack.pop_back(); + } + + void characters(std::string_view, bool) + { + if (m_stack.empty()) + return; + + element_ref& current = m_stack.back(); + current.prop->has_content = true; + } + + void attribute(std::string_view, std::string_view) + { + // Attribute for declaration. We don't handle this. + } + + void attribute(const sax_ns_parser_attribute& attr) + { + m_attrs.push_back(xml_structure_tree::entity_name(attr.ns, attr.name)); + } + + std::unique_ptr<root> release_root_element() + { + return std::move(mp_root); + } +}; + +struct sort_by_appearance +{ + bool operator() (const element_ref& left, const element_ref& right) const + { + return left.prop->appearance_order < right.prop->appearance_order; + } +}; + +struct scope +{ + xml_structure_tree::entity_name name; + elements_type elements; + elements_type::const_iterator current_pos; + bool repeat:1; + + scope(const scope&) = delete; + scope& operator=(const scope&) = delete; + + scope(const xml_structure_tree::entity_name& _name, bool _repeat, const element_ref& _elem) : + name(_name), repeat(_repeat) + { + elements.push_back(_elem); + current_pos = elements.begin(); + } + + scope(const xml_structure_tree::entity_name& _name, bool _repeat) : + name(_name), repeat(_repeat) {} +}; + +typedef std::vector<std::unique_ptr<scope>> scopes_type; + +void print_scope(std::ostream& os, const scopes_type& scopes, const xmlns_context& cxt) +{ + if (scopes.empty()) + throw general_error("scope stack shouldn't be empty while dumping tree."); + + // Skip the first scope which is root. + scopes_type::const_iterator it = scopes.begin(), it_end = scopes.end(); + for (++it; it != it_end; ++it) + { + os << "/"; + size_t num_id = cxt.get_index((*it)->name.ns); + if (num_id != INDEX_NOT_FOUND) + os << "ns" << num_id << ":"; + os << (*it)->name.name; + if ((*it)->repeat) + os << "[*]"; + } +} + +} + +xml_table_range_t::xml_table_range_t() {} + +xml_table_range_t::~xml_table_range_t() {} + +struct xml_structure_tree::impl +{ + string_pool m_pool; + xmlns_context& m_xmlns_cxt; + std::unique_ptr<root> mp_root; + + impl(const impl&) = delete; + impl& operator=(const impl&) = delete; + + impl(xmlns_context& xmlns_cxt) : m_xmlns_cxt(xmlns_cxt) {} + ~impl() {} + + std::string to_string(const xml_structure_tree::entity_name& name) const + { + std::ostringstream ss; + if (m_xmlns_cxt.get_index(name.ns) != INDEX_NOT_FOUND) + ss << m_xmlns_cxt.get_short_name(name.ns) << ":"; + ss << name.name; + return ss.str(); + } +}; + +struct xml_structure_tree::walker_impl +{ + const xml_structure_tree::impl& m_parent_impl; + root* mp_root; /// Root element of the authoritative tree. + element_ref m_cur_elem; + std::vector<element_ref> m_scopes; + + walker_impl& operator=(const walker_impl&) = delete; + + walker_impl(const xml_structure_tree::impl& parent_impl) : + m_parent_impl(parent_impl), mp_root(parent_impl.mp_root.get()) {} + + walker_impl(const walker_impl& r) : + m_parent_impl(r.m_parent_impl), mp_root(r.mp_root), m_cur_elem(r.m_cur_elem), m_scopes(r.m_scopes) {} +}; + +xml_structure_tree::entity_name::entity_name() : + ns(XMLNS_UNKNOWN_ID) {} + +xml_structure_tree::entity_name::entity_name(xmlns_id_t _ns, std::string_view _name) : + ns(_ns), name(_name) {} + +bool xml_structure_tree::entity_name::operator< (const entity_name& r) const +{ + if (ns != r.ns) + return ns < r.ns; + + return name < r.name; +} + +bool xml_structure_tree::entity_name::operator== (const entity_name& r) const +{ + return ns == r.ns && name == r.name; +} + +size_t xml_structure_tree::entity_name::hash::operator() (const entity_name& val) const +{ + size_t n = reinterpret_cast<size_t>(val.ns); + n += std::hash<std::string_view>{}(val.name); + return n; +} + +xml_structure_tree::element::element() : + repeat(false), has_content(false) {} + +xml_structure_tree::element::element(const entity_name& _name, bool _repeat, bool _has_content) : + name(_name), repeat(_repeat), has_content(_has_content) {} + +xml_structure_tree::walker::walker(const xml_structure_tree::impl& parent_impl) : + mp_impl(std::make_unique<walker_impl>(parent_impl)) +{ +} + +xml_structure_tree::walker::walker(const walker& r) : + mp_impl(std::make_unique<walker_impl>(*r.mp_impl)) +{ +} + +xml_structure_tree::walker::~walker() {} + +xml_structure_tree::walker& xml_structure_tree::walker::operator= (const walker& r) +{ + mp_impl->mp_root = r.mp_impl->mp_root; + return *this; +} + +xml_structure_tree::element xml_structure_tree::walker::root() +{ + if (!mp_impl->mp_root) + throw general_error("Tree is empty."); + + mp_impl->m_scopes.clear(); + + // Set the current element to root. + element_ref ref(mp_impl->mp_root->name, &mp_impl->mp_root->prop); + mp_impl->m_cur_elem = ref; + mp_impl->m_scopes.push_back(ref); + return xml_structure_tree::element(ref.name, false, ref.prop->has_content); +} + +xml_structure_tree::element xml_structure_tree::walker::descend(const entity_name& name) +{ + if (mp_impl->m_scopes.empty()) + throw general_error("Scope is empty."); + + assert(mp_impl->m_scopes.back().prop); + const auto& child_elems = mp_impl->m_scopes.back().prop->child_elements; + auto it = child_elems.find(name); + + if (it == child_elems.end()) + throw general_error("Specified child element does not exist."); + + // Push this new child element onto the stack. + element_ref ref(name, it->second.get()); + mp_impl->m_scopes.push_back(ref); + + return element(name, it->second->repeat, it->second->has_content); +} + +xml_structure_tree::element xml_structure_tree::walker::ascend() +{ + if (mp_impl->m_scopes.empty()) + throw general_error("Scope is empty."); + + if (mp_impl->m_scopes.size() == 1) + throw general_error("You can't ascend from the root element."); + + mp_impl->m_scopes.pop_back(); + const element_ref& ref = mp_impl->m_scopes.back(); + return element(ref.name, ref.prop->repeat, ref.prop->has_content); +} + +xml_structure_tree::entity_names_type xml_structure_tree::walker::get_children() +{ + if (mp_impl->m_scopes.empty()) + throw general_error("Scope is empty."); + + entity_names_type names; + assert(mp_impl->m_scopes.back().prop); + const elem_prop& prop = *mp_impl->m_scopes.back().prop; + names.assign(prop.child_element_names.begin(), prop.child_element_names.end()); + return names; +} + +xml_structure_tree::entity_names_type xml_structure_tree::walker::get_attributes() +{ + if (mp_impl->m_scopes.empty()) + throw general_error("Scope is empty."); + + entity_names_type names; + assert(mp_impl->m_scopes.back().prop); + const elem_prop& prop = *mp_impl->m_scopes.back().prop; + names.assign(prop.attribute_names.begin(), prop.attribute_names.end()); + return names; +} + +size_t xml_structure_tree::walker::get_xmlns_index(xmlns_id_t ns) const +{ + return mp_impl->m_parent_impl.m_xmlns_cxt.get_index(ns); +} + +std::string xml_structure_tree::walker::get_xmlns_short_name(xmlns_id_t ns) const +{ + return mp_impl->m_parent_impl.m_xmlns_cxt.get_short_name(ns); +} + +std::string xml_structure_tree::walker::to_string(const entity_name& name) const +{ + return mp_impl->m_parent_impl.to_string(name); +} + +std::string xml_structure_tree::walker::get_path() const +{ + std::ostringstream ss; + for (auto& element : mp_impl->m_scopes) + { + ss << "/" << mp_impl->m_parent_impl.to_string(element.name); + } + + return ss.str(); +} + +xml_structure_tree::element xml_structure_tree::walker::move_to(const std::string& path) +{ + auto parts = string_helper::split_string(path, '/'); + if (parts.empty()) + throw general_error("invalid format for path"); + + // string_helper::split_string will create an empty first element due to leading '/' + if (parts[0] != "") + { + throw general_error("invalid format for path"); + } + else + { + parts.erase(parts.begin()); + } + + if (parts.empty()) + throw general_error("invalid format for path"); + + element_ref root_ref(mp_impl->mp_root->name, &mp_impl->mp_root->prop); + if (mp_impl->m_parent_impl.to_string(root_ref.name) != parts[0]) + throw general_error("path does not match any element"); + + std::vector<element_ref> scopes; + scopes.push_back(root_ref); + + for (size_t i = 1; i < parts.size(); ++i) + { + const elem_prop& prop = *scopes.back().prop; + bool found = false; + for (auto& child : prop.child_elements) + { + if (mp_impl->m_parent_impl.to_string(child.first) == parts[i]) + { + scopes.emplace_back(child.first, child.second.get()); + found = true; + break; + } + } + if (!found) + throw general_error("path does not match any element"); + } + + std::swap(mp_impl->m_scopes, scopes); + const element_ref& ref = mp_impl->m_scopes.back(); + return element(ref.name, ref.prop->repeat, ref.prop->has_content); +} + +xml_structure_tree::xml_structure_tree(xmlns_context& xmlns_cxt) : + mp_impl(std::make_unique<impl>(xmlns_cxt)) {} + +xml_structure_tree::xml_structure_tree(xml_structure_tree&& other) : + mp_impl(std::move(other.mp_impl)) +{ + other.mp_impl = std::make_unique<impl>(mp_impl->m_xmlns_cxt); +} + +xml_structure_tree::~xml_structure_tree() {} + +void xml_structure_tree::parse(std::string_view s) +{ + xml_sax_handler hdl(mp_impl->m_pool); + sax_ns_parser<xml_sax_handler> parser(s, mp_impl->m_xmlns_cxt, hdl); + parser.parse(); + mp_impl->mp_root = hdl.release_root_element(); +} + +void xml_structure_tree::dump_compact(std::ostream& os) const +{ + if (!mp_impl->mp_root) + return; + + scopes_type scopes; + const xmlns_context& cxt = mp_impl->m_xmlns_cxt; + + // Dump all namespaces first. + cxt.dump(os); + + element_ref ref(mp_impl->mp_root->name, &mp_impl->mp_root->prop); + scopes.push_back(std::make_unique<scope>(entity_name(), false, ref)); + while (!scopes.empty()) + { + bool new_scope = false; + + // Iterate through all elements in the current scope. + scope& cur_scope = *scopes.back(); + for (; cur_scope.current_pos != cur_scope.elements.end(); ++cur_scope.current_pos) + { + const element_ref& this_elem = *cur_scope.current_pos; + std::ostringstream ss; + print_scope(ss, scopes, cxt); + + ss << "/"; + size_t num_id = cxt.get_index(this_elem.name.ns); + if (num_id != INDEX_NOT_FOUND) + ss << "ns" << num_id << ":"; + ss << this_elem.name.name; + if (this_elem.prop->repeat) + ss << "[*]"; + + std::string elem_name = ss.str(); + os << elem_name << std::endl; + + // Print all attributes that belong to this element. + for (const entity_name& attr : this_elem.prop->attribute_names) + os << elem_name << "/@" << mp_impl->to_string(attr) << std::endl; + + if (this_elem.prop->child_elements.empty()) + continue; + + // This element has child elements. Push a new scope and populate + // it with all child elements. + elements_type elems; + for (const auto& entry : this_elem.prop->child_elements) + { + ref.name = entry.first; + ref.prop = entry.second.get(); + elems.push_back(ref); + } + + // Sort the elements by order of appearance. + std::sort(elems.begin(), elems.end(), sort_by_appearance()); + + assert(!elems.empty()); + + // Push a new scope, and restart the loop with the new scope. + ++cur_scope.current_pos; + scopes.push_back(std::make_unique<scope>(this_elem.name, this_elem.prop->repeat)); + scope& child_scope = *scopes.back(); + child_scope.elements.swap(elems); + child_scope.current_pos = child_scope.elements.begin(); + + new_scope = true; + break; + } + + if (new_scope) + continue; + + scopes.pop_back(); + } +} + +xml_structure_tree::walker xml_structure_tree::get_walker() const +{ + return walker(*mp_impl); +} + +void xml_structure_tree::process_ranges(range_handler_type rh) const +{ + detail::xml_structure_mapper mapper(rh, get_walker()); + mapper.run(); +} + +void xml_structure_tree::swap(xml_structure_tree& other) +{ + mp_impl.swap(other.mp_impl); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_structure_tree_test.cpp b/src/liborcus/xml_structure_tree_test.cpp new file mode 100644 index 0000000..ba8b550 --- /dev/null +++ b/src/liborcus/xml_structure_tree_test.cpp @@ -0,0 +1,286 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <orcus/xml_structure_tree.hpp> +#include <orcus/xml_namespace.hpp> +#include <orcus/stream.hpp> +#include <orcus/parser_global.hpp> + +#include <cstdlib> +#include <cassert> +#include <iostream> +#include <sstream> +#include <vector> + +#include "filesystem_env.hpp" + +using namespace std; +using namespace orcus; + +const fs::path test_base_dir(SRCDIR"/test/xml-structure"); + +std::vector<fs::path> base_dirs = { + test_base_dir / "basic-1/", + test_base_dir / "basic-2/", + test_base_dir / "basic-3/", + test_base_dir / "attribute-1/", + test_base_dir / "nested-repeat-1/", + test_base_dir / "namespace-default/" +}; + +struct loaded_tree +{ + xmlns_context cxt; + file_content strm; + xml_structure_tree tree; + + loaded_tree(xmlns_repository& repo) : + cxt(repo.create_context()), + tree(cxt) {} + + loaded_tree(const loaded_tree&) = delete; +}; + +std::unique_ptr<loaded_tree> load_tree(xmlns_repository& repo, fs::path& filepath) +{ + auto ret = std::make_unique<loaded_tree>(repo); + ret->strm.load(filepath.string().data()); + assert(!ret->strm.empty()); + xml_structure_tree tree(ret->cxt); + tree.parse(ret->strm.str()); + ret->tree.swap(tree); + + return ret; +} + +void test_basic() +{ + xmlns_repository xmlns_repo; + + for (const fs::path& base_dir : base_dirs) + { + fs::path filepath = base_dir / "input.xml"; + cout << filepath << endl; + auto lt = load_tree(xmlns_repo, filepath); + + std::ostringstream os; + lt->tree.dump_compact(os); + string data_content = os.str(); + cout << "--" << endl; + cout << data_content; + + // Check the dump content against known datum. + filepath = base_dir / "check.txt"; + file_content strm_check(filepath.string().data()); + assert(!strm_check.empty()); + + // They should be identical, plus or minus leading/trailing whitespaces. + std::string_view s1(data_content.data(), data_content.size()); + std::string_view s2 = strm_check.str(); + assert(trim(s1) == trim(s2)); + } +} + +void test_walker() +{ + xmlns_repository xmlns_repo; + + { + fs::path filepath = base_dirs[0] / "input.xml"; + auto lt = load_tree(xmlns_repo, filepath); + + // Get walker from the tree. + xml_structure_tree::entity_names_type elem_names; + xml_structure_tree::walker wkr = lt->tree.get_walker(); + + // Root element. + xml_structure_tree::element elem = wkr.root(); + assert(elem.name.name == "root"); + assert(!elem.repeat); + + // Get names of child elements. There should only one one and it should be 'entry'. + elem_names = wkr.get_children(); + assert(elem_names.size() == 1); + xml_structure_tree::entity_name elem_name = elem_names.front(); + assert(elem_name.name == "entry"); + + // Descend into 'entry'. + elem = wkr.descend(elem_name); + assert(elem.name.name == "entry"); + assert(elem.repeat); + + // Element 'entry' should have 2 child elements 'name' and 'id' in this order. + elem_names = wkr.get_children(); + assert(elem_names.size() == 2); + assert(elem_names[0].name == "name"); + assert(elem_names[1].name == "id"); + + // Descend into 'name'. + elem_name = elem_names[0]; + elem = wkr.descend(elem_name); + assert(elem.name.name == "name"); + assert(!elem.repeat); + + // This is a leaf element. It should have no child elements. + xml_structure_tree::entity_names_type test_names = wkr.get_children(); + assert(test_names.empty()); + + // Move up to 'entry'. + elem = wkr.ascend(); + assert(elem.name.name == "entry"); + assert(elem.repeat); + + // Move down to 'id'. + elem = wkr.descend(elem_names[1]); + assert(elem.name.name == "id"); + assert(!elem.repeat); + + // Move up to 'entry' again. + elem = wkr.ascend(); + assert(elem.name.name == "entry"); + assert(elem.repeat); + + // Move up to 'root'. + elem = wkr.ascend(); + assert(elem.name.name == "root"); + assert(!elem.repeat); + } + + { + fs::path filepath = base_dirs[3] / "input.xml"; // attribute-1 + auto lt = load_tree(xmlns_repo, filepath); + + // Get walker from the tree. + xml_structure_tree::entity_names_type elem_names; + xml_structure_tree::walker wkr = lt->tree.get_walker(); + + // Root element. + xml_structure_tree::element elem = wkr.root(); + assert(elem.name.name == "root"); + assert(!elem.repeat); + + // Check attributes of root, which should have 'version' and 'type' in this order. + xml_structure_tree::entity_names_type names = wkr.get_attributes(); + assert(names.size() == 2); + assert(names[0].name == "version"); + assert(names[1].name == "type"); + + // Root element should have only one child element 'entry'. + names = wkr.get_children(); + assert(names.size() == 1); + assert(names[0].name == "entry"); + elem = wkr.descend(names[0]); + assert(elem.name.name == "entry"); + assert(elem.repeat); + + // The 'entry' element should have 3 attributes 'attr1', 'attr2', and 'attr3'. + names = wkr.get_attributes(); + assert(names.size() == 3); + assert(names[0].name == "attr1"); + assert(names[1].name == "attr2"); + assert(names[2].name == "attr3"); + } +} + +void test_walker_path() +{ + fs::path filepath = base_dirs[0] / "input.xml"; + xmlns_repository xmlns_repo; + auto lt = load_tree(xmlns_repo, filepath); + + // Get walker from the tree. + xml_structure_tree::entity_names_type elem_names; + xml_structure_tree::walker wkr = lt->tree.get_walker(); + wkr.root(); + assert("/root" == wkr.get_path()); + + elem_names = wkr.get_children(); + xml_structure_tree::entity_name elem_name = elem_names.front(); + wkr.descend(elem_name); + assert("/root/entry" == wkr.get_path()); + + xml_structure_tree::element element = wkr.move_to("/root/entry"); + assert(element.name.name == "entry"); + + try + { + wkr.move_to("/root/not-there"); + assert(false); + } + catch (...) + { + } + + try + { + wkr.move_to("something_different"); + assert(false); + } + catch (...) + { + } + + try + { + wkr.move_to("/non-exist"); + assert(false); + } + catch (...) + { + } +} + +void test_element_contents() +{ + xmlns_repository xmlns_repo; + + { + fs::path filepath = test_base_dir / "attribute-1" / "input.xml"; + auto lt = load_tree(xmlns_repo, filepath); + auto wkr = lt->tree.get_walker(); + auto elem = wkr.move_to("/root/entry"); + assert(wkr.to_string(elem.name) == "entry"); + assert(elem.repeat); + assert(!elem.has_content); + } + + { + fs::path filepath = test_base_dir / "basic-1" / "input.xml"; + auto lt = load_tree(xmlns_repo, filepath); + auto wkr = lt->tree.get_walker(); + auto elem = wkr.move_to("/root/entry/name"); + assert(wkr.to_string(elem.name) == "name"); + assert(!elem.repeat); + assert(elem.has_content); + + elem = wkr.move_to("/root/entry/id"); + assert(wkr.to_string(elem.name) == "id"); + assert(!elem.repeat); + assert(elem.has_content); + } + + { + fs::path filepath = test_base_dir / "nested-repeat-1" / "input.xml"; + auto lt = load_tree(xmlns_repo, filepath); + auto wkr = lt->tree.get_walker(); + auto elem = wkr.move_to("/root/mode/insert/command"); + assert(wkr.to_string(elem.name) == "command"); + assert(!elem.repeat); + assert(!elem.has_content); + } +} + +int main() +{ + test_basic(); + test_walker(); + test_walker_path(); + test_element_contents(); + + return EXIT_SUCCESS; +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_util.cpp b/src/liborcus/xml_util.cpp new file mode 100644 index 0000000..7c15adf --- /dev/null +++ b/src/liborcus/xml_util.cpp @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xml_util.hpp" + +#include <orcus/xml_namespace.hpp> +#include <orcus/tokens.hpp> + +#include <sstream> +#include <iostream> + +namespace orcus { + +xml_element_printer::xml_element_printer(const tokens& t) : + m_tokens(t) +{ +} + +void xml_element_printer::set_ns_context(const xmlns_context* ns_cxt) +{ + mp_ns_cxt = ns_cxt; +} + +void xml_element_printer::print_namespace(std::ostream& os, xmlns_id_t ns) const +{ + if (mp_ns_cxt) + { + std::string_view alias = mp_ns_cxt->get_alias(ns); + if (!alias.empty()) + os << alias; + else + os << mp_ns_cxt->get_short_name(ns); + } + else + os << ns; +} + +void xml_element_printer::print_element(std::ostream& os, xmlns_id_t ns, xml_token_t name) const +{ + os << '<'; + + std::ostringstream os_ns; + print_namespace(os_ns, ns); + std::string ns_str = os_ns.str(); + + if (!ns_str.empty()) + os << ns_str << ':'; + + os << m_tokens.get_token_name(name) << '>'; +} + +void print_attrs(const tokens& tokens, const xml_token_attrs_t& attrs) +{ + for (const auto& attr : attrs) + { + std::cout << " "; + if (attr.ns != XMLNS_UNKNOWN_ID) + std::cout << attr.ns << ":"; + + std::cout << tokens.get_token_name(attr.name) << " = \"" << attr.value << "\"" << std::endl; + } +} + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xml_util.hpp b/src/liborcus/xml_util.hpp new file mode 100644 index 0000000..1021ccf --- /dev/null +++ b/src/liborcus/xml_util.hpp @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <orcus/types.hpp> + +#include <ostream> + +namespace orcus { + +class tokens; +class xmlns_context; + +class xml_element_printer +{ + const tokens& m_tokens; + const xmlns_context* mp_ns_cxt = nullptr; + +public: + xml_element_printer(const tokens& t); + + void set_ns_context(const xmlns_context* ns_cxt); + + void print_namespace(std::ostream& os, xmlns_id_t ns) const; + + void print_element(std::ostream& os, xmlns_id_t ns, xml_token_t name) const; +}; + +void print_element(std::ostream& os, const tokens& t, xmlns_id_t ns, xml_token_t name); + +/** + * Print attributes to stdout for debugging purposes. + */ +void print_attrs(const tokens& tokens, const xml_token_attrs_t& attrs); + +} // namespace orcus + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xpath_parser.cpp b/src/liborcus/xpath_parser.cpp new file mode 100644 index 0000000..306b367 --- /dev/null +++ b/src/liborcus/xpath_parser.cpp @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xpath_parser.hpp" +#include "orcus/exception.hpp" +#include "orcus/xml_namespace.hpp" + +#define ORCUS_DEBUG_XPATH_PARSER 0 + +namespace orcus { + +xpath_parser::token::token(xmlns_id_t _ns, std::string_view _name, bool _attribute) : + ns(_ns), name(_name), attribute(_attribute) +{ +#if ORCUS_DEBUG_XPATH_PARSER + cout << "xpath_parser::token: (ns='" << (ns ? ns : "none") << "', name='" << name << "', attribute=" << attribute << ")" << endl; +#endif +} + +xpath_parser::token::token() : ns(XMLNS_UNKNOWN_ID), attribute(false) {} +xpath_parser::token::token(const token& r) : ns(r.ns), name(r.name), attribute(r.attribute) {} + +xpath_parser::xpath_parser(const xmlns_context& cxt, const char* p, size_t n, xmlns_id_t default_ns) : + m_cxt(cxt), + mp_char(p), + mp_end(p+n), + m_default_ns(default_ns) +{ + if (!n) + throw xpath_error("empty path"); + + if (*p != '/') + throw xpath_error("first character must be '/'."); + + ++mp_char; +} + +xpath_parser::token xpath_parser::next() +{ + if (mp_char == mp_end) + return token(); + + const char* p0 = nullptr; + size_t len = 0; + xmlns_id_t ns = m_default_ns; + + bool attribute = *mp_char == '@'; + if (attribute) + ++mp_char; + + for (; mp_char != mp_end; ++mp_char, ++len) + { + if (!p0) + { + p0 = mp_char; + len = 0; + } + + switch (*mp_char) + { + case '/': + { + ++mp_char; // skip the '/'. + return token(ns, std::string_view(p0, len), attribute); + } + case ':': + { + // What comes before ':' is a namespace. Reset the name and + // convert the namespace to a proper ID. + std::string_view ns_name(p0, len); + ns = m_cxt.get(ns_name); + p0 = nullptr; // reset the name. + break; + } + default: + ; + } + } + + // '/' has never been encountered. It must be the last name in the path. + return token(ns, std::string_view(p0, len), attribute); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xpath_parser.hpp b/src/liborcus/xpath_parser.hpp new file mode 100644 index 0000000..211d749 --- /dev/null +++ b/src/liborcus/xpath_parser.hpp @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_ORCUS_XPATH_PARSER_HPP +#define INCLUDED_ORCUS_XPATH_PARSER_HPP + +#include <orcus/types.hpp> + +namespace orcus { + +class xmlns_context; + +class xpath_parser +{ + const xmlns_context& m_cxt; + const char* mp_char; + const char* mp_end; + + xmlns_id_t m_default_ns; + + enum class token_type { element, attribute }; + +public: + + struct token + { + xmlns_id_t ns; + std::string_view name; + bool attribute; + + token(xmlns_id_t _ns, std::string_view _name, bool _attribute); + token(); + token(const token& r); + }; + + xpath_parser(const xmlns_context& cxt, const char* p, size_t n, xmlns_id_t default_ns); + + token next(); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/xpath_parser_test.cpp b/src/liborcus/xpath_parser_test.cpp new file mode 100644 index 0000000..26e7d6b --- /dev/null +++ b/src/liborcus/xpath_parser_test.cpp @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "xpath_parser.hpp" +#include "orcus/xml_namespace.hpp" + +#include <iostream> +#include <cassert> + +using namespace orcus; + +void test_elements() +{ + xmlns_repository repo; + xmlns_context cxt = repo.create_context(); + + std::string_view path("/A/B/C"); + + xpath_parser parser(cxt, path.data(), path.size(), XMLNS_UNKNOWN_ID); + auto token = parser.next(); + assert(token.name == "A"); + assert(!token.attribute); + + token = parser.next(); + assert(token.name == "B"); + assert(!token.attribute); + + token = parser.next(); + assert(token.name == "C"); + assert(!token.attribute); + + token = parser.next(); + assert(token.name.empty()); +} + +void test_attributes() +{ + xmlns_repository repo; + xmlns_context cxt = repo.create_context(); + + std::string_view path("/A/B/C/@foo"); + + xpath_parser parser(cxt, path.data(), path.size(), XMLNS_UNKNOWN_ID); + auto token = parser.next(); + assert(token.name == "A"); + assert(!token.attribute); + + token = parser.next(); + assert(token.name == "B"); + assert(!token.attribute); + + token = parser.next(); + assert(token.name == "C"); + assert(!token.attribute); + + token = parser.next(); + assert(token.name == "foo"); + assert(token.attribute); +} + +int main() +{ + test_elements(); + test_attributes(); + + return EXIT_SUCCESS; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ + diff --git a/src/liborcus/yaml_document_tree.cpp b/src/liborcus/yaml_document_tree.cpp new file mode 100644 index 0000000..1bd37a8 --- /dev/null +++ b/src/liborcus/yaml_document_tree.cpp @@ -0,0 +1,856 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/yaml_document_tree.hpp" +#include "orcus/yaml_parser.hpp" + +#include "json_util.hpp" + +#include <vector> +#include <memory> +#include <unordered_map> +#include <algorithm> +#include <iostream> + +#include <boost/current_function.hpp> + +#define ORCUS_DEBUG_YAML_TREE 0 + +#if ORCUS_DEBUG_YAML_TREE +#include <iostream> +#endif + +namespace orcus { namespace yaml { + +document_error::document_error(const std::string& msg) : + general_error("yaml_document_error", msg) {} + +document_error::~document_error() = default; + +struct yaml_value +{ + node_t type; + yaml_value* parent; + + yaml_value() : type(node_t::unset), parent(nullptr) {} + yaml_value(node_t _type) : type(_type), parent(nullptr) {} + virtual ~yaml_value() {} + + virtual size_t get_hash() const + { + return reinterpret_cast<size_t>(this); + } + + virtual std::string print() const + { + std::ostringstream os; + os << "type: "; + switch (type) + { + case node_t::unset: + os << "unset"; + break; + case node_t::string: + os << "string"; + break; + case node_t::number: + os << "number"; + break; + case node_t::map: + os << "map"; + break; + case node_t::sequence: + os << "sequence"; + break; + case node_t::boolean_true: + os << "true"; + break; + case node_t::boolean_false: + os << "false"; + break; + case node_t::null: + os << "null"; + break; + } + return os.str(); + } + + struct hash + { + size_t operator() (const yaml_value& v) const + { + return v.get_hash(); + } + }; +}; + +namespace { + +struct yaml_value_string : public yaml_value +{ + std::string value_string; + + yaml_value_string() : yaml_value(node_t::string) {} + yaml_value_string(std::string_view s) : yaml_value(node_t::string), value_string(s) {} + virtual ~yaml_value_string() {} + + virtual std::string print() const + { + std::ostringstream os; + os << "type: string, value: " << value_string; + return os.str(); + } +}; + +struct yaml_value_number : public yaml_value +{ + double value_number; + + yaml_value_number(double num) : yaml_value(node_t::number), value_number(num) {} + virtual ~yaml_value_number() {} + + virtual std::string print() const + { + std::ostringstream os; + os << "type: number, value: " << value_number; + return os.str(); + } +}; + +struct yaml_value_sequence : public yaml_value +{ + std::vector<std::unique_ptr<yaml_value>> value_sequence; + + yaml_value_sequence() : yaml_value(node_t::sequence) {} + virtual ~yaml_value_sequence() {} +}; + +struct yaml_value_map : public yaml_value +{ + std::vector<std::unique_ptr<yaml_value>> key_order; // owns the key instances. + std::unordered_map<const yaml_value*, std::unique_ptr<yaml_value>> value_map; + + yaml_value_map() : yaml_value(node_t::map) {} + virtual ~yaml_value_map() {} +}; + +struct parser_stack +{ + std::unique_ptr<yaml_value> key; + yaml_value* node; + + parser_stack(yaml_value* _node) : node(_node) {} + parser_stack(const parser_stack&) = delete; + parser_stack(parser_stack&& r) : key(std::move(r.key)), node(r.node) {} +}; + +typedef std::unique_ptr<yaml_value> document_root_type; + +class handler +{ + std::vector<document_root_type> m_docs; + + std::vector<parser_stack> m_stack; + std::vector<parser_stack> m_key_stack; + + document_root_type m_root; + document_root_type m_key_root; + + bool m_in_document; + +#if ORCUS_DEBUG_YAML_TREE + void print_stack() + { + std::ostringstream os; + os << '('; + for (auto i = m_stack.begin(), ie = m_stack.end(); i != ie; ++i) + os << i->node->print() << ','; + os << ')'; + std::cout << os.str() << std::endl; + } +#endif + + yaml_value* push_value(std::unique_ptr<yaml_value>&& value) + { + assert(!m_stack.empty()); + parser_stack& cur = m_stack.back(); + + switch (cur.node->type) + { + case node_t::sequence: + { + yaml_value_sequence* yvs = static_cast<yaml_value_sequence*>(cur.node); + value->parent = yvs; + yvs->value_sequence.push_back(std::move(value)); + return yvs->value_sequence.back().get(); + } + case node_t::map: + { + yaml_value_map* yvm = static_cast<yaml_value_map*>(cur.node); + value->parent = yvm; + + yvm->key_order.push_back(std::move(cur.key)); + + auto r = yvm->value_map.insert( + std::make_pair( + yvm->key_order.back().get(), std::move(value))); + + return r.first->second.get(); + } + default: + break; + } + + std::ostringstream os; + os << BOOST_CURRENT_FUNCTION << ": unstackable YAML value type (" << cur.node->print() << ")."; + throw document_error(os.str()); + } + +public: + handler() : m_in_document(false) {} + + void begin_parse() + { + } + + void end_parse() + { + } + + void begin_document() + { + assert(!m_in_document); + m_in_document = true; + m_root.reset(); + } + + void end_document() + { + assert(m_stack.empty()); + m_in_document = false; + m_docs.push_back(std::move(m_root)); + } + + void begin_sequence() + { + assert(m_in_document); + + if (m_root) + { + yaml_value* yv = push_value(std::make_unique<yaml_value_sequence>()); + assert(yv && yv->type == node_t::sequence); + m_stack.push_back(parser_stack(yv)); + } + else + { + m_root = std::make_unique<yaml_value_sequence>(); + m_stack.push_back(parser_stack(m_root.get())); + } + } + + void end_sequence() + { + assert(!m_stack.empty()); + m_stack.pop_back(); + } + + void begin_map() + { + assert(m_in_document); + if (m_root) + { + yaml_value* yv = push_value(std::make_unique<yaml_value_map>()); + assert(yv && yv->type == node_t::map); + m_stack.push_back(parser_stack(yv)); + } + else + { + m_root = std::make_unique<yaml_value_map>(); + m_stack.push_back(parser_stack(m_root.get())); + } + } + + void begin_map_key() + { + assert(!m_key_root); + assert(m_key_stack.empty()); + m_key_root.swap(m_root); + m_key_stack.swap(m_stack); + } + + void end_map_key() + { + m_key_root.swap(m_root); + m_key_stack.swap(m_stack); + + assert(!m_stack.empty()); + parser_stack& cur = m_stack.back(); + cur.key.swap(m_key_root); + m_key_stack.clear(); + m_key_root.reset(); + } + + void end_map() + { + assert(!m_stack.empty()); + m_stack.pop_back(); + } + + void string(std::string_view v) + { + assert(m_in_document); + + if (m_root) + { + yaml_value* yv = push_value(std::make_unique<yaml_value_string>(v)); + assert(yv && yv->type == node_t::string); + } + else + m_root = std::make_unique<yaml_value_string>(v); + } + + void number(double val) + { + assert(m_in_document); + if (m_root) + { + yaml_value* yv = push_value(std::make_unique<yaml_value_number>(val)); + assert(yv && yv->type == node_t::number); + } + else + m_root = std::make_unique<yaml_value_number>(val); + } + + void boolean_true() + { + assert(m_in_document); + if (m_root) + { + yaml_value* yv = push_value(std::make_unique<yaml_value>(node_t::boolean_true)); + assert(yv && yv->type == node_t::boolean_true); + } + else + m_root = std::make_unique<yaml_value>(node_t::boolean_true); + } + + void boolean_false() + { + assert(m_in_document); + if (m_root) + { + yaml_value* yv = push_value(std::make_unique<yaml_value>(node_t::boolean_false)); + assert(yv && yv->type == node_t::boolean_false); + } + else + m_root = std::make_unique<yaml_value>(node_t::boolean_false); + } + + void null() + { + assert(m_in_document); + if (m_root) + { + yaml_value* yv = push_value(std::make_unique<yaml_value>(node_t::null)); + assert(yv && yv->type == node_t::null); + } + else + m_root = std::make_unique<yaml_value>(node_t::null); + } + + void swap(std::vector<document_root_type>& docs) + { + m_docs.swap(docs); + } +}; + +} // anonymous namespace + +struct document_tree::impl +{ + std::vector<document_root_type> m_docs; +}; + +struct const_node::impl +{ + const yaml_value* m_node; + + impl(const yaml_value* yv) : m_node(yv) {} +}; + +const_node::const_node(const yaml_value* yv) : mp_impl(std::make_unique<impl>(yv)) {} +const_node::const_node(const const_node& other) : mp_impl(std::make_unique<impl>(other.mp_impl->m_node)) {} +const_node::const_node(const_node&& rhs) : mp_impl(std::move(rhs.mp_impl)) {} +const_node::~const_node() {} + +const_node& const_node::operator=(const const_node& other) +{ + if (this == &other) + return *this; + + const_node tmp(other); + mp_impl.swap(tmp.mp_impl); + return *this; +} + +uintptr_t const_node::identity() const +{ + return reinterpret_cast<uintptr_t>(mp_impl->m_node); +} + +node_t const_node::type() const +{ + return mp_impl->m_node->type; +} + +size_t const_node::child_count() const +{ + switch (mp_impl->m_node->type) + { + case node_t::map: + return static_cast<const yaml_value_map*>(mp_impl->m_node)->value_map.size(); + case node_t::sequence: + return static_cast<const yaml_value_sequence*>(mp_impl->m_node)->value_sequence.size(); + case node_t::string: + case node_t::number: + case node_t::boolean_true: + case node_t::boolean_false: + case node_t::null: + case node_t::unset: + default: + ; + } + return 0; +} + +std::vector<const_node> const_node::keys() const +{ + if (mp_impl->m_node->type != node_t::map) + throw document_error("node::keys: this node is not of map type."); + + const yaml_value_map* yvm = static_cast<const yaml_value_map*>(mp_impl->m_node); + std::vector<const_node> keys; + std::for_each(yvm->key_order.begin(), yvm->key_order.end(), + [&](const std::unique_ptr<yaml_value>& key) + { + keys.push_back(const_node(key.get())); + } + ); + + return keys; +} + +const_node const_node::key(size_t index) const +{ + if (mp_impl->m_node->type != node_t::map) + throw document_error("node::key: this node is not of map type."); + + const yaml_value_map* yvm = static_cast<const yaml_value_map*>(mp_impl->m_node); + if (index >= yvm->key_order.size()) + throw std::out_of_range("node::key: index is out-of-range."); + + return const_node(yvm->key_order[index].get()); +} + +const_node const_node::child(size_t index) const +{ + switch (mp_impl->m_node->type) + { + case node_t::map: + { + const yaml_value_map* yvm = static_cast<const yaml_value_map*>(mp_impl->m_node); + if (index >= yvm->key_order.size()) + throw std::out_of_range("node::child: index is out-of-range"); + + const yaml_value* key = yvm->key_order[index].get(); + auto it = yvm->value_map.find(key); + assert(it != yvm->value_map.end()); + return const_node(it->second.get()); + } + break; + case node_t::sequence: + { + const yaml_value_sequence* yvs = static_cast<const yaml_value_sequence*>(mp_impl->m_node); + if (index >= yvs->value_sequence.size()) + throw std::out_of_range("node::child: index is out-of-range"); + + return const_node(yvs->value_sequence[index].get()); + } + break; + case node_t::string: + case node_t::number: + case node_t::boolean_true: + case node_t::boolean_false: + case node_t::null: + case node_t::unset: + default: + throw document_error("node::child: this node cannot have child nodes."); + } +} + +const_node const_node::child(const const_node& key) const +{ + if (mp_impl->m_node->type != node_t::map) + throw document_error("node::child: this node is not of map type."); + + const yaml_value_map* yvm = static_cast<const yaml_value_map*>(mp_impl->m_node); + auto it = yvm->value_map.find(key.mp_impl->m_node); + if (it == yvm->value_map.end()) + throw document_error("node::child: this map does not have the specified key."); + + return const_node(it->second.get()); +} + +const_node const_node::parent() const +{ + if (!mp_impl->m_node->parent) + throw document_error("node::parent: this node has no parent."); + + return const_node(mp_impl->m_node->parent); +} + +std::string_view const_node::string_value() const +{ + if (mp_impl->m_node->type != node_t::string) + throw document_error("node::key: current node is not of string type."); + + const yaml_value_string* yvs = static_cast<const yaml_value_string*>(mp_impl->m_node); + return yvs->value_string; +} + +double const_node::numeric_value() const +{ + if (mp_impl->m_node->type != node_t::number) + throw document_error("node::key: current node is not of numeric type."); + + const yaml_value_number* yvn = static_cast<const yaml_value_number*>(mp_impl->m_node); + return yvn->value_number; +} + +document_tree::document_tree() : + mp_impl(std::make_unique<impl>()) {} + +document_tree::document_tree(document_tree&& other) : + mp_impl(std::move(other.mp_impl)) {} + +document_tree::~document_tree() {} + +void document_tree::load(std::string_view s) +{ + handler hdl; + yaml_parser<handler> parser(s, hdl); + parser.parse(); + hdl.swap(mp_impl->m_docs); +} + +size_t document_tree::get_document_count() const +{ + return mp_impl->m_docs.size(); +} + +const_node document_tree::get_document_root(size_t index) const +{ + return const_node(mp_impl->m_docs[index].get()); +} + +namespace { + +const char* indent = " "; +const char* kw_true = "true"; +const char* kw_false = "false"; +const char* kw_tilde = "~"; +const char* kw_null = "null"; + +const char quote = '"'; + +void dump_indent(std::ostringstream& os, size_t scope) +{ + for (size_t i = 0; i < scope; ++i) + os << indent; +} + +bool needs_quoting(const std::string& s) +{ + // See if it contains certain characters... + for (auto it = s.begin(), ite = s.end(); it != ite; ++it) + if (is_in(*it, "#'")) + return true; + + // See if the whole string is parsed as a number. + const char* p = s.data(); + const char* p_end = p + s.size(); + double v; + p = parse_numeric(p, p_end, v); + if (p == p_end) + return true; + + return false; +} + +void dump_yaml_string(std::ostringstream& os, const std::string& s) +{ + if (needs_quoting(s)) + os << quote << s << quote; + else + os << s; +} + +void dump_yaml_map(std::ostringstream& os, const yaml_value& node, size_t scope); +void dump_yaml_sequence(std::ostringstream& os, const yaml_value& node, size_t scope); + +void dump_yaml_node(std::ostringstream& os, const yaml_value& node, size_t scope) +{ + switch (node.type) + { + case node_t::map: + dump_yaml_map(os, node, scope); + break; + case node_t::sequence: + dump_yaml_sequence(os, node, scope); + break; + case node_t::boolean_true: + dump_indent(os, scope); + os << kw_true << std::endl; + break; + case node_t::boolean_false: + dump_indent(os, scope); + os << kw_false << std::endl; + break; + case node_t::null: + dump_indent(os, scope); + os << kw_tilde << std::endl; + break; + case node_t::number: + dump_indent(os, scope); + os << static_cast<const yaml_value_number&>(node).value_number << std::endl; + break; + case node_t::string: + dump_indent(os, scope); + dump_yaml_string(os, static_cast<const yaml_value_string&>(node).value_string); + os << std::endl; + break; + case node_t::unset: + default: + ; + } +} + +void dump_yaml_container_item(std::ostringstream& os, const yaml_value& node, size_t scope) +{ + switch (node.type) + { + case node_t::map: + case node_t::sequence: + // End the line and dump this child container in the next scope. + os << std::endl; + dump_yaml_node(os, node, scope+1); + break; + default: + // Dump inline. + os << " "; + dump_yaml_node(os, node, 0); + } +} + +void dump_yaml_map(std::ostringstream& os, const yaml_value& node, size_t scope) +{ + const yaml_value_map& yvm = static_cast<const yaml_value_map&>(node); + + std::for_each(yvm.key_order.begin(), yvm.key_order.end(), + [&](const std::unique_ptr<yaml_value>& pkey) + { + const yaml_value* key = pkey.get(); + + switch (key->type) + { + case node_t::map: + // TODO + break; + case node_t::sequence: + // TODO + break; + case node_t::boolean_true: + dump_indent(os, scope); + os << kw_true; + break; + case node_t::boolean_false: + dump_indent(os, scope); + os << kw_false; + break; + case node_t::null: + dump_indent(os, scope); + os << kw_tilde; + break; + case node_t::number: + dump_indent(os, scope); + os << static_cast<const yaml_value_number*>(key)->value_number; + break; + case node_t::string: + dump_indent(os, scope); + dump_yaml_string(os, static_cast<const yaml_value_string*>(key)->value_string); + break; + case node_t::unset: + default: + ; + } + + os << ":"; + auto it = yvm.value_map.find(key); + assert(it != yvm.value_map.end()); + const yaml_value& value = *it->second; + dump_yaml_container_item(os, value, scope); + } + ); +} + +void dump_yaml_sequence(std::ostringstream& os, const yaml_value& node, size_t scope) +{ + const yaml_value_sequence& yvs = static_cast<const yaml_value_sequence&>(node); + + std::for_each(yvs.value_sequence.begin(), yvs.value_sequence.end(), + [&](const std::unique_ptr<yaml_value>& p) + { + const yaml_value& child = *p; + dump_indent(os, scope); + os << "-"; + dump_yaml_container_item(os, child, scope); + } + ); +} + +void dump_yaml_document(std::ostringstream& os, const yaml_value& root) +{ + os << "---" << std::endl; + dump_yaml_node(os, root, 0); +} + +void dump_json_node(std::ostringstream& os, const yaml_value& node, size_t scope, const std::string* key); + +void dump_json_item( + std::ostringstream& os, const std::string* key, const yaml_value& val, + size_t scope, bool sep) +{ + dump_json_node(os, val, scope+1, key); + if (sep) + os << ","; + os << std::endl; +} + +void dump_json_node(std::ostringstream& os, const yaml_value& node, size_t scope, const std::string* key = nullptr) +{ + dump_indent(os, scope); + + if (key) + { + os << quote << *key << quote << ": "; + } + + switch (node.type) + { + case node_t::map: + { + auto& key_order = static_cast<const yaml_value_map&>(node).key_order; + auto& vals = static_cast<const yaml_value_map&>(node).value_map; + os << "{" << std::endl; + size_t n = vals.size(); + + // Dump them based on key's original ordering. + size_t pos = 0; + for (auto it = key_order.begin(), ite = key_order.end(); it != ite; ++it, ++pos) + { + const yaml_value* this_key = it->get(); + if (this_key->type != node_t::string) + throw document_error("JSON doesn't support non-string key."); + + auto val_pos = vals.find(this_key); + assert(val_pos != vals.end()); + + dump_json_item( + os, + &static_cast<const yaml_value_string*>(this_key)->value_string, + *val_pos->second, scope, pos < (n-1)); + } + + dump_indent(os, scope); + os << "}"; + } + break; + case node_t::sequence: + { + auto& vals = static_cast<const yaml_value_sequence&>(node).value_sequence; + os << "[" << std::endl; + size_t n = vals.size(); + size_t pos = 0; + for (auto it = vals.begin(), ite = vals.end(); it != ite; ++it, ++pos) + dump_json_item(os, nullptr, **it, scope, pos < (n-1)); + + dump_indent(os, scope); + os << "]"; + } + break; + case node_t::boolean_true: + os << kw_true; + break; + case node_t::boolean_false: + os << kw_false; + break; + case node_t::null: + os << kw_null; + break; + case node_t::number: + os << static_cast<const yaml_value_number&>(node).value_number; + break; + case node_t::string: + json::dump_string(os, static_cast<const yaml_value_string&>(node).value_string); + break; + case node_t::unset: + default: + ; + } +} + +const char* warning_multiple_documents = +"warning: this YAML file contains multiple documents. Only the first document\n" +"will be written."; + +} + +std::string document_tree::dump_yaml() const +{ + std::ostringstream os; + + std::for_each( + mp_impl->m_docs.begin(), mp_impl->m_docs.end(), + [&](const document_root_type& root) + { + dump_yaml_document(os, *root); + } + ); + + return os.str(); +} + +std::string document_tree::dump_json() const +{ + if (mp_impl->m_docs.empty()) + return std::string(); + + if (mp_impl->m_docs.size() > 1) + std::cerr << warning_multiple_documents << std::endl; + + const yaml_value& root = *mp_impl->m_docs.front(); + + std::ostringstream os; + dump_json_node(os, root, 0); + + os << std::endl; + + return os.str(); +} + +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/yaml_document_tree_test.cpp b/src/liborcus/yaml_document_tree_test.cpp new file mode 100644 index 0000000..cb674ea --- /dev/null +++ b/src/liborcus/yaml_document_tree_test.cpp @@ -0,0 +1,642 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/yaml_document_tree.hpp" +#include "orcus/stream.hpp" +#include "orcus/yaml_parser_base.hpp" + +#include <cassert> +#include <iostream> +#include <cmath> + +#include "filesystem_env.hpp" + +using namespace orcus; +using namespace std; + +bool string_expected(const yaml::const_node& node, const char* expected) +{ + if (node.type() != yaml::node_t::string) + return false; + + if (node.string_value() == expected) + return true; + + cerr << "expected='" << expected << "', actual='" << node.string_value() << "'" << endl; + return false; +} + +bool number_expected( + const yaml::const_node& node, double expected, + double decimal = 0.0, double exponent = 0.0) +{ + if (node.type() != yaml::node_t::number) + return false; + + double actual = node.numeric_value(); + if (!decimal || !exponent) + return actual == expected; + + // Remove the exponent component. + actual /= std::pow(10.0, exponent); + expected /= std::pow(10.0, exponent); + + // Only compare down to the specified decimal place. + actual *= std::pow(10.0, decimal); + expected *= std::pow(10.0, decimal); + + actual = std::round(actual); + expected = std::round(expected); + + return actual == expected; +} + +yaml::document_tree load_doc(const char* filepath) +{ + cout << filepath << endl; + file_content strm(filepath); + cout << strm.str() << endl; + yaml::document_tree doc; + doc.load(strm.str()); + + return doc; +} + +void test_yaml_invalids() +{ + // Get all yaml files in this directory. + fs::path dirpath(SRCDIR"/test/yaml/invalids/"); + fs::directory_iterator it_end; + + size_t file_count = 0; + + for (fs::directory_iterator it(dirpath); it != it_end; ++it) + { + auto path = it->path(); + if (!fs::is_regular_file(path)) + continue; + + if (path.extension().string() != ".yaml") + continue; + + ++file_count; + + file_content strm(path.string().data()); + yaml::document_tree doc; + + try + { + doc.load(strm.str()); + assert(!"yaml::parse_error was not thrown, but expected to be."); + } + catch (const parse_error&) + { + // This is expected. + } + } + + assert(file_count > 0); +} + +void test_yaml_parse_basic1() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/basic1/input.yaml"); + + assert(doc.get_document_count() == 1); + + // Document root is a map node with 4 elements. + yaml::const_node root = doc.get_document_root(0); + uintptr_t root_id = root.identity(); + assert(root.type() == yaml::node_t::map); + assert(root.child_count() == 4); + + std::vector<yaml::const_node> keys = root.keys(); + assert(keys.size() == 4); + + yaml::const_node key = keys[0]; + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "dict"); + + key = keys[1]; + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "list"); + + key = keys[2]; + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "number"); + + key = keys[3]; + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "string"); + + // first child is a map. + yaml::const_node node = root.child(keys[0]); + assert(node.type() == yaml::node_t::map); + assert(node.child_count() == 3); + + key = node.key(0); + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "a"); + + key = node.key(1); + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "b"); + + key = node.key(2); + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "c"); + + node = node.child(0); + assert(node.type() == yaml::node_t::number); + assert(node.numeric_value() == 1.0); + node = node.parent(); + + node = node.child(1); + assert(node.type() == yaml::node_t::number); + assert(node.numeric_value() == 2.0); + node = node.parent(); + + node = node.child(2); + assert(node.type() == yaml::node_t::sequence); + assert(node.child_count() == 2); + yaml::const_node child = node.child(0); + assert(child.type() == yaml::node_t::string); + assert(child.string_value() == "foo"); + child = node.child(1); + assert(child.type() == yaml::node_t::string); + assert(child.string_value() == "bar"); + + // Go up to the root node. + node = node.parent().parent(); + assert(node.type() == yaml::node_t::map); + assert(node.identity() == root_id); + + node = node.child(keys[1]); + assert(node.type() == yaml::node_t::sequence); + assert(node.child_count() == 3); + + node = node.child(0); + assert(node.type() == yaml::node_t::number); + assert(node.numeric_value() == 1.0); + node = node.parent(); + + node = node.child(1); + assert(node.type() == yaml::node_t::number); + assert(node.numeric_value() == 2.0); + node = node.parent(); + + node = node.child(2); + assert(node.type() == yaml::node_t::map); + assert(node.child_count() == 3); + + key = node.key(0); + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "a"); + + key = node.key(1); + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "b"); + + key = node.key(2); + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "c"); + + node = node.child(0); + assert(node.type() == yaml::node_t::number); + assert(node.numeric_value() == 1.1); + node = node.parent(); + + node = node.child(1); + assert(node.type() == yaml::node_t::number); + assert(node.numeric_value() == 1.2); + node = node.parent(); + + node = node.child(2); + assert(node.type() == yaml::node_t::number); + assert(node.numeric_value() == 1.3); + node = node.parent(); + + node = node.parent().parent(); // back to the root. + assert(node.identity() == root_id); + + key = node.key(2); + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "number"); + + key = node.key(3); + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "string"); + + node = node.child(2); + assert(node.type() == yaml::node_t::number); + assert(node.numeric_value() == 12.3); + node = node.parent(); + + node = node.child(3); + assert(node.type() == yaml::node_t::string); + assert(node.string_value() == "foo"); + node = node.parent(); +} + +void test_yaml_parse_basic2() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/basic2/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + + assert(node.type() == yaml::node_t::sequence); + assert(node.child_count() == 3); + + node = node.child(0); + assert(node.type() == yaml::node_t::number); + assert(node.numeric_value() == 1); + node = node.parent(); + + node = node.child(1); + assert(node.type() == yaml::node_t::number); + assert(node.numeric_value() == 2); + node = node.parent(); + + node = node.child(2); + assert(node.type() == yaml::node_t::number); + assert(node.numeric_value() == 3); + node = node.parent(); +} + +void test_yaml_parse_basic3() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/basic3/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + + assert(node.type() == yaml::node_t::sequence); + assert(node.child_count() == 2); + + node = node.child(0); + assert(node.type() == yaml::node_t::map); + assert(node.child_count() == 3); + + assert(string_expected(node.key(0), "a")); + assert(string_expected(node.key(1), "b")); + assert(string_expected(node.key(2), "c")); + + assert(number_expected(node.child(0), 1)); + assert(number_expected(node.child(1), 2)); + assert(number_expected(node.child(2), 3)); + + node = node.parent(); + + node = node.child(1); + assert(node.type() == yaml::node_t::map); + assert(node.child_count() == 3); + + assert(string_expected(node.key(0), "d")); + assert(string_expected(node.key(1), "e")); + assert(string_expected(node.key(2), "f")); + + assert(number_expected(node.child(0), 4)); + assert(number_expected(node.child(1), 5)); + assert(number_expected(node.child(2), 6)); +} + +void test_yaml_parse_null() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/null/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + + assert(node.type() == yaml::node_t::sequence); + assert(node.child_count() == 6); + + node = node.child(0); + assert(node.type() == yaml::node_t::null); + node = node.parent(); + + node = node.child(1); + assert(node.type() == yaml::node_t::null); + node = node.parent(); + + node = node.child(2); + assert(node.type() == yaml::node_t::null); + node = node.parent(); + + node = node.child(3); + assert(node.type() == yaml::node_t::null); + node = node.parent(); + + node = node.child(4); + assert(node.type() == yaml::node_t::string); + assert(node.string_value() == "nULL"); + node = node.parent(); + + node = node.child(5); + assert(node.type() == yaml::node_t::string); + assert(node.string_value() == "NUll"); + node = node.parent(); +} + +void test_yaml_parse_boolean() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/boolean/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + + assert(node.type() == yaml::node_t::map); + assert(node.child_count() == 3); + + yaml::const_node key = node.key(0); + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "positive"); + + key = node.key(1); + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "negative"); + + key = node.key(2); + assert(key.type() == yaml::node_t::string); + assert(key.string_value() == "non boolean"); + + // list of boolean true's. + node = node.child(0); + assert(node.type() == yaml::node_t::sequence); + assert(node.child_count() == 11); + for (size_t i = 0; i < node.child_count(); ++i) + { + yaml::const_node child = node.child(i); + assert(child.type() == yaml::node_t::boolean_true); + } + node = node.parent(); + + // list of boolean false's. + node = node.child(1); + assert(node.type() == yaml::node_t::sequence); + assert(node.child_count() == 11); + for (size_t i = 0; i < node.child_count(); ++i) + { + yaml::const_node child = node.child(i); + assert(child.type() == yaml::node_t::boolean_false); + } + node = node.parent(); + + // list of strings. + const char* values[] = { + "yES", + "nO", + "tRUE", + "faLSE", + "oN", + "oFF" + }; + + node = node.child(2); + assert(node.type() == yaml::node_t::sequence); + assert(node.child_count() == std::size(values)); + + for (size_t i = 0; i < std::size(values); ++i) + { + node = node.child(i); + assert(node.type() == yaml::node_t::string); + assert(node.string_value() == values[i]); + node = node.parent(); + } +} + +void test_yaml_parse_quoted_string() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/quoted-string/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + + assert(node.type() == yaml::node_t::map); + assert(node.child_count() == 3); + + assert(string_expected(node.key(0), "I am quoted: ~ ")); + assert(string_expected(node.key(1), "list with quoted string values")); + assert(string_expected(node.key(2), "single quoted string values")); + assert(string_expected(node.child(0), "Here is another quote.")); + + node = node.child(1); + + { + // list of strings. + const char* values[] = { + "1 2 3", + "null", + "true", + "false", + "#hashtag", + "\"quoted inside\"", + "'single quote inside'", + "Japan's finest beer" + }; + + size_t n = std::size(values); + assert(node.type() == yaml::node_t::sequence); + assert(node.child_count() == n); + + for (size_t i = 0; i < n; ++i) + assert(string_expected(node.child(i), values[i])); + } + + node = node.parent().child(2); + + { + // list of strings. + const char* values[] = { + "8.8.8.8", + "'single quote inside'", + "prefix 'quoted' suffix", + "\"double quote\"", + "before \"quote\" after", + "http://www.google.com", + "'''", + " ' ' ' ", + "#hashtag" + }; + + size_t n = std::size(values); + assert(node.type() == yaml::node_t::sequence); + assert(node.child_count() == n); + + for (size_t i = 0; i < n; ++i) + assert(string_expected(node.child(i), values[i])); + } +} + +void test_yaml_parse_multi_line_1() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/multi-line-1/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + assert(string_expected(node, "1 2 3")); + assert(node.child_count() == 0); +} + +void test_yaml_parse_multi_line_2() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/multi-line-2/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + assert(string_expected(node, "1 - 2 - 3")); + assert(node.child_count() == 0); +} + +void test_yaml_parse_literal_block_1() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/literal-block-1/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + + assert(string_expected(node, "line 1\n line 2\nline 3\n2 blanks follow ")); + assert(node.child_count() == 0); +} + +void test_yaml_parse_literal_block_2() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/literal-block-2/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + + assert(node.type() == yaml::node_t::map); + assert(node.child_count() == 2); + + assert(string_expected(node.key(0), "literal block")); + assert(string_expected(node.child(0), "line 1\n line 2\n line 3")); + assert(string_expected(node.key(1), "multi line")); + assert(string_expected(node.child(1), "line 1 line 2 line 3")); +} + +void test_yaml_parse_url() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/url/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + + assert(node.type() == yaml::node_t::sequence); + assert(node.child_count() == 3); + + assert(string_expected(node.child(0), "http://www.google.com/")); + assert(string_expected(node.child(1), "mailto:joe@joe-me.com")); + + node = node.child(2); + assert(node.type() == yaml::node_t::map); + assert(node.child_count() == 2); + + assert(string_expected(node.key(0), "orcus-url")); + assert(string_expected(node.key(1), "debian-bugs")); + assert(string_expected(node.child(0), "http://gitlab.com/orcus/orcus")); + assert(string_expected(node.child(1), "mailto:submit@bugs.debian.org")); +} + +void test_yaml_parse_empty_value_map_1() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/empty-value-map-1/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + + assert(node.type() == yaml::node_t::map); + assert(node.child_count() == 1); + + assert(string_expected(node.key(0), "key")); + assert(node.child(0).type() == yaml::node_t::null); +} + +void test_yaml_parse_empty_value_map_2() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/empty-value-map-2/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + + assert(node.type() == yaml::node_t::map); + assert(node.child_count() == 2); + + assert(string_expected(node.key(0), "key1")); + assert(node.child(0).type() == yaml::node_t::null); + assert(string_expected(node.key(1), "key2")); + assert(node.child(1).type() == yaml::node_t::null); +} + +void test_yaml_parse_empty_value_sequence_1() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/empty-value-sequence-1/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + + assert(node.type() == yaml::node_t::sequence); + assert(node.child_count() == 1); + + assert(node.child(0).type() == yaml::node_t::null); +} + +void test_yaml_parse_empty_value_sequence_2() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/empty-value-sequence-2/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + + assert(node.type() == yaml::node_t::sequence); + assert(node.child_count() == 2); + + assert(node.child(0).type() == yaml::node_t::null); + assert(node.child(1).type() == yaml::node_t::null); +} + +void test_yaml_map_key_1() +{ + yaml::document_tree doc = load_doc(SRCDIR"/test/yaml/map-key-1/input.yaml"); + + assert(doc.get_document_count() == 1); + yaml::const_node node = doc.get_document_root(0); + + assert(node.type() == yaml::node_t::map); + assert(node.child_count() == 2); + + assert(string_expected(node.key(0), "-key")); + assert(string_expected(node.child(0), "value")); + assert(string_expected(node.key(1), "key")); + assert(string_expected(node.child(1), "value")); +} + +int main() +{ + test_yaml_invalids(); + test_yaml_parse_basic1(); + test_yaml_parse_basic2(); + test_yaml_parse_basic3(); + test_yaml_parse_null(); + test_yaml_parse_boolean(); + test_yaml_parse_quoted_string(); + test_yaml_parse_multi_line_1(); + test_yaml_parse_multi_line_2(); + test_yaml_parse_literal_block_1(); + test_yaml_parse_literal_block_2(); + test_yaml_parse_url(); + test_yaml_parse_empty_value_map_1(); + test_yaml_parse_empty_value_map_2(); + test_yaml_parse_empty_value_sequence_1(); + test_yaml_parse_empty_value_sequence_2(); + test_yaml_map_key_1(); + + return EXIT_SUCCESS; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ + |