]> git.lyx.org Git - lyx.git/blobdiff - lib/examples/listerrors.lyx
Math.lyx: add info about character ^ in chemical formulas
[lyx.git] / lib / examples / listerrors.lyx
index 48999af139fe9902df484d03dfdd64e488c23e12..4214c4fe45a6db8ba607f4491595983fb9da456e 100644 (file)
@@ -1,5 +1,7 @@
-#LyX 1.2 created this file. For more info see http://www.lyx.org/
-\lyxformat 220
+#LyX 2.1 created this file. For more info see http://www.lyx.org/
+\lyxformat 442
+\begin_document
+\begin_header
 \textclass literate-article
 \begin_preamble
 %
 \def\nwendcode{\endtrivlist \endgroup \vfil\penalty10\vfilneg}
 \let\nwdocspar=\smallbreak
 \end_preamble
+\use_default_options false
+\maintain_unincluded_children false
 \language english
+\language_package default
 \inputencoding auto
-\fontscheme pslatex
+\fontencoding global
+\font_roman times
+\font_sans helvet
+\font_typewriter courier
+\font_math auto
+\font_default_family default
+\use_non_tex_fonts false
+\font_sc false
+\font_osf false
+\font_sf_scale 100
+\font_tt_scale 100
 \graphics default
+\default_output_format default
+\output_sync 0
+\bibtex_command default
+\index_command default
 \paperfontsize default
-\spacing single 
-\papersize Default
-\paperpackage a4
-\use_geometry 0
-\use_amsmath 0
-\use_natbib 0
-\use_numerical_citations 0
+\spacing single
+\use_hyperref false
+\papersize default
+\use_geometry false
+\use_package amsmath 0
+\use_package amssymb 0
+\use_package esint 0
+\use_package mathdots 1
+\use_package mathtools 0
+\use_package mhchem 1
+\use_package undertilde 0
+\cite_engine basic
+\cite_engine_type numerical
+\biblio_style plain
+\use_bibtopic false
+\use_indices false
 \paperorientation portrait
+\suppress_date false
+\justification true
+\use_refstyle 0
+\index Index
+\shortcut idx
+\color #008000
+\end_index
 \secnumdepth 3
 \tocdepth 3
 \paragraph_separation indent
-\defskip medskip
+\paragraph_indentation default
 \quotes_language english
-\quotes_times 2
 \papercolumns 1
 \papersides 1
 \paperpagestyle default
+\tracking_changes false
+\output_changes false
+\html_math_output 0
+\html_css_as_file 0
+\html_be_strict false
+\end_header
 
-\layout Title
+\begin_body
 
+\begin_layout Title
 LyX listerrors:
-\newline 
+\begin_inset Newline newline
+\end_inset
+
 rewritten in Python
-\layout Author
+\end_layout
 
+\begin_layout Author
 Kayvan A.
  Sylvan
-\newline 
+\begin_inset Newline newline
+\end_inset
+
+
+\begin_inset Flex URL
+status collapsed
 
-\begin_inset LatexCommand \url{mailto:kayvan@sylvan.com}
+\begin_layout Plain Layout
 
-\end_inset 
+mailto:kayvan@sylvan.com
+\end_layout
 
+\end_inset
 
-\layout Date
 
+\end_layout
+
+\begin_layout Date
 3/15/2002
-\layout Abstract
+\end_layout
 
+\begin_layout Abstract
 The listerrors program used to be compiled as a C program and installed
  as 
-\emph on 
+\emph on
 BINDIR/listerrors
-\emph default 
+\emph default
  along with LyX in order to perform some simple re-formatting of noweb and
  GCC error messages.
  This document describes and implements the Python version of the same program.
-\layout Standard
-
+\end_layout
 
-\begin_inset LatexCommand \tableofcontents{}
+\begin_layout Standard
+\begin_inset CommandInset toc
+LatexCommand tableofcontents
 
-\end_inset 
+\end_inset
 
 
-\layout Section
+\end_layout
 
+\begin_layout Section
 Introduction
-\layout Standard
+\end_layout
 
-The motivation for this program was Bugzilla bug 190
+\begin_layout Standard
+The motivation for this program was LyX bug 190
 \begin_inset Foot
