-
Notifications
You must be signed in to change notification settings - Fork 0
/
analyzer.bat
607 lines (480 loc) · 16.8 KB
/
analyzer.bat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
@echo off
rem Copyright 2020 Antenna House, Inc.
rem
rem Licensed under the Apache License, Version 2.0 (the "License");
rem you may not use this file except in compliance with the License.
rem You may obtain a copy of the License at
rem
rem http://www.apache.org/licenses/LICENSE-2.0
rem
rem Unless required by applicable law or agreed to in writing, software
rem distributed under the License is distributed on an "AS IS" BASIS,
rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
rem implied.
rem
rem See the License for the specific language governing permissions and
rem limitations under the License.
rem Download msxsl.exe from:
rem https://www.microsoft.com/en-us/download/details.aspx?id=21714
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
rem Directory locations
set PWD=%cd%
rem Value of '%~dp0' includes trailing '\'.
set ANALYZER_DIR=%~dp0
set LIB_DIR=%ANALYZER_DIR%lib
set XSL_DIR=%ANALYZER_DIR%xsl
rem Command-line parameter defaults (possibly used in 'usage' message)
set ahfcmd=
set d=
set force=
set format=annotate
set js=yes
set lang=en
set opt=
set pdfver=PDF1.7
set show=yes
set transformer=
set xslt=
set xsltparam=
if "%1"=="" goto usage
goto start
:usage
echo.
echo Analyze a formatted file and generate a PDF report
:usage_command_line
echo.
echo usage: analyzer -d file [-format format] [-lang lang]
echo [-ahfcmd AHFCmd] [-opt "options"]
echo [-xslt xslt] [-xsltparam "xslt-params" ]
echo [-transformer transformer ]
echo [-pdfver pdfver] [-force yes] [-js no]
echo [-show no]
echo.
echo file : File to format and analyze
echo format : Analysis result format -- annotate or report
echo Default is '%format%'
echo lang : Language for error messages -- en or ja
echo Default is '%lang%'
echo AHFCmd : Path to AHFCmd.exe
echo options : Additional AHFCmd command-line parameters
echo xslt : XSLT stylesheet to use
echo xslt-params : XSLT processor parameters
echo transformer : XSLT 1.0 processor -- msxsl, xsltproc, or saxon6
echo Used with 'annotate' result format only
echo pdfver : PDF version of reports. Default is '%pdfver%'
echo -force yes : Force all stages to run
echo -js no : Do not include JavaScript in PDF report
echo -show no : Do not open the PDF report
echo.
goto done
rem ----------------------------------------------------------------------
:start
rem Command-line argument handling based on:
rem https://stackoverflow.com/a/32078177
rem https://stackoverflow.com/a/54234876
rem List of names of recognized parameters that do not require a value.
rem There must be at least one space (' ') at the beginning and end of
rem the list and between parameter names.
set __short_param= f
rem List of names of recognized parameters that require a value.
rem There must be at least one space (' ') at the beginning and end of
rem the list and between parameter names.
set __long_param= ahfcmd d force format js lang opt pdfver show transformer xslt xsltparam
rem List of all recognized parameter names.
rem There must be at least one space (' ') at the beginning and end of
rem the list and between parameter names.
set __all_param= %__short_param% %__long_param%
set __expect_param_name=yes
:initial
if "%~1"=="" goto parameters_done
if "%~1"=="--" (
shift
goto parameters_done
)
rem echo %1
set aux=%~1
rem if "%__expect_param_name%"=="yes" (
if not "%__expect_param_name%"=="yes" goto parameters_value
if "%aux:~0,1%"=="-" (
rem Parameter name.
set __param=%aux:~1,250%
rem Parameter name with a space charater before and after the name.
rem You can't see the final ' ', but it has to be there.
set __param_tmp= %aux:~1,250%
rem echo __param: "!__param!"
rem echo __param: "%__param%"
rem echo __param_tmp: "!__param_tmp!"
rem echo __param_tmp: "%__param_tmp%"
rem The two strings match only if __param is not in the list.
call set __param_removed=%%__all_param:!__param_tmp!=%%
rem Remove transient variables
set __param_tmp=
rem echo __param_removed: "!__param_removed!"
rem echo __param_removed: "%__param_removed%"
rem set __param_removed=
set __expect_param_name=
shift
goto initial
) else (
echo.
echo Expected a parameter starting with "-": %aux%
goto usage_command_line
)
:parameters_value
rem ) else (
rem echo __param_removed: "!__param_removed!"
rem echo __param_removed: "%__param_removed%"
rem List of all parameter names, possibly with __param removed.
if "x%__param_removed%"=="x%__all_param%" (
echo.
echo Unrecognized parameter: -!__param!
goto usage_command_line
)
set "%__param%=%~1"
set __param=
set __expect_param_name=yes
rem )
shift
goto initial
:parameters_done
set FILE=%d%
if not exist "%d%" (
echo.
echo Source file does not exist: '%d%'
goto error
)
set BASENAME=
call :sub_basename BASENAME "%FILE%"
set EXT=
call :sub_ext EXT "%FILE%"
rem echo '%FILE%' '%BASENAME%'
if not "%BASENAME%"=="" goto have_basename
echo Could not determine basename for %FILE%
goto error
:have_basename
rem echo opt: %opt%
set REPORTER_XSLT=%XSL_DIR%\annotate.xsl
if "%format%"=="report" (
rem Default 'report' format is 'compact' format.
set REPORTER_XSLT=%XSL_DIR%\compact-report.xsl
) else if "%format%"=="compact" (
rem 'compact' was used internally but never in a public release.
set REPORTER_XSLT=%XSL_DIR%\compact-report.xsl
)
if not "%xslt%"=="" (
if EXIST "%xslt%" (
set REPORTER_XSLT=%xslt%
) else (
echo XSLT file does not exist: %xslt%
goto error
)
)
if not "%ahfcmd%"=="" (
if EXIST "%ahfcmd%" (
set AHFCMD="%ahfcmd%"
goto ahfcmd_done
) else (
echo AHFCmd file does not exist: %ahfcmd%
goto error
)
) else if not "%AHF70_64_HOME%"=="" (
if EXIST "%AHF70_64_HOME%\AHFCmd.exe" (
set AHFCMD="%AHF70_64_HOME%\AHFCmd.exe"
goto ahfcmd_done
) else (
echo AHFCmd file does not exist in '%AHF70_64_HOME%'
goto error
)
)
rem The '(86)' in %AHFXX_HOME% value causes problem when %AHFXX_HOME%
rem is used in an 'if' statement that includes '(' and ')'. It is
rem necessary to do the check a different way.
if "%AHF70_HOME%"=="" (
echo No AHFCmd.exe
goto error
)
if EXIST "%AHF70_HOME%\AHFCmd.exe" goto ahfcmd_ahfxx_home
echo AHFCmd file does not exist in '%AHF70_HOME%'
goto error
:ahfcmd_ahfxx_home
set AHFCMD="%AHF70_HOME%\AHFCmd.exe"
:ahfcmd_done
rem echo %AHFCMD%
set JAVASCRIPT=true
if "%js%"=="no" (
set JAVASCRIPT=false
)
rem Check format value before taking time to generate Area Tree XML.
if not "%format%"=="annotate" (
if not "%format%"=="compact" (
if not "%format%"=="report" (
echo Unrecognized result format: %format%
goto error
)
)
)
rem All of the reasons to generate "%BASENAME%.AT.XML" ...
if "%force%"=="yes" goto at_do
if not exist "%BASENAME%.AT.XML" goto at_do
rem Sort files by date. Newer file is last to set NEWER.
for /F "usebackq delims=" %%q in (`dir /B /OD "%FILE%" "%BASENAME%.AT.XML"`) do (
set NEWER=%%q
)
rem echo %NEWER%
if not "%NEWER%"=="%BASENAME%.AT.XML" goto at_do
rem 'dir /B /OD' does not work across directories.
rem Use a function that returns timestamp in seconds since 1970.
if exist "%BASENAME%.AT.XML" call :sub_file_mod_time "%BASENAME%.AT.XML" AT_XML_DATE
call :sub_file_mod_time %AHFCMD% AHFCMD_DATE
if "%AHFCMD_DATE%" GTR "%AT_XML_DATE%" goto at_do
rem No need to regenerate %BASENAME%.AT.XML
echo '%BASENAME%.AT.XML' is up to date
goto at_done
:at_do
echo Analyzing '%FILE%' and generating '%BASENAME%.AT.XML'
if exist "%BASENAME%.AT.XML" del "%BASENAME%.AT.XML"
if exist "%BASENAME%.AT.XML" (
echo Unable to replace '%BASENAME%.AT.XML'.
goto error
)
%AHFCMD% -analyze -p @AreaTree -xmlerr -d "%FILE%" %opt% -o "%BASENAME%.AT.XML" 2> "%BASENAME%.log.xml"
if %ERRORLEVEL% NEQ 0 (
echo An error occurred when analyzing '%FILE%'. Check log file '%BASENAME%.log.xml'.
goto error
)
if not exist "%BASENAME%.AT.XML" (
echo Area Tree XML file for '%FILE%' was not created. Check log file '%BASENAME%.log.xml'.
goto error
)
:at_done
if "%format%"=="annotate" (
goto annotate
) else if "%format%"=="compact" (
goto report
) else if "%format%"=="report" (
goto report
) else (
echo Unrecognized result format: %format%
goto error
)
rem ----------------------------------------------------------------------
:annotate
if not "%transformer%"=="" (
rem This sccipt does NOT check that specified transformer is available.
if "%transformer%"=="msxsl" (
call :sub_msxsl
goto annotate_done_xslt
)
if "%transformer%"=="xsltproc" (
call :sub_xsltproc
goto annotate_done_xslt
)
if "%transformer%"=="saxon6" (
call :sub_saxon6
goto annotate_done_xslt
)
echo Unrecognized XSLT transformer: %transformer%
goto error
)
echo Generating '%BASENAME%.annotated.AT.xml' from '%BASENAME%.AT.xml'
call :sub_on_path msxsl.exe
if not "%__SUB_ON_PATH_MATCH%"=="" (
call :sub_msxsl
goto annotate_done_xslt
)
call :sub_on_path xsltproc.exe
if not "%__SUB_ON_PATH_MATCH%"=="" (
call :sub_xsltproc
goto annotate_done_xslt
)
call :sub_on_path java.exe
if not "%__SUB_ON_PATH_MATCH%"=="" (
call :sub_saxon6
goto annotate_done_xslt
)
rem No XSLT processor is available.
echo Either msxsl.exe, xsltproc.exe, or java.exe must be in a directory on the PATH.
goto error
:annotate_done_xslt
if %ERRORLEVEL% NEQ 0 (
echo.
echo An error occurred when creating the annotated Area Tree XML file.
goto error
)
call :sub_2pdf "%PWD%\%BASENAME%.annotated.AT.xml" "%PWD%\%BASENAME%.annotated.pdf" "%PWD%\%BASENAME%.annotated.pdf.log"
if %ERRORLEVEL% NEQ 0 goto error
rem View the PDF
if exist "%BASENAME%.annotated.pdf" (
echo Analysis completed.
echo Annotated PDF: '%BASENAME%.annotated.pdf'
if "%show%" == "yes" (
"%BASENAME%.annotated.pdf"
)
) else (
echo An error occurred when generating '%BASENAME%.annotated.pdf'. Check log file '%BASENAME%.annotated.pdf.log'.
goto error
)
rem ----------------------------------------------------------------------
:done
exit /B 0
rem ----------------------------------------------------------------------
:error
exit /B 1
rem ----------------------------------------------------------------------
:report
if not "%transformer%"=="" (
echo '-transformer' is ignored unless '-format annotate'
)
rem Whether or not to regenerate %BASENAME%.pdf...
if "%force%"=="yes" goto report_pdf_do
for /F "usebackq delims=" %%q in (`dir /B /OD "%BASENAME%%EXT%" "%BASENAME%.pdf"`) do (
set NEWER=%%q
)
rem echo %NEWER%
if not "%NEWER%"=="%BASENAME%.pdf" goto report_pdf_do
rem 'dir /B /OD' does not work across directories.
rem Use a function that returns timestamp in seconds since 1970.
if exist "%BASENAME%.pdf" call :sub_file_mod_time "%BASENAME%.pdf" PDF_DATE
call :sub_file_mod_time %AHFCMD% AHFCMD_DATE
if "%AHFCMD_DATE%" GTR "%PDF_DATE%" goto report_pdf_do
echo '%BASENAME%.pdf' is up to date
goto report_pdf_done
:report_pdf_do
call :sub_2pdf "%PWD%\%BASENAME%%EXT%" "%PWD%\%BASENAME%.pdf" "%PWD%\%BASENAME%.pdf.log" "%opt%"
if %ERRORLEVEL% NEQ 0 (
echo An error occurred when generating '%BASENAME%.pdf'. Check log file '%BASENAME%.pdf.log'.
goto error
)
:report_pdf_done
rem Whether or not to regenerate %BASENAME%.report.fo...
for /F "delims=" %%q in ('dir /B /OD "%BASENAME%%EXT%" "%BASENAME%.log.xml" "%BASENAME%.report.fo"') do (
set NEWER=%%q
)
rem echo %NEWER%
if not "%NEWER%"=="%BASENAME%.report.fo" goto report_fo_do
echo '%BASENAME%.report.fo' is up to date
goto report_fo_done
:report_fo_do
call :sub_on_path java.exe
if "%__SUB_ON_PATH_MATCH%"=="" (
rem Java is not available.
echo java.exe must be in a directory on the PATH.
goto error
)
call :sub_mod_date FILE_DATE "%BASENAME%%EXT%"
echo Generating '%BASENAME%.report.fo' from '%BASENAME%.AT.xml'
java -jar "%LIB_DIR%\saxon9he.jar" "-s:%PWD:\=/%/%BASENAME%.AT.xml" "-xsl:%REPORTER_XSLT:\=/%" "-o:%BASENAME%.report.fo" "logfile=file:///%PWD%/%BASENAME%.log.xml" javascript=%JAVASCRIPT% lang=%lang% "file=%PWD:\=/%/%BASENAME%%EXT%" file-date="%FILE_DATE%" "pdf-file=%PWD:\=/%/%BASENAME%.pdf" %xsltparam%
if %ERRORLEVEL% NEQ 0 (
echo.
echo An error occurred when creating the report XSL-FO file.
goto error
)
:report_fo_done
rem Whether or not to regenerate %BASENAME%.report.pdf...
for /F "usebackq delims=" %%q in (`dir /B /OD "%BASENAME%.report.fo" "%BASENAME%.report.pdf"`) do (
set NEWER=%%q
)
rem echo %NEWER%
if not "%NEWER%"=="%BASENAME%.report.pdf" goto report_pdf_do
echo '%BASENAME%.report.pdf' is up to date
goto report_pdf_done
:report_pdf_do
call :sub_2pdf "%PWD%\%BASENAME%.report.fo" "%PWD%\%BASENAME%.report.pdf" "%PWD%\%BASENAME%.report.pdf.log" "-pdfver %pdfver%"
if %ERRORLEVEL% NEQ 0 goto error
:report_pdf_done
rem View the PDF
if exist "%BASENAME%.report.pdf" (
echo Analysis completed.
echo Report PDF: '%BASENAME%.report.pdf'
if "%show%" == "yes" (
"%BASENAME%.report.pdf"
)
) else (
echo An error occurred when generating '%BASENAME%.report.pdf'. Check log file '%BASENAME%.report.pdf.log'.
goto error
)
goto done
rem ----------------------------------------------------------------------
rem Subroutines
:sub_on_path
rem echo %1
set __SUB_ON_PATH_MATCH=%~$PATH:1
exit /B 1
:sub_basename
rem echo %1 %2
set "%~1=%~n2"
exit /B 1
:sub_basename_ext
rem echo %1 %2
set "%~1=%~nx2"
exit /B 1
:sub_ext
rem echo %1 %2
set "%~1=%~x2"
exit /B 1
:sub_mod_date
rem echo %1 %2
set "%~1=%~t2"
exit /B 1
:sub_msxsl
msxsl "%BASENAME%.AT.xml" "%REPORTER_XSLT%" -o "%BASENAME%.annotated.AT.xml" logfile="%PWD%/%BASENAME%.log.xml" lang=%lang% %xsltparam%
exit /B %ERRORLEVEL%
:sub_xsltproc
xsltproc --stringparam logfile "%PWD%/%BASENAME%.log.xml" --stringparam lang %lang% %xsltparam% -o "%BASENAME%.annotated.AT.xml" "%REPORTER_XSLT%" "%PWD%/%BASENAME%.AT.xml"
exit /B %ERRORLEVEL%
:sub_saxon6
java -jar "%LIB_DIR%\saxon.jar" -o "%BASENAME%.annotated.AT.xml" "%PWD:\=/%/%BASENAME%.AT.xml" "%REPORTER_XSLT:\=/%" "logfile=file:///%PWD%/%BASENAME%.log.xml" lang=%lang% %xsltparam%
exit /B %ERRORLEVEL%
:sub_saxon9
java -jar "%LIB_DIR%\saxon9he.jar" "-s:%PWD:\=/%/%BASENAME%.AT.xml" "-xsl:%REPORTER_XSLT:\=/%" "-o:%BASENAME%.report.fo" "logfile=file:///%PWD%/%BASENAME%.log.xml" lang=%lang% %xsltparam%
exit /B %ERRORLEVEL%
:sub_2pdf
set SOURCE=%~1
set TARGET=%~2
set LOG=%~3
set PDF_OPT=%~4
rem If the PDF is open in Acrobat, it can't be either deleted or replaced.
if exist "%TARGET%" del "%TARGET%"
if exist "%TARGET%" (
echo Unable to replace '%TARGET%'.
exit /B 1
)
set SOURCE_BASENAME=
call :sub_basename_ext SOURCE_BASENAME "%SOURCE%"
set TARGET_BASENAME=
call :sub_basename_ext TARGET_BASENAME "%TARGET%"
echo Formatting '%SOURCE_BASENAME%' as '%TARGET_BASENAME%'
rem Use highest-possible PDF version in case embedding high-version PDF
%AHFCMD% -x 4 %PDF_OPT% -d "%SOURCE%" -o "%TARGET%" 2> "%LOG%"
if %ERRORLEVEL% NEQ 0 (
echo An error occurred when generating '%TARGET%'. Check log file '%LOG%'.
exit /B 1
)
exit /B 0
rem From https://www.dostips.com/forum/viewtopic.php?p=38229#p38229
:sub_file_mod_time File [TimeVar]
::
:: Computes the Unix time (epoch time) for the last modified timestamp for File.
:: The result is an empty string if the file does not exist. Stores the result
:: in TimeVar, or prints the result if TimeVar is not specified.
::
:: Unix time = number of seconds since midnight, January 1, 1970 GMT
::
setlocal disableDelayedExpansion
:: Get full path of file (short form if possible)
for %%F in ("%~1") do set "file=%%~sF"
:: Get last modified time in YYYYMMDDHHMMSS format
set "time="
for /f "skip=1 delims=,. tokens=2" %%A in (
'wmic datafile where name^="%file:\=\\%" get lastModified /format:csv 2^>nul'
) do set "ts=%%A"
set "ts=%ts%"
:: Convert time to Unix time (aka epoch time)
if defined ts (
set /a "yy=10000%ts:~0,4% %% 10000, mm=100%ts:~4,2% %% 100, dd=100%ts:~6,2% %% 100"
set /a "dd=dd-2472663+1461*(yy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yy+4900+(mm-14)/12)/100)/4"
set /a "ss=(((1%ts:~8,2%*60)+1%ts:~10,2%)*60)+1%ts:~12,2%-366100-%ts:~21,1%((1%ts:~22,3%*60)-60000)"
set /a "ts=ss+dd*86400"
)
:: Return the result
endlocal & if "%~2" neq "" (set "%~2=%ts%") else echo(%ts%