]> git.lyx.org Git - lyx.git/blob - lib/examples/listerrors.lyx
3 new Spanish translations of example files by Ignacio
[lyx.git] / lib / examples / listerrors.lyx
1 #LyX 1.6.0 created this file. For more info see http://www.lyx.org/
2 \lyxformat 345
3 \begin_document
4 \begin_header
5 \use_default_options false
6 \textclass literate-article
7 \begin_preamble
8 %
9 % ps2pdf stuff
10 %
11 \usepackage[ps2pdf,pdftitle={LyX listerrors re-implemented},urlcolor=blue,linktocpage,letterpaper,colorlinks=true]{hyperref}
12 \@savsf=1% This is to get around a hyperref+noweb interaction problem
13 \hyphenpenalty 10000
14
15 %
16 % This (from the noweb FAQ) relaxes the constraint that chunks are never broken across pages.
17 %
18 \def\nwendcode{\endtrivlist \endgroup \vfil\penalty10\vfilneg}
19 \let\nwdocspar=\smallbreak
20 \end_preamble
21 \language english
22 \inputencoding auto
23 \font_roman times
24 \font_sans helvet
25 \font_typewriter courier
26 \font_default_family default
27 \font_sc false
28 \font_osf false
29 \font_sf_scale 100
30 \font_tt_scale 100
31 \graphics default
32 \paperfontsize default
33 \spacing single
34 \use_hyperref false
35 \papersize default
36 \use_geometry false
37 \use_amsmath 0
38 \use_esint 0
39 \cite_engine basic
40 \use_bibtopic false
41 \paperorientation portrait
42 \secnumdepth 3
43 \tocdepth 3
44 \paragraph_separation indent
45 \defskip medskip
46 \quotes_language english
47 \papercolumns 1
48 \papersides 1
49 \paperpagestyle default
50 \tracking_changes false
51 \output_changes false
52 \author ""
53 \end_header
54
55 \begin_body
56
57 \begin_layout Title
58 LyX listerrors:
59 \begin_inset Newline newline
60 \end_inset
61
62 rewritten in Python
63 \end_layout
64
65 \begin_layout Author
66 Kayvan A.
67  Sylvan
68 \begin_inset Newline newline
69 \end_inset
70
71
72 \begin_inset Flex URL
73 status collapsed
74
75 \begin_layout Plain Layout
76
77 mailto:kayvan@sylvan.com
78 \end_layout
79
80 \end_inset
81
82
83 \end_layout
84
85 \begin_layout Date
86 3/15/2002
87 \end_layout
88
89 \begin_layout Abstract
90 The listerrors program used to be compiled as a C program and installed
91  as 
92 \emph on
93 BINDIR/listerrors
94 \emph default
95  along with LyX in order to perform some simple re-formatting of noweb and
96  GCC error messages.
97  This document describes and implements the Python version of the same program.
98 \end_layout
99
100 \begin_layout Standard
101 \begin_inset CommandInset toc
102 LatexCommand tableofcontents
103
104 \end_inset
105
106
107 \end_layout
108
109 \begin_layout Section
110 Introduction
111 \end_layout
112
113 \begin_layout Standard
114 The motivation for this program was Bugzilla bug 190
115 \begin_inset Foot
116 status collapsed
117
118 \begin_layout Plain Layout
119 Visit 
120 \begin_inset Flex URL
121 status collapsed
122
123 \begin_layout Plain Layout
124
125 http://bugzilla.lyx.org/show_bug.cgi?id=190
126 \end_layout
127
128 \end_inset
129
130  for the details.
131 \end_layout
132
133 \end_inset
134
135  dealing with the 
136 \begin_inset Quotes eld
137 \end_inset
138
139 listerrors
140 \begin_inset Quotes erd
141 \end_inset
142
143  executable.
144 \end_layout
145
146 \begin_layout Standard
147 What is 
148 \begin_inset Quotes eld
149 \end_inset
150
151 listerrors
152 \begin_inset Quotes erd
153 \end_inset
154
155 ? Usually, LyX has great support for parsing of error messages.
156  For each error in the log file, LyX pops up an error box at that location
157  in the LyX window.
158  The error scanning routines expect these errors to be in a certain format
159  (similar to LaTeX errors).
160  When dealing with Literate Programs, you have 
161 \begin_inset Quotes eld
162 \end_inset
163
164 noweb
165 \begin_inset Foot
166 status collapsed
167
168 \begin_layout Plain Layout
169 See 
170 \begin_inset Flex URL
171 status collapsed
172
173 \begin_layout Plain Layout
174
175 http://www.eecs.harvard.edu/~nr/noweb
176 \end_layout
177
178 \end_inset
179
180  for more information about noweb.
181 \end_layout
182
183 \end_inset
184
185
186 \begin_inset Quotes erd
187 \end_inset
188
189  as well as gcc error messages (and potentially others).
190  The listerrors program attempts to standardize these error messages to
191  a format that LyX can parse and react to.
192 \end_layout
193
194 \begin_layout Standard
195 In a nutshell, the problems with the old implementation of listerrors that
196  bug 190 refers to were::
197 \end_layout
198
199 \begin_layout Enumerate
200 It was a C program and it was installed in the user path in the same directory
201  as LyX.
202  Having such a generically named binary in, for example, 
203 \emph on
204 /usr/bin
205 \emph default
206 , was potentially confusing.
207 \end_layout
208
209 \begin_layout Enumerate
210 It required that noweb be installed on the compiling machine (the source
211  was extracted by noweb from 
212 \emph on
213 SRCDIR/examples/Literate.lyx
214 \emph default
215 , compiled and installed by 
216 \begin_inset Quotes eld
217 \end_inset
218
219 make install
220 \begin_inset Quotes erd
221 \end_inset
222
223 ).
224 \end_layout
225
226 \begin_layout Standard
227 The new version deals with these problems in the following fashion:
228 \end_layout
229
230 \begin_layout Enumerate
231 Both the example file (this document) and the program are to be added to
232  the LyX CVS repository.
233 \end_layout
234
235 \begin_layout Enumerate
236 The program itself will be installed in 
237 \emph on
238 SHAREDIR/lyx/scripts
239 \emph default
240 , along with other LyX-specific helper scripts.
241 \end_layout
242
243 \begin_layout Standard
244 In the design and implementation of this new 
245 \begin_inset Quotes eld
246 \end_inset
247
248 listerrors
249 \begin_inset Quotes erd
250 \end_inset
251
252 , the Python
253 \begin_inset Foot
254 status collapsed
255
256 \begin_layout Plain Layout
257 See the Python home page (
258 \begin_inset Flex URL
259 status collapsed
260
261 \begin_layout Plain Layout
262
263 http://www.python.org
264 \end_layout
265
266 \end_inset
267
268 ) for more information.
269 \end_layout
270
271 \end_inset
272
273  language was chosen since it is fully multi-platform and provides a very
274  uniform and easy to read syntax.
275  This re-write also simplifies the code for 
276 \begin_inset Quotes eld
277 \end_inset
278
279 listerrors
280 \begin_inset Quotes erd
281 \end_inset
282
283  greatly.
284  Python is installed by default on all modern Linux systems and is freely
285  available for all other platforms.
286 \end_layout
287
288 \begin_layout Scrap
289 <<listerrors>>=
290 \begin_inset Newline newline
291 \end_inset
292
293 #!/usr/bin/python -tt
294 \begin_inset Newline newline
295 \end_inset
296
297 """reformat noweb and compiler errors for LyX.
298 \begin_inset Newline newline
299 \end_inset
300
301
302 \begin_inset Newline newline
303 \end_inset
304
305 Expects to read from stdin and output to stdout.
306 \begin_inset Newline newline
307 \end_inset
308
309 """
310 \begin_inset Newline newline
311 \end_inset
312
313
314 \begin_inset Newline newline
315 \end_inset
316
317 __author__ = "Kayvan A.
318  Sylvan <kayvan@sylvan.com>"
319 \begin_inset Newline newline
320 \end_inset
321
322 __date__ = "$Date: 2005/07/18 09:42:26 $"
323 \begin_inset Newline newline
324 \end_inset
325
326 __version__ = "$Revision: 1.5 $"
327 \begin_inset Newline newline
328 \end_inset
329
330 __credits__ = """Edmar Wienskoski Jr.
331  <edmar-w-jr@technologist.com>
332 \begin_inset Newline newline
333 \end_inset
334
335     original Literate support for LyX.
336 \begin_inset Newline newline
337 \end_inset
338
339 Bernard Michael Hurley <berhardh@westherts.ac.uk>
340 \begin_inset Newline newline
341 \end_inset
342
343     modifications to original listerrors."""
344 \begin_inset Newline newline
345 \end_inset
346
347 __copyright__ = "Copyright 2002 - Kayvan Sylvan."
348 \begin_inset Newline newline
349 \end_inset
350
351
352 \begin_inset Newline newline
353 \end_inset
354
355 import sys, string
356 \begin_inset Newline newline
357 \end_inset
358
359
360 \begin_inset Newline newline
361 \end_inset
362
363 <<Function Bodies>>
364 \begin_inset Newline newline
365 \end_inset
366
367
368 \begin_inset Newline newline
369 \end_inset
370
371 if __name__ == "__main__":
372 \begin_inset Newline newline
373 \end_inset
374
375   main()
376 \begin_inset Newline newline
377 \end_inset
378
379 @
380 \end_layout
381
382 \begin_layout Section
383 LaTeX style error message
384 \end_layout
385
386 \begin_layout Standard
387 The following function mimics the TeX error message format.
388 \end_layout
389
390 \begin_layout Scrap
391 <<Function Bodies>>=
392 \begin_inset Newline newline
393 \end_inset
394
395 def write_error(msg, tool = "noweb", line_number = 1):
396 \begin_inset Newline newline
397 \end_inset
398
399   """Write out the given message in TeX error style.
400 \begin_inset Newline newline
401 \end_inset
402
403
404 \begin_inset Newline newline
405 \end_inset
406
407   called like: write_error(msg, tool, line_number)."""
408 \begin_inset Newline newline
409 \end_inset
410
411   print "! Build Error: ==> %s ==>
412 \backslash
413 n" % (tool),
414 \begin_inset Newline newline
415 \end_inset
416
417   print " ...
418 \backslash
419 n
420 \backslash
421 nl.%d ...
422 \backslash
423 n" % (line_number),
424 \begin_inset Newline newline
425 \end_inset
426
427   if type(msg) == type("str"): # simple string
428 \begin_inset Newline newline
429 \end_inset
430
431     print msg
432 \begin_inset Newline newline
433 \end_inset
434
435   else: # some kind of list (sequence or tuple)
436 \begin_inset Newline newline
437 \end_inset
438
439     for m in msg:
440 \begin_inset Newline newline
441 \end_inset
442
443         if m != "": print m,
444 \begin_inset Newline newline
445 \end_inset
446
447     print
448 \begin_inset Newline newline
449 \end_inset
450
451
452 \begin_inset Newline newline
453 \end_inset
454
455 @ %def write_error
456 \end_layout
457
458 \begin_layout Section
459 Filtering errors
460 \end_layout
461
462 \begin_layout Standard
463 The only complication in our filtering code is that some parsers might need
464  to push back lines that are read in to be read again later.
465  We solve this problem by implementing a 
466 \begin_inset Quotes eld
467 \end_inset
468
469 getline
470 \begin_inset Quotes erd
471 \end_inset
472
473  and 
474 \begin_inset Quotes eld
475 \end_inset
476
477 pushline
478 \begin_inset Quotes erd
479 \end_inset
480
481  set of functions:
482 \end_layout
483
484 \begin_layout Scrap
485 <<Function Bodies>>=
486 \begin_inset Newline newline
487 \end_inset
488
489 __lines = [] # lines pushed back
490 \begin_inset Newline newline
491 \end_inset
492
493
494 \begin_inset Newline newline
495 \end_inset
496
497 def getline(file = sys.stdin):
498 \begin_inset Newline newline
499 \end_inset
500
501   """read a line from internal stack or from file.
502 \begin_inset Newline newline
503 \end_inset
504
505
506 \begin_inset Newline newline
507 \end_inset
508
509   optional file argument defaults to sys.stdin."""
510 \begin_inset Newline newline
511 \end_inset
512
513   global __lines
514 \begin_inset Newline newline
515 \end_inset
516
517   lines = __lines
518 \begin_inset Newline newline
519 \end_inset
520
521   if lines:
522 \begin_inset Newline newline
523 \end_inset
524
525     line = lines.pop()
526 \begin_inset Newline newline
527 \end_inset
528
529   else:
530 \begin_inset Newline newline
531 \end_inset
532
533     line = file.readline()
534 \begin_inset Newline newline
535 \end_inset
536
537   return line
538 \begin_inset Newline newline
539 \end_inset
540
541
542 \begin_inset Newline newline
543 \end_inset
544
545 @ %def getline
546 \end_layout
547
548 \begin_layout Standard
549 And now for the corresponding pushline function:
550 \end_layout
551
552 \begin_layout Scrap
553 <<Function Bodies>>=
554 \begin_inset Newline newline
555 \end_inset
556
557 def pushline(line):
558 \begin_inset Newline newline
559 \end_inset
560
561   "push a line onto the pushback stack."
562 \begin_inset Newline newline
563 \end_inset
564
565   global __lines
566 \begin_inset Newline newline
567 \end_inset
568
569   lines = __lines
570 \begin_inset Newline newline
571 \end_inset
572
573   lines.append(line)
574 \begin_inset Newline newline
575 \end_inset
576
577
578 \begin_inset Newline newline
579 \end_inset
580
581 @ %def pushline
582 \end_layout
583
584 \begin_layout Standard
585 The main() entry point function is extremely simple.
586  Note that this version of 
587 \begin_inset Quotes eld
588 \end_inset
589
590 listerrors
591 \begin_inset Quotes erd
592 \end_inset
593
594  takes no options and simply filters, attempting simply to match against
595  the known error message patterns.
596  The listerrors C program handled a single-character command-line argument
597  that the current code no longer needs.
598  
599 \end_layout
600
601 \begin_layout Scrap
602 <<Function Bodies>>=
603 \begin_inset Newline newline
604 \end_inset
605
606 def main():
607 \begin_inset Newline newline
608 \end_inset
609
610   """Entry point for listerrors.
611  Takes no options.
612 \begin_inset Newline newline
613 \end_inset
614
615
616 \begin_inset Newline newline
617 \end_inset
618
619   Reads stdin and writes to stdout.
620  Filter errors"""
621 \begin_inset Newline newline
622 \end_inset
623
624
625 \begin_inset Newline newline
626 \end_inset
627
628   while 1:
629 \begin_inset Newline newline
630 \end_inset
631
632     line = getline()
633 \begin_inset Newline newline
634 \end_inset
635
636     if line == "": break
637 \begin_inset Newline newline
638 \end_inset
639
640     <<Check line against patterns and take action>>
641 \begin_inset Newline newline
642 \end_inset
643
644 @ %def main
645 \end_layout
646
647 \begin_layout Standard
648 For each line read in, we need to find out if it matches any of our tools
649  (noweb, gcc, etc.) and act accordingly.
650 \end_layout
651
652 \begin_layout Scrap
653 <<Check line against patterns and take action>>=
654 \begin_inset Newline newline
655 \end_inset
656
657 try_patterns_dispatch = [ noweb_try, gcc_try, xlc_try ]
658 \begin_inset Newline newline
659 \end_inset
660
661 for predicate in try_patterns_dispatch:
662 \begin_inset Newline newline
663 \end_inset
664
665   if predicate(line): break
666 \begin_inset Newline newline
667 \end_inset
668
669 @
670 \end_layout
671
672 \begin_layout Section
673 Different Error Formats
674 \end_layout
675
676 \begin_layout Standard
677 The following sections handle the various error message formats that we
678  recognize in this program.
679  
680 \end_layout
681
682 \begin_layout Subsection
683 noweb errors
684 \end_layout
685
686 \begin_layout Standard
687 Noweb errors are output on a single line, so examining just the current
688  line is enough.
689 \end_layout
690
691 \begin_layout Scrap
692 <<Function Bodies>>=
693 \begin_inset Newline newline
694 \end_inset
695
696 def noweb_try(line):
697 \begin_inset Newline newline
698 \end_inset
699
700   """see if line is a noweb error.
701 \begin_inset Newline newline
702 \end_inset
703
704
705 \begin_inset Newline newline
706 \end_inset
707
708   Returns 1 on success, 0 otherwise.
709  Outputs on stdout."""
710 \begin_inset Newline newline
711 \end_inset
712
713   retval = 0
714 \begin_inset Newline newline
715 \end_inset
716
717   <<Look for the unescaped angle-brackets in documentation>>
718 \begin_inset Newline newline
719 \end_inset
720
721   <<Look for anything with double angle brackets>>
722 \begin_inset Newline newline
723 \end_inset
724
725   <<Last ditch effort scan for specific strings>>
726 \begin_inset Newline newline
727 \end_inset
728
729   return retval
730 \begin_inset Newline newline
731 \end_inset
732
733
734 \begin_inset Newline newline
735 \end_inset
736
737 @ %def noweb_try
738 \end_layout
739
740 \begin_layout Standard
741 First, we look for the 
742 \begin_inset Quotes eld
743 \end_inset
744
745 unescaped < < in documentation chunk
746 \begin_inset Quotes erd
747 \end_inset
748
749  message.
750  This is the only message with an associated line number from noweb.
751 \end_layout
752
753 \begin_layout Scrap
754 <<Look for the unescaped angle-brackets in documentation>>=
755 \begin_inset Newline newline
756 \end_inset
757
758 if string.find(line, ": unescaped << in documentation chunk") != -1:
759 \begin_inset Newline newline
760 \end_inset
761
762   line_parts = string.split(line, ':')
763 \begin_inset Newline newline
764 \end_inset
765
766   num_str = line_parts[1]
767 \begin_inset Newline newline
768 \end_inset
769
770   num_len = len(num_str)
771 \begin_inset Newline newline
772 \end_inset
773
774   i = 0
775 \begin_inset Newline newline
776 \end_inset
777
778   while i < num_len and (num_str[i] in string.digits): i = i + 1
779 \begin_inset Newline newline
780 \end_inset
781
782   if i == num_len:
783 \begin_inset Newline newline
784 \end_inset
785
786     write_error(":" + line_parts[2], "noweb", int(num_str))
787 \begin_inset Newline newline
788 \end_inset
789
790     retval = 1
791 \begin_inset Newline newline
792 \end_inset
793
794 @
795 \end_layout
796
797 \begin_layout Standard
798 Some noweb messages are simply about undefined scraps.
799  These can be seen by looking for matching double-angle-brackets.
800 \end_layout
801
802 \begin_layout Scrap
803 <<Look for anything with double angle brackets>>=
804 \begin_inset Newline newline
805 \end_inset
806
807 if (not retval):
808 \begin_inset Newline newline
809 \end_inset
810
811   left = string.find(line, "<<")
812 \begin_inset Newline newline
813 \end_inset
814
815   if (left != -1) and ((left + 2) < len(line)) and 
816 \backslash
817
818 \begin_inset Newline newline
819 \end_inset
820
821      (string.find(line[left+2:], ">>") != -1):
822 \begin_inset Newline newline
823 \end_inset
824
825     write_error(line, "noweb");
826 \begin_inset Newline newline
827 \end_inset
828
829     retval = 1;
830 \begin_inset Newline newline
831 \end_inset
832
833 @
834 \end_layout
835
836 \begin_layout Standard
837 Finally, here is an additional list of explicit strings to check for.
838 \end_layout
839
840 \begin_layout Scrap
841 <<Last ditch effort scan for specific strings>>=
842 \begin_inset Newline newline
843 \end_inset
844
845 if (not retval):
846 \begin_inset Newline newline
847 \end_inset
848
849   msgs_to_try = ("couldn't open file",
850 \begin_inset Newline newline
851 \end_inset
852
853     "couldn't open temporary file",
854 \begin_inset Newline newline
855 \end_inset
856
857     "error writing temporary file",
858 \begin_inset Newline newline
859 \end_inset
860
861     "ill-formed option",
862 \begin_inset Newline newline
863 \end_inset
864
865     "unknown option",
866 \begin_inset Newline newline
867 \end_inset
868
869     "Bad format sequence",
870 \begin_inset Newline newline
871 \end_inset
872
873     "Can't open output file",
874 \begin_inset Newline newline
875 \end_inset
876
877     "Can't open temporary file",
878 \begin_inset Newline newline
879 \end_inset
880
881     "Capacity exceeded:",
882 \begin_inset Newline newline
883 \end_inset
884
885     "Ignoring unknown option -",
886 \begin_inset Newline newline
887 \end_inset
888
889     "This can't happen:",
890 \begin_inset Newline newline
891 \end_inset
892
893     "non-numeric line number in")
894 \begin_inset Newline newline
895 \end_inset
896
897   for msg in msgs_to_try:
898 \begin_inset Newline newline
899 \end_inset
900
901     if string.find(line, msg) != -1:
902 \begin_inset Newline newline
903 \end_inset
904
905       write_error(line, "noweb")
906 \begin_inset Newline newline
907 \end_inset
908
909       retval = 1
910 \begin_inset Newline newline
911 \end_inset
912
913       break
914 \begin_inset Newline newline
915 \end_inset
916
917 @
918 \end_layout
919
920 \begin_layout Subsection
921 gcc errors
922 \end_layout
923
924 \begin_layout Standard
925 The gcc errors can be multi-line, with the following format:
926 \end_layout
927
928 \begin_layout LyX-Code
929 foo.c: In function `main': 
930 \begin_inset Newline newline
931 \end_inset
932
933 foo.c:3: `bar' undeclared (first use in this function) 
934 \begin_inset Newline newline
935 \end_inset
936
937 foo.c:3: (Each undeclared identifier is reported only once 
938 \begin_inset Newline newline
939 \end_inset
940
941 foo.c:3: for each function it appears in.) 
942 \begin_inset Newline newline
943 \end_inset
944
945 foo.c:3: parse error before `x'
946 \end_layout
947
948 \begin_layout Standard
949 In order to parse this, the gcc error handler has to look ahead and return
950  any and all lines that do not match the expected pattern.
951 \end_layout
952
953 \begin_layout Scrap
954 <<Function Bodies>>=
955 \begin_inset Newline newline
956 \end_inset
957
958 def gcc_try(line):
959 \begin_inset Newline newline
960 \end_inset
961
962   """See if line is a gcc error.
963  Read ahead to handle all the lines.
964 \begin_inset Newline newline
965 \end_inset
966
967
968 \begin_inset Newline newline
969 \end_inset
970
971   Returns 1 on success, 0 otherwise.
972  Outputs on stdout."""
973 \begin_inset Newline newline
974 \end_inset
975
976   retval = 0
977 \begin_inset Newline newline
978 \end_inset
979
980   <<Handle the gcc error message>>
981 \begin_inset Newline newline
982 \end_inset
983
984   return retval
985 \begin_inset Newline newline
986 \end_inset
987
988
989 \begin_inset Newline newline
990 \end_inset
991
992 @ %def gcc_try
993 \end_layout
994
995 \begin_layout Standard
996 The error message starts with a gcc header (as above) without an associated
997  line number.
998 \end_layout
999
1000 \begin_layout Scrap
1001 <<Handle the gcc error message>>= 
1002 \begin_inset Newline newline
1003 \end_inset
1004
1005 first_space = string.find(line, ' ')
1006 \begin_inset Newline newline
1007 \end_inset
1008
1009 if first_space > 1: # The smallest would be "X: "
1010 \begin_inset Newline newline
1011 \end_inset
1012
1013   if line[first_space - 1] == ':':
1014 \begin_inset Newline newline
1015 \end_inset
1016
1017     header_to_see = line[:first_space - 1]
1018 \begin_inset Newline newline
1019 \end_inset
1020
1021     next_line = getline()
1022 \begin_inset Newline newline
1023 \end_inset
1024
1025     if next_line and next_line[:first_space - 1] == header_to_see:
1026 \begin_inset Newline newline
1027 \end_inset
1028
1029       num_end = first_space
1030 \begin_inset Newline newline
1031 \end_inset
1032
1033       while next_line[num_end] in string.digits: num_end = num_end + 1
1034 \begin_inset Newline newline
1035 \end_inset
1036
1037       if num_end > first_space: # good!
1038 \begin_inset Newline newline
1039 \end_inset
1040
1041         <<Accumulate gcc error lines and print it>>
1042 \begin_inset Newline newline
1043 \end_inset
1044
1045       else: # oops! Not a gcc error.
1046 \begin_inset Newline newline
1047 \end_inset
1048
1049         pushline(next_line)
1050 \begin_inset Newline newline
1051 \end_inset
1052
1053     elif next_line:
1054 \begin_inset Newline newline
1055 \end_inset
1056
1057       pushline(next_line) # return this line to input stream
1058 \begin_inset Newline newline
1059 \end_inset
1060
1061 @
1062 \end_layout
1063
1064 \begin_layout Standard
1065 At the point in the code that we know that we are in the middle of an error
1066  message, we do the following:
1067 \end_layout
1068
1069 \begin_layout Scrap
1070 <<Accumulate gcc error lines and print it>>=
1071 \begin_inset Newline newline
1072 \end_inset
1073
1074 num_str = next_line[first_space:num_end]
1075 \begin_inset Newline newline
1076 \end_inset
1077
1078 msgs = [line[first_space:]]
1079 \begin_inset Newline newline
1080 \end_inset
1081
1082 msgs.append(next_line[num_end + 1:])
1083 \begin_inset Newline newline
1084 \end_inset
1085
1086 header_to_see = next_line[:num_end]
1087 \begin_inset Newline newline
1088 \end_inset
1089
1090 next_line = getline()
1091 \begin_inset Newline newline
1092 \end_inset
1093
1094 while next_line and next_line[:num_end] == header_to_see:
1095 \begin_inset Newline newline
1096 \end_inset
1097
1098   msgs.append(next_line[num_end + 1:])
1099 \begin_inset Newline newline
1100 \end_inset
1101
1102   next_line = getline()
1103 \begin_inset Newline newline
1104 \end_inset
1105
1106 if next_line: pushline(next_line)
1107 \begin_inset Newline newline
1108 \end_inset
1109
1110 write_error(msgs, "gcc", int(num_str))
1111 \begin_inset Newline newline
1112 \end_inset
1113
1114 retval = 1
1115 \begin_inset Newline newline
1116 \end_inset
1117
1118 @
1119 \end_layout
1120
1121 \begin_layout Subsection
1122 xlc errors
1123 \end_layout
1124
1125 \begin_layout Standard
1126 A xlc error message is easy to identify.
1127  Every error message starts with a quoted string with no spaces, a comma,
1128  a space, the word 
1129 \begin_inset Quotes eld
1130 \end_inset
1131
1132 line
1133 \begin_inset Quotes erd
1134 \end_inset
1135
1136 , a space, and some variable text.
1137  The following routine tests if a given buffer line matches this criteria
1138  (this code would probably be simpler if I used the 
1139 \begin_inset Quotes eld
1140 \end_inset
1141
1142 re
1143 \begin_inset Quotes erd
1144 \end_inset
1145
1146  regexp module, but we don't really need the full regular expression engine
1147  here).
1148  
1149 \end_layout
1150
1151 \begin_layout Scrap
1152 <<Function Bodies>>=
1153 \begin_inset Newline newline
1154 \end_inset
1155
1156 def xlc_try(line):
1157 \begin_inset Newline newline
1158 \end_inset
1159
1160   """see if line is an xlc error.
1161 \begin_inset Newline newline
1162 \end_inset
1163
1164
1165 \begin_inset Newline newline
1166 \end_inset
1167
1168   Returns 1 on success, 0 otherwise.
1169  Outputs on stdout."""
1170 \begin_inset Newline newline
1171 \end_inset
1172
1173   retval = 0
1174 \begin_inset Newline newline
1175 \end_inset
1176
1177   if line[0] == '"': # This is the first character of all xlc errors
1178 \begin_inset Newline newline
1179 \end_inset
1180
1181     next_quote = string.find(line, '"', 1)
1182 \begin_inset Newline newline
1183 \end_inset
1184
1185     first_space = string.find(line, ' ')
1186 \begin_inset Newline newline
1187 \end_inset
1188
1189     if (next_quote != -1) and (first_space > next_quote): # no space inisde
1190  quotes
1191 \begin_inset Newline newline
1192 \end_inset
1193
1194       if line[first_space - 1:first_space + 6] == ", line ":
1195 \begin_inset Newline newline
1196 \end_inset
1197
1198         num_start = num_end = first_space + 6
1199 \begin_inset Newline newline
1200 \end_inset
1201
1202         while line[num_end] in string.digits: num_end = num_end + 1
1203 \begin_inset Newline newline
1204 \end_inset
1205
1206         if num_end > num_start:
1207 \begin_inset Newline newline
1208 \end_inset
1209
1210           write_error(line, "xlc", int(line[num_start : num_end]))
1211 \begin_inset Newline newline
1212 \end_inset
1213
1214           retval = 1
1215 \begin_inset Newline newline
1216 \end_inset
1217
1218   return retval
1219 \begin_inset Newline newline
1220 \end_inset
1221
1222   
1223 \begin_inset Newline newline
1224 \end_inset
1225
1226 @ %def xlc_try
1227 \end_layout
1228
1229 \begin_layout Section
1230 Extracting the code
1231 \end_layout
1232
1233 \begin_layout Standard
1234 This project can be tangled from LyX if you set your 
1235 \begin_inset Quotes eld
1236 \end_inset
1237
1238 Program
1239 \begin_inset Quotes erd
1240 \end_inset
1241
1242  convertor to call a generic script that always extracts a scrap named 
1243 \family typewriter
1244 build-script
1245 \family default
1246  and executes it.
1247  Here is an example of such a generic script:
1248 \end_layout
1249
1250 \begin_layout LyX-Code
1251 #!/bin/sh
1252 \begin_inset Newline newline
1253 \end_inset
1254
1255 notangle -Rbuild-script $1 | env NOWEB_SOURCE=$1 sh
1256 \end_layout
1257
1258 \begin_layout Standard
1259 This section defines our build-script, which extracts the code.
1260 \end_layout
1261
1262 \begin_layout Scrap
1263 <<build-script>>=
1264 \begin_inset Newline newline
1265 \end_inset
1266
1267 #!/bin/sh
1268 \begin_inset Newline newline
1269 \end_inset
1270
1271 if [ -z "$NOWEB_SOURCE" ]; then NOWEB_SOURCE=listerrors.nw; fi
1272 \begin_inset Newline newline
1273 \end_inset
1274
1275 notangle -Rlisterrors ${NOWEB_SOURCE} > listerrors
1276 \begin_inset Newline newline
1277 \end_inset
1278
1279 chmod +x listerrors
1280 \begin_inset Newline newline
1281 \end_inset
1282
1283 @
1284 \end_layout
1285
1286 \begin_layout Section
1287 Indices
1288 \end_layout
1289
1290 \begin_layout Standard
1291 This section provides cross-references into the rest of the program.
1292 \end_layout
1293
1294 \begin_layout Subsection
1295 Macros
1296 \end_layout
1297
1298 \begin_layout Standard
1299 \begin_inset ERT
1300 status collapsed
1301
1302 \begin_layout Plain Layout
1303
1304
1305 \backslash
1306 nowebchunks
1307 \end_layout
1308
1309 \end_inset
1310
1311
1312 \end_layout
1313
1314 \begin_layout Subsection
1315 Identifiers
1316 \end_layout
1317
1318 \begin_layout Standard
1319 \begin_inset ERT
1320 status collapsed
1321
1322 \begin_layout Plain Layout
1323
1324
1325 \backslash
1326 nowebindex
1327 \end_layout
1328
1329 \end_inset
1330
1331
1332 \end_layout
1333
1334 \end_body
1335 \end_document