]> git.lyx.org Git - lyx.git/blob - development/autotests/export.cmake
85195c67cfe4cb9a715eff0ad485e380e2d37cee
[lyx.git] / development / autotests / export.cmake
1 # This file is part of LyX, the document processor.
2 # Licence details can be found in the file COPYING.
3 #
4 # Copyright (c) 2012 Kornel Benko kornel@lyx.org
5 #
6 #
7 # LYX_ROOT  = ${TOP_SRC_DIR}/lib/{doc,examples,templates,tabletemplates}
8 # LYX_USERDIR_VER = Name of environment variable for the user directory
9 # lyx       =
10 # format    = lyx16x|lyx20x|lyx21x|lyx22x|xhtml|docbook5|epub
11 # extension = 16.lyx|20.lyx|21.lyx|22.lyx|xhtml|xml|epub
12 # file      = xxx
13 #
14 # Script should be called like:
15 # cmake -DLYX_ROOT=xxx \
16 #       -DLYX_TESTS_USERDIR=${LYX_TESTS_USERDIR} \
17 #       -DWORKDIR=${BUILD_DIR}/autotests/out-home \
18 #       -DLYX_USERDIR_VER=${LYX_USERDIR_VER} \
19 #       -Dlyx=xxx \
20 #       -Dformat=xxx \
21 #       -Dfonttype=xxx \
22 #       -Dextension=xxx \
23 #       -DLYX_FORMAT_NUM=${_lyx_format_num} \
24 #       -Dfile=xxx \
25 #       -Dinverted=[01] \
26 #       -DTOP_SRC_DIR=${TOP_SRC_DIR} \
27 #       -DIgnoreErrorMessage=(ON/OFF) \
28 #       -DPERL_EXECUTABLE=${PERL_EXECUTABLE} \
29 #       -DLYX_PYTHON_EXECUTABLE=${LYX_PYTHON_EXECUTABLE} \
30 #       -DXMLLINT_EXECUTABLE=${XMLLINT_EXECUTABLE} \
31 #       -DJAVA_EXECUTABLE=${JAVA_EXECUTABLE} \
32 #       -DENCODING=xxx \
33 #       -P "${TOP_SRC_DIR}/development/autotests/export.cmake"
34 #
35
36 set(_TestResultMessage "")
37 message(STATUS "IgnoreErrorMessage = \"${IgnoreErrorMessage}\"")
38 set(Perl_Script "${TOP_SRC_DIR}/development/autotests/useSystemFonts.pl")
39 set(Structure_Script "${TOP_SRC_DIR}/development/autotests/beginEndStructureCheck.pl")
40 set(LanguageFile "${TOP_SRC_DIR}/lib/languages")
41 set(GetTempDir "${TOP_SRC_DIR}/development/autotests/getTempDir.pl")
42 set(_ft ${fonttype})
43 execute_process(COMMAND ${PERL_EXECUTABLE} "${GetTempDir}" "${WORKDIR}" OUTPUT_VARIABLE TempDir)
44 message(STATUS "using fonttype = ${_ft}")
45 if(NOT ENCODING)
46   set(ENCODING "default")
47 endif()
48 if(ENCODING STREQUAL "default")
49   set(_enc)
50 else()
51   set(_enc "_${ENCODING}")
52 endif()
53
54 # move the the last directory part of LYX_ROOT to filename
55 # to make the destination unique for otherwise identical
56 # filenames
57 get_filename_component(updir_ "${LYX_ROOT}" DIRECTORY)
58 get_filename_component(updir2_ "${LYX_ROOT}" NAME)
59 set(file "${updir2_}/${file}")
60 set(LYX_ROOT "${updir_}")
61 set(NO_FAILES 0)
62
63 if(format MATCHES "dvi|pdf")
64   message(STATUS "LYX_TESTS_USERDIR = ${LYX_TESTS_USERDIR}")
65   message(STATUS "Converting with perl ${Perl_Script}")
66   set(LYX_SOURCE "${TempDir}/${file}_${format}_${_ft}${_enc}.lyx")
67   message(STATUS "Using source \"${LYX_ROOT}/${file}.lyx\"")
68   message(STATUS "Using dest \"${LYX_SOURCE}\"")
69   if(NOT "${ENCODING}" STREQUAL "default")
70     # message(STATUS "ENCODING = ${ENCODING}")
71   endif()
72   message(STATUS "Executing ${PERL_EXECUTABLE} \"${Perl_Script}\" \"${LYX_ROOT}/${file}.lyx\" \"${LYX_SOURCE}\" ${format} ${_ft} ${ENCODING} ${LanguageFile}")
73   execute_process(COMMAND ${PERL_EXECUTABLE} "${Perl_Script}" "${LYX_ROOT}/${file}.lyx" "${LYX_SOURCE}" ${format} ${_ft} ${ENCODING} ${LanguageFile}
74     RESULT_VARIABLE _err)
75   string(COMPARE EQUAL  ${_err} 0 _erg)
76   if(NOT _erg)
77     set(NO_FAILES 1)
78     message(FATAL_ERROR "Export failed while converting")
79   endif()
80   # We only need "_${ENCODING}" for unicode tests (because multiple encodings
81   # are tested with the same format), but doesn't hurt to include for all.
82   set(result_file_name ${file}_${_ft}_${ENCODING}.${extension})
83 else()
84   message(STATUS "Converting with perl ${Perl_Script}")
85   set(LYX_SOURCE "${TempDir}/${file}.lyx")
86   message(STATUS "Using source \"${LYX_ROOT}/${file}.lyx\"")
87   message(STATUS "Using dest \"${LYX_SOURCE}\"")
88   execute_process(COMMAND ${PERL_EXECUTABLE} "${Perl_Script}" "${LYX_ROOT}/${file}.lyx" "${LYX_SOURCE}" ${format} "dontChange" "default" ${LanguageFile}
89     RESULT_VARIABLE _err)
90   string(COMPARE EQUAL  ${_err} 0 _erg)
91   if(NOT _erg)
92     set(NO_FAILES 1)
93     message(FATAL_ERROR "Export failed while converting")
94   endif()
95   if(extension MATCHES "\\.lyx$")
96     # Font-type not relevant for lyx16/lyx2[0123] exports
97     set(result_file_base "${TempDir}/${file}")
98   else()
99     set(result_file_name ${file}.${extension})
100   endif()
101 endif()
102
103 function(get_md5sum msource mresult mreserr)
104   execute_process(
105     COMMAND ${CMAKE_COMMAND} -E md5sum ${${msource}}
106     OUTPUT_VARIABLE msource_md5sum_x
107     RESULT_VARIABLE mres_err)
108   if (NOT mres_err)
109     string(REGEX REPLACE " .*" "" msource_md5sum ${msource_md5sum_x})
110     set(${mresult} ${msource_md5sum} PARENT_SCOPE)
111     message(STATUS "MD5SUM of \"${${msource}}\" is ${msource_md5sum}")
112   else()
113     set(${mresult} "xx" PARENT_SCOPE)
114     message(STATUS "Error getting MD5SUM of \"${${msource}}\"")
115   endif()
116   set(${mreserr} ${mres_err} PARENT_SCOPE)
117 endfunction()
118
119 macro(Summary _err _msg)
120   #message(STATUS "Summary called with err=${_err}, msg=${_msg}")
121   if (_err)
122     MATH(EXPR NO_FAILES "${NO_FAILES}+1")
123     list(APPEND _TestResultMessage "Error: ${_msg}")
124   else()
125     list(APPEND _TestResultMessage "OK: ${_msg}")
126   endif()
127 endmacro()
128
129 macro(validate_output output outputfile errmsg errx)
130   if (NOT "${output}" STREQUAL "")
131     file(WRITE "${outputfile}" "${output}")
132     MATH(EXPR NO_FAILES "${NO_FAILES}+1")
133     Summary(${errx} "Validating \"${outputfile}\", ${errmsg}")
134   endif()
135 endmacro()
136
137 macro(check_xhtml_validate xhtml_file)
138   message(STATUS "Calling ${LYX_PYTHON_EXECUTABLE} \"${TOP_SRC_DIR}/development/autotests/simplehtml_validity.py\" \"${TempDir}/${xhtml_file}\"")
139   set(_outputfile "${TempDir}/${xhtml_file}.validate_out")
140   set(_errorfile "${TempDir}/${xhtml_file}.validate_err")
141   execute_process(
142     COMMAND ${LYX_PYTHON_EXECUTABLE} "${TOP_SRC_DIR}/development/autotests/simplehtml_validity.py" "${TempDir}/${xhtml_file}"
143     WORKING_DIRECTORY "${TempDir}"
144     OUTPUT_VARIABLE xmlout
145     ERROR_VARIABLE xmlerr
146     RESULT_VARIABLE _err)
147   if (NOT "${xmlout}" STREQUAL "")
148     if ("${xmlout}" MATCHES "Error: ")
149       validate_output("${xmlout}" "${_outputfile}" "found errors" -5)
150     endif()
151   endif()
152   validate_output("${xmlerr}" "${_errorfile}" "Not emty" -6)
153   if (NO_FAILES EQUAL 0 AND ${_err} EQUAL 254)
154     # Ignore this result, validate the outputs only instead
155     set(_err 0)
156   endif()
157   Summary(${_err} "Calling simplehtml_validity.py, result=${_err}")
158 endmacro()
159
160 macro(check_xhtml_xmllint xhtml_file)
161   set(xmllint_params --loaddtd --noout)
162   string(REPLACE ";" " " xmllint_params2 " ${xmllint_params}")
163   message(STATUS "Calling: " ${XMLLINT_EXECUTABLE} ${xmllint_params2} " \"${TempDir}/${xhtml_file}\"")
164   set(_outputfile "${TempDir}/${xhtml_file}.sax_out")
165   execute_process(
166     COMMAND ${XMLLINT_EXECUTABLE} ${xmllint_params} "${xhtml_file}"
167     WORKING_DIRECTORY "${TempDir}"
168     OUTPUT_VARIABLE xmlout
169     ERROR_VARIABLE xmlerr
170     RESULT_VARIABLE _err)
171   file(WRITE "${_outputfile}" ${xmlout})
172   Summary(${_err} "Checking \"${TempDir}/${xhtml_file}\" with ${XMLLINT_EXECUTABLE}")
173   if (NOT _err)
174     # check if parser output contains error messages
175     message(STATUS "Check the output: ${PERL_EXECUTABLE} ${TOP_SRC_DIR}/development/autotests/examineXmllintOutput.pl")
176     execute_process(
177       COMMAND ${PERL_EXECUTABLE} "${TOP_SRC_DIR}/development/autotests/examineXmllintOutput.pl" "${_outputfile}"
178       WORKING_DIRECTORY "${TempDir}"
179       OUTPUT_VARIABLE xmlout
180       RESULT_VARIABLE _err)
181     Summary(${_err} "Parse messages of ${XMLLINT_EXECUTABLE} for errors")
182   else()
183     message(STATUS "Errors from xmllint: ${xmlerr}")
184   endif()
185   if (NOT _err)
186     if (NOT "${xmlout}" STREQUAL "")
187       message(STATUS "${xmlout}")
188       set(_err -1)
189       Summary(${_err} "Non empty output \"${_outputfile}\" of \"${XMLLINT_EXECUTABLE}\"")
190     endif()
191   endif()
192 endmacro()
193
194 macro(check_xhtml_xmlparser xhtml_file)
195   message(STATUS "Calling ${PERL_EXECUTABLE} \"${TOP_SRC_DIR}/development/autotests/xmlParser.pl\" \"${xhtml_file}\"")
196   execute_process(
197     COMMAND ${PERL_EXECUTABLE} "${TOP_SRC_DIR}/development/autotests/xmlParser.pl" "${result_file_name}"
198     WORKING_DIRECTORY "${TempDir}"
199     OUTPUT_VARIABLE parserout
200     ERROR_VARIABLE parsererr
201     RESULT_VARIABLE _err
202   )
203   if (_err)
204     message(STATUS "${parsererr}")
205   endif()
206   Summary(_err "Checking \"${TempDir}/${xhtml_file}\" with xmlParser.pl")
207 endmacro()
208
209 macro(check_docbook_jing xhtml_file)
210   message(STATUS "Calling: ${JAVA_EXECUTABLE} -jar \"${TOP_SRC_DIR}/development/tools/jing.jar\" \"https://docbook.org/xml/5.2b09/rng/docbook.rng\" \"${TempDir}/${xhtml_file}\"")
211   set(_outputfile "${TempDir}/${xhtml_file}.jing_out")
212   execute_process(
213     COMMAND ${JAVA_EXECUTABLE} -jar "${TOP_SRC_DIR}/development/tools/jing.jar" "https://docbook.org/xml/5.2b09/rng/docbook.rng" "${xhtml_file}"
214     WORKING_DIRECTORY "${TempDir}"
215     OUTPUT_VARIABLE jingout
216     RESULT_VARIABLE _err)
217   file(WRITE "${_outputfile}" ${jingout})
218   message(STATUS "_err = ${_err}, jingout = ${jingout}")
219   Summary(_err "Checking for empty output \"${_outputfile}\" of ${JAVA_EXECUTABLE} -jar \"${TOP_SRC_DIR}/development/tools/jing.jar\"")
220 endmacro()
221
222 set(ENV{${LYX_USERDIR_VER}} "${LYX_TESTS_USERDIR}")
223 set(ENV{LANG} "en_US.UTF-8") # to get all error-messages in english
224 set(ENV{LANGUAGE} "US:en")
225 #set(ENV{LC_ALL} "C")
226 if (extension MATCHES "\\.lyx$")
227   include(${TOP_SRC_DIR}/development/autotests/CheckLoadErrors.cmake)
228   get_md5sum(LYX_SOURCE source_md5sum _err)
229   foreach(_lv RANGE 1 20)
230     set(used_tex_file "${result_file_base}.tex")
231     set(result_file_base "${result_file_base}.${LYX_FORMAT_NUM}")
232     set(result_file_name "${result_file_base}.lyx")
233     file(REMOVE "${result_file_name}" "${result_file_name}.emergency" )
234     message(STATUS "Executing ${lyx} -userdir \"${LYX_TESTS_USERDIR}\" -E ${format} ${result_file_name} \"${LYX_SOURCE}\"")
235     message(STATUS "This implicitly checks load of ${LYX_SOURCE}")
236     execute_process(
237       COMMAND ${lyx} -userdir "${LYX_TESTS_USERDIR}" -E ${format} ${result_file_name} "${LYX_SOURCE}"
238       RESULT_VARIABLE _err
239       ERROR_VARIABLE lyxerr)
240     Summary(_err "Converting \"${LYX_SOURCE}\" to format ${format}")
241     if(_err)
242       break()
243     else()
244       if(NOT EXISTS "${result_file_name}")
245         set(_err -1)
246         Summary(_err "Expected result file \"${result_file_name}\" does not exist")
247         break()
248       else()
249         message(STATUS "Expected result file \"${result_file_name}\" exists")
250         execute_process(
251           COMMAND ${PERL_EXECUTABLE} ${Structure_Script} "${result_file_name}"
252           RESULT_VARIABLE _err)
253         Summary(_err "Structure of the intermediate file \"${result_file_name}\"")
254         if(_err)
255           break()
256         endif()
257         checkLoadErrors(lyxerr "${TOP_SRC_DIR}/development/autotests" _err)
258         Summary(_err "Examination of error/warning messages of the conversion of \"${LYX_SOURCE}\" to format ${format}")
259         if(_err)
260           break()
261         endif()
262         message(STATUS "Create the corresponding .tex file \"${used_tex_file}\"")
263         execute_process(
264           COMMAND ${lyx} -userdir "${LYX_TESTS_USERDIR}" -E pdflatex ${used_tex_file} "${LYX_SOURCE}"
265           RESULT_VARIABLE _errx)
266       endif()
267     endif()
268     get_md5sum(result_file_name result_md5sum _err)
269     Summary(_err "Getting md5sum of \"${result_file_name}\"")
270     if(_err)
271       # Somehow the created file is not readable?
272       break()
273     endif()
274     # Check if result file identical to source file
275     if(result_md5sum STREQUAL ${source_md5sum})
276       if (format MATCHES "lyx(1[0-9]|2[01])x")
277         # Do not compile, missing \origin statement prevents inclusion of
278         # files with relative path
279         message(STATUS "Not exporting due to missing \\origin statement")
280         break()
281       elseif(format MATCHES "lyx22x" AND file MATCHES "Minted")
282         message(STATUS "Not exporting due to missing minted support")
283         break()
284       endif()
285       message(STATUS "Source(${LYX_SOURCE}) and dest(${result_file_name}) are equal")
286       message(STATUS "Now try to export the lyx2lyx created file")
287       message(STATUS "Executing ${lyx} -userdir \"${LYX_TESTS_USERDIR}\" -E default \"${result_file_name}.default\" \"${result_file_name}\"")
288       execute_process(
289         COMMAND ${lyx} -userdir "${LYX_TESTS_USERDIR}" -E default "${result_file_name}.default" "${result_file_name}"
290         RESULT_VARIABLE _err
291         ERROR_VARIABLE lyxerr)
292       Summary(_err "Test-compilation of \"${result_file_name}\" to format default")
293       break()
294     else()
295       list(APPEND _TestResultMessage "Warning: \"${LYX_SOURCE}\" and \"${result_file_name}\" differ")
296       message(STATUS "Source(${LYX_SOURCE}) and dest(${result_file_name}) are still different")
297       if (_lv GREATER 10)
298         set(_err 1)
299         message(STATUS "Possible endless loop encountered")
300         Summary(_err "Test-Loop exceeded the count of 10, Possible endless loop")
301         break()
302       endif()
303     endif()
304     set(source_md5sum ${result_md5sum})
305     set(LYX_SOURCE ${result_file_name})
306   endforeach()
307 else()
308   if ($ENV{LYX_DEBUG_LATEX})
309     set(LyXExtraParams -dbg latex)
310   else()
311     set(LyXExtraParams -dbg info)
312   endif()
313   if(IgnoreErrorMessage)
314     foreach (_em ${IgnoreErrorMessage})
315       list(APPEND LyXExtraParams --ignore-error-message ${_em})
316     endforeach()
317   endif()
318   string(REGEX REPLACE ";" " " _LyXExtraParams "${LyXExtraParams}")
319   message(STATUS "Executing in working dir ${TempDir}")
320   message(STATUS "Executing ${lyx} ${_LyXExtraParams} -userdir \"${LYX_TESTS_USERDIR}\" -E ${format} ${result_file_name} \"${LYX_SOURCE}\"")
321   file(REMOVE "${TempDir}/${result_file_name}")
322   execute_process(
323     COMMAND ${lyx} ${LyXExtraParams} -userdir "${LYX_TESTS_USERDIR}" -E ${format} ${result_file_name} "${LYX_SOURCE}"
324     WORKING_DIRECTORY "${TempDir}"
325     RESULT_VARIABLE _err)
326   Summary(_err "Exporting \"${LYX_SOURCE}\" to format ${format}")
327   if (NOT _err)
328     #check if result file created
329     if (NOT EXISTS "${TempDir}/${result_file_name}")
330       message(STATUS "Expected result file \"${TempDir}/${result_file_name}\" does not exist")
331       set(_err -1)
332       Summary(_err "Expected result file \"${TempDir}/${result_file_name}\" does not exists")
333     else()
334       message(STATUS "Expected result file \"${TempDir}/${result_file_name}\" exists")
335       if (extension MATCHES "^x(ht)?ml$")
336         if (NOT format MATCHES "xhtml")
337           # Check with perl xml-parser
338           # needs XML::Parser module
339           check_xhtml_xmlparser(${result_file_name})
340         endif()
341         if (JAVA_EXECUTABLE)
342           if (format MATCHES "docbook5")
343             check_docbook_jing(${result_file_name})
344           else()
345             check_xhtml_validate(${result_file_name})
346           endif()
347         endif()
348         if (XMLLINT_EXECUTABLE)
349           check_xhtml_xmllint(${result_file_name})
350         endif()
351       endif()
352     endif()
353   endif()
354 endif()
355
356 if(inverted)
357   string(COMPARE EQUAL  ${NO_FAILES} 0 _erg)
358 else()
359   string(COMPARE NOTEQUAL  ${NO_FAILES} 0 _erg)
360 endif()
361
362 if ($ENV{LYX_DEBUG_LATEX})
363   # Do not remove temporary files if one wants to examine them
364   # for example if setting the env-var LYX_DEBUG_LATEX
365   # This needs a remove all temp-dirs from time to time
366   # $ cd build-dir
367   # $ find autotests/out-home -name AbC_\* | xargs rm -rf
368 else()
369   execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory "${TempDir}")
370 endif()
371 if(_TestResultMessage)
372   message(STATUS "Msg Summary:")
373   foreach(_l ${_TestResultMessage})
374     message(STATUS "\t${_l}")
375   endforeach()
376 endif()
377 if(_erg)
378   message(STATUS "Exporting ${file}.lyx to ${format}")
379   message(FATAL_ERROR "Export failed")
380 endif()