-collapsed true
-
-\layout Standard
+status collapsed
 
+\begin_layout Plain Layout
 Visit 
-\begin_inset LatexCommand \url{http://bugzilla.lyx.org/show_bug.cgi?id=190}
+\begin_inset Flex URL
+status collapsed
 
-\end_inset 
+\begin_layout Plain Layout
+
+http://www.lyx.org/trac/ticket/190
+\end_layout
+
+\end_inset
 
  for the details.
-\end_inset 
+\end_layout
+
+\end_inset
 
  dealing with the 
 \begin_inset Quotes eld
-\end_inset 
+\end_inset
 
 listerrors
 \begin_inset Quotes erd
-\end_inset 
+\end_inset
 
  executable.
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 What is 
 \begin_inset Quotes eld
-\end_inset 
+\end_inset
 
 listerrors
 \begin_inset Quotes erd
-\end_inset 
+\end_inset
 
 ? Usually, LyX has great support for parsing of error messages.
  For each error in the log file, LyX pops up an error box at that location
@@ -120,736 +185,1356 @@ listerrors
  (similar to LaTeX errors).
  When dealing with Literate Programs, you have 
 \begin_inset Quotes eld
-\end_inset 
+\end_inset
 
 noweb
 \begin_inset Foot
-collapsed true
-
-\layout Standard
+status collapsed
 
+\begin_layout Plain Layout
 See 
-\begin_inset LatexCommand \url{http://www.eecs.harvard.edu/~nr/noweb}
+\begin_inset Flex URL
+status collapsed
+
+\begin_layout Plain Layout
+
+http://www.eecs.harvard.edu/~nr/noweb
+\end_layout
 
-\end_inset 
+\end_inset
 
  for more information about noweb.
-\end_inset 
+\end_layout
+
+\end_inset
 
 
 \begin_inset Quotes erd
-\end_inset 
+\end_inset
 
  as well as gcc error messages (and potentially others).
  The listerrors program attempts to standardize these error messages to
  a format that LyX can parse and react to.
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 In a nutshell, the problems with the old implementation of listerrors that
  bug 190 refers to were::
-\layout Enumerate
+\end_layout
 
+\begin_layout Enumerate
 It was a C program and it was installed in the user path in the same directory
  as LyX.
  Having such a generically named binary in, for example, 
-\emph on 
+\emph on
 /usr/bin
-\emph default 
+\emph default
 , was potentially confusing.
-\layout Enumerate
+\end_layout
 
+\begin_layout Enumerate
 It required that noweb be installed on the compiling machine (the source
  was extracted by noweb from 
-\emph on 
+\emph on
 SRCDIR/examples/Literate.lyx
-\emph default 
+\emph default
 , compiled and installed by 
 \begin_inset Quotes eld
-\end_inset 
+\end_inset
 
 make install
 \begin_inset Quotes erd
-\end_inset 
+\end_inset
 
 ).
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 The new version deals with these problems in the following fashion:
-\layout Enumerate
+\end_layout
 
+\begin_layout Enumerate
 Both the example file (this document) and the program are to be added to
  the LyX CVS repository.
-\layout Enumerate
+\end_layout
 
+\begin_layout Enumerate
 The program itself will be installed in 
-\emph on 
+\emph on
 SHAREDIR/lyx/scripts
-\emph default 
+\emph default
 , along with other LyX-specific helper scripts.
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 In the design and implementation of this new 
 \begin_inset Quotes eld
-\end_inset 
+\end_inset
 
 listerrors
 \begin_inset Quotes erd
-\end_inset 
+\end_inset
 
 , the Python
 \begin_inset Foot
-collapsed true
-
-\layout Standard
+status collapsed
 
+\begin_layout Plain Layout
 See the Python home page (
-\begin_inset LatexCommand \url{http://www.python.org}
+\begin_inset Flex URL
+status collapsed
+
+\begin_layout Plain Layout
 
-\end_inset 
+http://www.python.org
+\end_layout
+
+\end_inset
 
 ) for more information.
-\end_inset 
+\end_layout
+
+\end_inset
 
  language was chosen since it is fully multi-platform and provides a very
  uniform and easy to read syntax.
  This re-write also simplifies the code for 
 \begin_inset Quotes eld
-\end_inset 
+\end_inset
 
 listerrors
 \begin_inset Quotes erd
-\end_inset 
+\end_inset
 
  greatly.
  Python is installed by default on all modern Linux systems and is freely
  available for all other platforms.
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
 
 <<listerrors>>=
-\newline 
-#!/usr/bin/python
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+#!/usr/bin/python -tt
+\end_layout
+
+\begin_layout Scrap
+
 """reformat noweb and compiler errors for LyX.
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
 Expects to read from stdin and output to stdout.
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 """
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
 __author__ = "Kayvan A.
  Sylvan <kayvan@sylvan.com>"
-\newline 
-__date__ = "$Date: 2002/03/25 23:29:30 $"
-\newline 
-__version__ = "$Revision: 1.2 $"
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+__date__ = "$Date: 2005/07/18 09:42:26 $"
+\end_layout
+
+\begin_layout Scrap
+
+__version__ = "$Revision: 1.5 $"
+\end_layout
+
+\begin_layout Scrap
+
 __credits__ = """Edmar Wienskoski Jr.
  <edmar-w-jr@technologist.com>
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     original Literate support for LyX.
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 Bernard Michael Hurley <berhardh@westherts.ac.uk>
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     modifications to original listerrors."""
-\newline 
-__copyright__ = "Copyright 2002 - The LyX team."
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+__copyright__ = "Copyright 2002 - Kayvan Sylvan."
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
 import sys, string
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
 <<Function Bodies>>
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
 if __name__ == "__main__":
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   main()
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 @
-\layout Section
+\end_layout
 
+\begin_layout Section
 LaTeX style error message
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 The following function mimics the TeX error message format.
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
 
 <<Function Bodies>>=
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 def write_error(msg, tool = "noweb", line_number = 1):
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   """Write out the given message in TeX error style.
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
   called like: write_error(msg, tool, line_number)."""
-\newline 
+\begin_inset Newline newline
+\end_inset
+
   print "! Build Error: ==> %s ==>
-\backslash 
+\backslash
 n" % (tool),
-\newline 
+\begin_inset Newline newline
+\end_inset
+
   print " ...
-\backslash 
+\backslash
 n
-\backslash 
+\backslash
 nl.%d ...
-\backslash 
+\backslash
 n" % (line_number),
-\newline 
+\begin_inset Newline newline
+\end_inset
+
   if type(msg) == type("str"): # simple string
-\newline 
+\begin_inset Newline newline
+\end_inset
+
     print msg
-\newline 
+\begin_inset Newline newline
+\end_inset
+
   else: # some kind of list (sequence or tuple)
-\newline 
+\begin_inset Newline newline
+\end_inset
+
     for m in msg:
-\newline 
+\begin_inset Newline newline
+\end_inset
+
         if m != "": print m,
-\newline 
+\begin_inset Newline newline
+\end_inset
+
     print
-\newline 
+\begin_inset Newline newline
+\end_inset
+
+
+\begin_inset Newline newline
+\end_inset
 
-\newline 
 @ %def write_error
-\layout Section
+\end_layout
 
+\begin_layout Section
 Filtering errors
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 The only complication in our filtering code is that some parsers might need
  to push back lines that are read in to be read again later.
  We solve this problem by implementing a 
 \begin_inset Quotes eld
-\end_inset 
+\end_inset
 
 getline
 \begin_inset Quotes erd
-\end_inset 
+\end_inset
 
  and 
 \begin_inset Quotes eld
-\end_inset 
+\end_inset
 
 pushline
 \begin_inset Quotes erd
-\end_inset 
+\end_inset
 
  set of functions:
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
 
 <<Function Bodies>>=
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 __lines = [] # lines pushed back
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
 def getline(file = sys.stdin):
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   """read a line from internal stack or from file.
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
   optional file argument defaults to sys.stdin."""
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   global __lines
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   lines = __lines
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   if lines:
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     line = lines.pop()
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   else:
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     line = file.readline()
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   return line
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
 @ %def getline
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 And now for the corresponding pushline function:
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
 
 <<Function Bodies>>=
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 def pushline(line):
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   "push a line onto the pushback stack."
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
+
   global __lines
-\newline 
+\begin_inset Newline newline
+\end_inset
+
   lines = __lines
-\newline 
+\begin_inset Newline newline
+\end_inset
+
   lines.append(line)
-\newline 
+\begin_inset Newline newline
+\end_inset
+
+
+\begin_inset Newline newline
+\end_inset
 
-\newline 
 @ %def pushline
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 The main() entry point function is extremely simple.
  Note that this version of 
 \begin_inset Quotes eld
-\end_inset 
+\end_inset
 
 listerrors
 \begin_inset Quotes erd
-\end_inset 
+\end_inset
 
  takes no options and simply filters, attempting simply to match against
  the known error message patterns.
  The listerrors C program handled a single-character command-line argument
  that the current code no longer needs.
  
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
 
 <<Function Bodies>>=
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 def main():
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   """Entry point for listerrors.
  Takes no options.
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
   Reads stdin and writes to stdout.
  Filter errors"""
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
   while 1:
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     line = getline()
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     if line == "": break
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     <<Check line against patterns and take action>>
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 @ %def main
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 For each line read in, we need to find out if it matches any of our tools
  (noweb, gcc, etc.) and act accordingly.
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
 
 <<Check line against patterns and take action>>=
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
+
 try_patterns_dispatch = [ noweb_try, gcc_try, xlc_try ]
-\newline 
+\begin_inset Newline newline
+\end_inset
+
 for predicate in try_patterns_dispatch:
-\newline 
+\begin_inset Newline newline
+\end_inset
+
   if predicate(line): break
-\newline 
+\begin_inset Newline newline
+\end_inset
+
 @
-\layout Section
+\end_layout
 
+\begin_layout Section
 Different Error Formats
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 The following sections handle the various error message formats that we
  recognize in this program.
  
-\layout Subsection
+\end_layout
 
+\begin_layout Subsection
 noweb errors
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 Noweb errors are output on a single line, so examining just the current
  line is enough.
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
 
 <<Function Bodies>>=
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 def noweb_try(line):
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   """see if line is a noweb error.
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
   Returns 1 on success, 0 otherwise.
  Outputs on stdout."""
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   retval = 0
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   <<Look for the unescaped angle-brackets in documentation>>
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   <<Look for anything with double angle brackets>>
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   <<Last ditch effort scan for specific strings>>
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   return retval
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
 @ %def noweb_try
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 First, we look for the 
 \begin_inset Quotes eld
-\end_inset 
+\end_inset
 
 unescaped < < in documentation chunk
 \begin_inset Quotes erd
-\end_inset 
+\end_inset
 
  message.
  This is the only message with an associated line number from noweb.
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
 <<Look for the unescaped angle-brackets in documentation>>=
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 if string.find(line, ": unescaped << in documentation chunk") != -1:
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   line_parts = string.split(line, ':')
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   num_str = line_parts[1]
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   num_len = len(num_str)
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   i = 0
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   while i < num_len and (num_str[i] in string.digits): i = i + 1
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   if i == num_len:
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     write_error(":" + line_parts[2], "noweb", int(num_str))
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     retval = 1
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 @
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 Some noweb messages are simply about undefined scraps.
  These can be seen by looking for matching double-angle-brackets.
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
 
 <<Look for anything with double angle brackets>>=
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
+
 if (not retval):
-\newline 
+\begin_inset Newline newline
+\end_inset
+
   left = string.find(line, "<<")
-\newline 
+\begin_inset Newline newline
+\end_inset
+
   if (left != -1) and ((left + 2) < len(line)) and 
-\backslash 
+\backslash
+
+\begin_inset Newline newline
+\end_inset
 
-\newline 
      (string.find(line[left+2:], ">>") != -1):
-\newline 
+\begin_inset Newline newline
+\end_inset
+
     write_error(line, "noweb");
-\newline 
+\begin_inset Newline newline
+\end_inset
+
     retval = 1;
-\newline 
+\begin_inset Newline newline
+\end_inset
+
 @
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 Finally, here is an additional list of explicit strings to check for.
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
 
 <<Last ditch effort scan for specific strings>>=
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 if (not retval):
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   msgs_to_try = ("couldn't open file",
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     "couldn't open temporary file",
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     "error writing temporary file",
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     "ill-formed option",
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     "unknown option",
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     "Bad format sequence",
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     "Can't open output file",
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     "Can't open temporary file",
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     "Capacity exceeded:",
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     "Ignoring unknown option -",
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     "This can't happen:",
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     "non-numeric line number in")
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   for msg in msgs_to_try:
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     if string.find(line, msg) != -1:
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
       write_error(line, "noweb")
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
       retval = 1
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
       break
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 @
-\layout Subsection
+\end_layout
 
+\begin_layout Subsection
 gcc errors
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 The gcc errors can be multi-line, with the following format:
-\layout LyX-Code
+\end_layout
 
+\begin_layout LyX-Code
 foo.c: In function `main': 
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 foo.c:3: `bar' undeclared (first use in this function) 
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 foo.c:3: (Each undeclared identifier is reported only once 
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
+
 foo.c:3: for each function it appears in.) 
-\newline 
+\begin_inset Newline newline
+\end_inset
+
 foo.c:3: parse error before `x'
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 In order to parse this, the gcc error handler has to look ahead and return
  any and all lines that do not match the expected pattern.
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
 
 <<Function Bodies>>=
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 def gcc_try(line):
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   """See if line is a gcc error.
  Read ahead to handle all the lines.
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
   Returns 1 on success, 0 otherwise.
  Outputs on stdout."""
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   retval = 0
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   <<Handle the gcc error message>>
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   return retval
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
 @ %def gcc_try
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 The error message starts with a gcc header (as above) without an associated
  line number.
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
 
 <<Handle the gcc error message>>= 
-\newline 
+\begin_inset Newline newline
+\end_inset
+
 first_space = string.find(line, ' ')
-\newline 
+\begin_inset Newline newline
+\end_inset
+
 if first_space > 1: # The smallest would be "X: "
-\newline 
+\begin_inset Newline newline
+\end_inset
+
   if line[first_space - 1] == ':':
-\newline 
+\begin_inset Newline newline
+\end_inset
+
     header_to_see = line[:first_space - 1]
-\newline 
+\begin_inset Newline newline
+\end_inset
+
     next_line = getline()
-\newline 
+\begin_inset Newline newline
+\end_inset
+
     if next_line and next_line[:first_space - 1] == header_to_see:
-\newline 
+\begin_inset Newline newline
+\end_inset
+
       num_end = first_space
-\newline 
+\begin_inset Newline newline
+\end_inset
+
       while next_line[num_end] in string.digits: num_end = num_end + 1
-\newline 
+\begin_inset Newline newline
+\end_inset
+
       if num_end > first_space: # good!
-\newline 
+\begin_inset Newline newline
+\end_inset
+
         <<Accumulate gcc error lines and print it>>
-\newline 
+\begin_inset Newline newline
+\end_inset
+
       else: # oops! Not a gcc error.
-\newline 
+\begin_inset Newline newline
+\end_inset
+
         pushline(next_line)
-\newline 
+\begin_inset Newline newline
+\end_inset
+
     elif next_line:
-\newline 
+\begin_inset Newline newline
+\end_inset
+
       pushline(next_line) # return this line to input stream
-\newline 
+\begin_inset Newline newline
+\end_inset
+
 @
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 At the point in the code that we know that we are in the middle of an error
  message, we do the following:
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
 
 <<Accumulate gcc error lines and print it>>=
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 num_str = next_line[first_space:num_end]
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 msgs = [line[first_space:]]
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 msgs.append(next_line[num_end + 1:])
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 header_to_see = next_line[:num_end]
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 next_line = getline()
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 while next_line and next_line[:num_end] == header_to_see:
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   msgs.append(next_line[num_end + 1:])
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   next_line = getline()
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 if next_line: pushline(next_line)
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 write_error(msgs, "gcc", int(num_str))
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 retval = 1
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 @
-\layout Subsection
+\end_layout
 
+\begin_layout Subsection
 xlc errors
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 A xlc error message is easy to identify.
  Every error message starts with a quoted string with no spaces, a comma,
  a space, the word 
 \begin_inset Quotes eld
-\end_inset 
+\end_inset
 
 line
 \begin_inset Quotes erd
-\end_inset 
+\end_inset
 
 , a space, and some variable text.
  The following routine tests if a given buffer line matches this criteria
  (this code would probably be simpler if I used the 
 \begin_inset Quotes eld
-\end_inset 
+\end_inset
 
 re
 \begin_inset Quotes erd
-\end_inset 
+\end_inset
 
  regexp module, but we don't really need the full regular expression engine
  here).
  
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
 <<Function Bodies>>=
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 def xlc_try(line):
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   """see if line is an xlc error.
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+\end_layout
+
+\begin_layout Scrap
 
-\newline 
   Returns 1 on success, 0 otherwise.
  Outputs on stdout."""
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   retval = 0
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   if line[0] == '"': # This is the first character of all xlc errors
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     next_quote = string.find(line, '"', 1)
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     first_space = string.find(line, ' ')
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
     if (next_quote != -1) and (first_space > next_quote): # no space inisde
  quotes
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
       if line[first_space - 1:first_space + 6] == ", line ":
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
         num_start = num_end = first_space + 6
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
         while line[num_end] in string.digits: num_end = num_end + 1
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
         if num_end > num_start:
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
           write_error(line, "xlc", int(line[num_start : num_end]))
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
           retval = 1
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   return retval
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
   
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 @ %def xlc_try
-\layout Section
+\end_layout
 
+\begin_layout Section
 Extracting the code
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 This project can be tangled from LyX if you set your 
 \begin_inset Quotes eld
-\end_inset 
+\end_inset
 
 Program
 \begin_inset Quotes erd
-\end_inset 
+\end_inset
 
  convertor to call a generic script that always extracts a scrap named 
-\family typewriter 
+\family typewriter
 build-script
-\family default 
+\family default
  and executes it.
  Here is an example of such a generic script:
-\layout LyX-Code
+\end_layout
 
+\begin_layout LyX-Code
 #!/bin/sh
-\newline 
+\begin_inset Newline newline
+\end_inset
+
 notangle -Rbuild-script $1 | env NOWEB_SOURCE=$1 sh
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 This section defines our build-script, which extracts the code.
-\layout Scrap
+\end_layout
+
+\begin_layout Scrap
 
 <<build-script>>=
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 #!/bin/sh
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
 if [ -z "$NOWEB_SOURCE" ]; then NOWEB_SOURCE=listerrors.nw; fi
-\newline 
-notangle -Rlisterrors ${NOWEB_SOURCE} > listerrors
-\newline 
-chmod +x listerrors
-\newline 
+\end_layout
+
+\begin_layout Scrap
+
+if [ -z "$NOWEB_OUTPUT_DIR" ]; then NOWEB_OUTPUT_DIR=.; fi
+\end_layout
+
+\begin_layout Scrap
+
+notangle -Rlisterrors ${NOWEB_SOURCE} > ${NOWEB_OUTPUT_DIR}/listerrors
+\end_layout
+
+\begin_layout Scrap
+
+chmod +x ${NOWEB_OUTPUT_DIR}/listerrors
+\end_layout
+
+\begin_layout Scrap
+
 @
-\layout Section
+\end_layout
 
+\begin_layout Section
 Indices
-\layout Standard
+\end_layout
 
+\begin_layout Standard
 This section provides cross-references into the rest of the program.
-\layout Subsection
+\end_layout
 
+\begin_layout Subsection
 Macros
-\layout Standard
-
+\end_layout
 
+\begin_layout Standard
 \begin_inset ERT
-status Collapsed
+status collapsed
+
+\begin_layout Plain Layout
 
-\layout Standard
 
-\backslash 
+\backslash
 nowebchunks
-\end_inset 
+\end_layout
 
+\end_inset
 
-\layout Subsection
 
-Identifiers
-\layout Standard
+\end_layout
 
+\begin_layout Subsection
+Identifiers
+\end_layout
 
+\begin_layout Standard
 \begin_inset ERT
-status Collapsed
+status collapsed
+
+\begin_layout Plain Layout
 
-\layout Standard
 
-\backslash 
+\backslash
 nowebindex
-\end_inset 
+\end_layout
+
+\end_inset
+
 
+\end_layout
 
-\the_end
+\end_body
+\end_document