detect missing commas in bib files
[latexmk-quieter.git] / latexmk-quieter
blob5df4c56ae8cdf2a9d7b174744a5499154dd1a842
1 #!/usr/bin/env lua
3 local spawn = require('spawn.posix')
4 local unix = require('unix')
5 local lpeg = require('lpeg')
7 local V, R, P, S, C, Ct, Cg, Cmt, Cb =
8         lpeg.V, lpeg.R, lpeg.P, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cg, lpeg.Cmt,
9         lpeg.Cb
11 file_line_error = P{
12         "full";
13         cnc = (P":" * (R"09")^1 * P": "),
14         fn = (P(1) - (P" " + V"cnc"))^1,
15         full = V"fn" * V"cnc",
17 fatal_error_occurred = (P(1) - (P"  ==> Fatal error"))^1 * P"  ==> Fatal error"
19 exclam_start = P"! " * (1 - P" ")
20 exclam_finish = P"!  "
22 runaway = P"Runaway argument?" * (-1)
24 biber_error = P{
25         "full";
26         idf = P("I didn't find a database entry") + 1 * V"idf",
27         full = P("WARN") * V"idf",
30 bibtex_subsystem_error = P{
31         "full";
32         full = P("ERROR - BibTeX subsystem") * 1^0,
35 function should_print(s, l)
36         --
37         -- ! Foo bar exploded
38         -- ... blah blah blah ...
39         -- !  ==> Fatal error occurred, no output...
40         if s.wait_for_exclam_finish then
41                 if exclam_finish:match(l) then
42                         s.wait_for_exclam_finish = false
43                         return nil
44                 end
46                 return l
47         end
49         if exclam_start:match(l) then
50                 s.wait_for_exclam_finish = true
51                 return l
52         end
54         --
55         -- file:12: Undefined control sequence
56         -- ... blah blah blah ...
57         -- file:12:  ==> Fatal error occurred, no output...
58         --
59         if s.wait_for_fle_fatal_error_message then
60                 if fatal_error_occurred:match(l) then
61                         s.wait_for_fle_fatal_error_message = false
62                         return nil
63                 end
65                 return l
66         end
68         if file_line_error:match(l) then
69                 s.wait_for_fle_fatal_error_message = true
70                 return l
71         end
73         --
74         -- Specific matches.
75         --
76         if s.show_next > 0 then
77                 s.show_next = s.show_next - 1
78                 return l
79         end
81         if runaway:match(l) then
82                 s.show_next = 4
83                 return l
84         end
86         if biber_error:match(l) then
87                 return l
88         end
90         if bibtex_subsystem_error:match(l) then
91                 return l
92         end
94         return nil
95 end
97 local file_actions = assert(spawn.new_file_actions())
98 local attr = assert(spawn.new_attr())
99 local child_stdin, child_stdout, read, write
100 child_stdin, write = assert(unix.fpipe("e"))
101 read, child_stdout = assert(unix.fpipe("e"))
102 assert(file_actions:adddup2(unix.fileno(child_stdin), 0))
103 assert(file_actions:adddup2(unix.fileno(child_stdout), 1))
104 assert(file_actions:adddup2(1, 2))
106 local pid = assert(spawn.spawnp(arg[1], file_actions, attr,
107         arg, nil))
108 child_stdin:close()
109 child_stdout:close()
110 state = {
111         show_next = 0,
112         wait_for_exclam_finish = false,
113         wait_for_fle_fatal_error_message = false,
115 while true do
116         line = read:read('*line')
117         if not line then break end
118         line = should_print(state, line)
119         if line then
120                 io.stderr:write(line .. "\n")
121         end
124 local why, status
125 _, why, status = unix.waitpid(pid)
127 os.exit(status)