#LyX 2.1 created this file. For more info see http://www.lyx.org/
-\lyxformat 431
+\lyxformat 442
\begin_document
\begin_header
\textclass scrbook
\font_roman default
\font_sans default
\font_typewriter default
+\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 1
\family typewriter
build-script $$i
\family default
-
+ $$r
\begin_inset Quotes erd
\end_inset
\end_inset
(a program or script) with the name of the Noweb file (normally a file
- in the LyX temp directory).
+ in the LyX temp directory) and the directory path of the original LyX file.
\end_layout
\end_layout
\begin_layout LyX-Code
-notangle -Rbuild-script $1 | env NOWEB_SOURCE=$1 sh
+notangle -Rbuild-script $1 | env NOWEB_SOURCE=$1 NOWEB_OUTPUT_DIR=$2 sh
\end_layout
\begin_layout Standard
\family typewriter
-parselog=listerrors
+parselog=$$s/scripts/listerrors
\family default
\begin_inset Quotes erd
program.
\end_layout
-\begin_layout Standard
-The converter code looks in
-\emph on
-MYLYXDIR/scripts
-\emph default
- first, then in
-\emph on
-LIBDIR/scripts
-\emph default
- then on the path for the
-\begin_inset Quotes eld
-\end_inset
-
-listerrors
-\begin_inset Quotes erd
-\end_inset
-
- program.
-\end_layout
-
\begin_layout Standard
The build will normally take place in LyX's temporary directory, so the
files produced by the conversion will be in that directory.
\family default
conversion may produce several files, and so most of these would then be
deleted when LyX was closed.
- The present solution is to use a `copier',
-\begin_inset Foot
-status collapsed
-
-\begin_layout Plain Layout
-See section
-\emph on
-Copiers
-\emph default
- of the
-\emph on
-Customization
-\emph default
- manual for information on these.
-\end_layout
-
-\end_inset
-
- in this case, the
-\family typewriter
-ext_copy.py
-\family default
- script in its default mode, so that the entire contents of the temporary
- directory is copied.
- More will get copied than is needed, to be sure, but nothing will be lost.
- If, however, you know what extensions the generated files will have, this
- can be improved by using the
-\family typewriter
--e
-\family default
- option to
-\family typewriter
-ext_copy
-\family default
-.
- This option takes a comma-separated list of extensions to copy.
- So, for example, if the conversion will generate only files with the extensions
-
-\family typewriter
-.c
-\family default
- and
-\family typewriter
-.h
-\family default
-, then the correct definition would be:
-\end_layout
-
-\begin_layout LyX-Code
-python -tt $$s/scripts/ext_copy.py -e c,h $$i $$o
-\end_layout
-
-\begin_layout Standard
-The result will be that only files with these two extensions will be copied
- out.
+ This is why we pass in the NOWEB_OUTPUT_DIR environment variable so that
+ the build-script scrap can place the generated files in that location.
\end_layout
\begin_layout Paragraph
\end_inset
[...
- code to extract files ...]
+ code to extract files ...
+ use NOWEB_OUTPUT_DIR here ...]
\begin_inset Newline newline
\end_inset
\begin_inset Quotes eld
\end_inset
-Conversion
+File Handling
\begin_inset Quotes erd
\end_inset
\begin_inset Quotes eld
\end_inset
-literate
+NoWeb
\begin_inset Quotes erd
\end_inset
\begin_inset space ~
\end_inset
-format Set up via the Formats tab, this is where the Noweb-specific pieces
- are set up.
+format Set up via the File Formats tab, this is where the Noweb-specific
+ pieces are set up.
The
\family sans
GUI Name
\family typewriter
build-script $$i
\family default
-
+ $$r
\begin_inset Quotes erd
\end_inset
\family typewriter
-originaldir,parselog=listerrors
+parselog=$$s/scripts/listerrors
\family default
\begin_inset Quotes erd
#LyX 2.1 created this file. For more info see http://www.lyx.org/
-\lyxformat 431
+\lyxformat 442
\begin_document
\begin_header
\textclass scrbook
\font_roman default
\font_sans default
\font_typewriter default
+\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
\html_be_strict true
\author -195340706 "Georg Baum"
\author 5863208 "ab"
+\author 1082167584 "Kayvan Sylvan" kayvan@sylvan.com
\author 1414654397 "Richard Heck"
\end_header
\end_inset
The output file
+\change_inserted 1082167584 1348453985
+
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+
+\change_inserted 1082167584 1348453986
+$$b The base name (without filename extension) in the LyX temporary directory
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+
+\change_inserted 1082167584 1348453986
+$$p The full directory path of the LyX temporary directory
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+
+\change_inserted 1082167584 1348453986
+$$r The full pathname to the original LyX file being processed
+\end_layout
+
+\begin_layout Labeling
+\labelwidthstring 00.00.0000
+
+\change_inserted 1082167584 1348453986
+$$f The filename (without any directory path) of the LyX file.
\end_layout
\begin_layout Labeling
\end_inset
The `LaTeX name'
+\change_inserted 1082167584 1348453720
+
\end_layout
\begin_layout Standard
-#LyX 2.0 created this file. For more info see http://www.lyx.org/
-\lyxformat 413
+#LyX 2.1 created this file. For more info see http://www.lyx.org/
+\lyxformat 442
\begin_document
\begin_header
\textclass literate-article
\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
\use_hyperref false
\papersize default
\use_geometry false
-\use_amsmath 0
-\use_esint 0
-\use_mhchem 1
-\use_mathdots 1
+\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
\end_layout
\begin_layout Scrap
+
<<listerrors>>=
\end_layout
\begin_layout Scrap
+
#!/usr/bin/python -tt
\end_layout
\begin_layout Scrap
+
"""reformat noweb and compiler errors for LyX.
\end_layout
\end_layout
\begin_layout Scrap
+
Expects to read from stdin and output to stdout.
\end_layout
\begin_layout Scrap
+
"""
\end_layout
\end_layout
\begin_layout Scrap
+
__author__ = "Kayvan A.
Sylvan <kayvan@sylvan.com>"
\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>
\end_layout
\begin_layout Scrap
+
original Literate support for LyX.
\end_layout
\begin_layout Scrap
+
Bernard Michael Hurley <berhardh@westherts.ac.uk>
\end_layout
\begin_layout Scrap
+
modifications to original listerrors."""
\end_layout
\begin_layout Scrap
+
__copyright__ = "Copyright 2002 - Kayvan Sylvan."
\end_layout
\end_layout
\begin_layout Scrap
+
import sys, string
\end_layout
\end_layout
\begin_layout Scrap
+
<<Function Bodies>>
\end_layout
\end_layout
\begin_layout Scrap
+
if __name__ == "__main__":
\end_layout
\begin_layout Scrap
+
main()
\end_layout
\begin_layout Scrap
+
@
\end_layout
\end_layout
\begin_layout Scrap
+
<<Function Bodies>>=
\end_layout
\begin_layout Scrap
+
def write_error(msg, tool = "noweb", line_number = 1):
\end_layout
\begin_layout Scrap
+
"""Write out the given message in TeX error style.
\end_layout
\end_layout
\begin_layout Scrap
+
called like: write_error(msg, tool, line_number)."""
\begin_inset Newline newline
\end_inset
\end_layout
\begin_layout Scrap
+
<<Function Bodies>>=
\end_layout
\begin_layout Scrap
+
__lines = [] # lines pushed back
\end_layout
\end_layout
\begin_layout Scrap
+
def getline(file = sys.stdin):
\end_layout
\begin_layout Scrap
+
"""read a line from internal stack or from file.
\end_layout
\end_layout
\begin_layout Scrap
+
optional file argument defaults to sys.stdin."""
\end_layout
\begin_layout Scrap
+
global __lines
\end_layout
\begin_layout Scrap
+
lines = __lines
\end_layout
\begin_layout Scrap
+
if lines:
\end_layout
\begin_layout Scrap
+
line = lines.pop()
\end_layout
\begin_layout Scrap
+
else:
\end_layout
\begin_layout Scrap
+
line = file.readline()
\end_layout
\begin_layout Scrap
+
return line
\end_layout
\end_layout
\begin_layout Scrap
+
@ %def getline
\end_layout
\end_layout
\begin_layout Scrap
+
<<Function Bodies>>=
\end_layout
\begin_layout Scrap
+
def pushline(line):
\end_layout
\begin_layout Scrap
+
"push a line onto the pushback stack."
\end_layout
\end_layout
\begin_layout Scrap
+
global __lines
\begin_inset Newline newline
\end_inset
\end_layout
\begin_layout Scrap
+
<<Function Bodies>>=
\end_layout
\begin_layout Scrap
+
def main():
\end_layout
\begin_layout Scrap
+
"""Entry point for listerrors.
Takes no options.
\end_layout
\end_layout
\begin_layout Scrap
+
Reads stdin and writes to stdout.
Filter errors"""
\end_layout
\end_layout
\begin_layout Scrap
+
while 1:
\end_layout
\begin_layout Scrap
+
line = getline()
\end_layout
\begin_layout Scrap
+
if line == "": break
\end_layout
\begin_layout Scrap
+
<<Check line against patterns and take action>>
\end_layout
\begin_layout Scrap
+
@ %def main
\end_layout
\end_layout
\begin_layout Scrap
+
<<Check line against patterns and take action>>=
\end_layout
\end_layout
\begin_layout Scrap
+
try_patterns_dispatch = [ noweb_try, gcc_try, xlc_try ]
\begin_inset Newline newline
\end_inset
\end_layout
\begin_layout Scrap
+
<<Function Bodies>>=
\end_layout
\begin_layout Scrap
+
def noweb_try(line):
\end_layout
\begin_layout Scrap
+
"""see if line is a noweb error.
\end_layout
\end_layout
\begin_layout Scrap
+
Returns 1 on success, 0 otherwise.
Outputs on stdout."""
\end_layout
\begin_layout Scrap
+
retval = 0
\end_layout
\begin_layout Scrap
+
<<Look for the unescaped angle-brackets in documentation>>
\end_layout
\begin_layout Scrap
+
<<Look for anything with double angle brackets>>
\end_layout
\begin_layout Scrap
+
<<Last ditch effort scan for specific strings>>
\end_layout
\begin_layout Scrap
+
return retval
\end_layout
\end_layout
\begin_layout Scrap
+
@ %def noweb_try
\end_layout
\end_layout
\begin_layout Scrap
+
<<Look for the unescaped angle-brackets in documentation>>=
\end_layout
\begin_layout Scrap
+
if string.find(line, ": unescaped << in documentation chunk") != -1:
\end_layout
\begin_layout Scrap
+
line_parts = string.split(line, ':')
\end_layout
\begin_layout Scrap
+
num_str = line_parts[1]
\end_layout
\begin_layout Scrap
+
num_len = len(num_str)
\end_layout
\begin_layout Scrap
+
i = 0
\end_layout
\begin_layout Scrap
+
while i < num_len and (num_str[i] in string.digits): i = i + 1
\end_layout
\begin_layout Scrap
+
if i == num_len:
\end_layout
\begin_layout Scrap
+
write_error(":" + line_parts[2], "noweb", int(num_str))
\end_layout
\begin_layout Scrap
+
retval = 1
\end_layout
\begin_layout Scrap
+
@
\end_layout
\end_layout
\begin_layout Scrap
+
<<Look for anything with double angle brackets>>=
\end_layout
\end_layout
\begin_layout Scrap
+
if (not retval):
\begin_inset Newline newline
\end_inset
\end_layout
\begin_layout Scrap
+
<<Last ditch effort scan for specific strings>>=
\end_layout
\begin_layout Scrap
+
if (not retval):
\end_layout
\begin_layout Scrap
+
msgs_to_try = ("couldn't open file",
\end_layout
\begin_layout Scrap
+
"couldn't open temporary file",
\end_layout
\begin_layout Scrap
+
"error writing temporary file",
\end_layout
\begin_layout Scrap
+
"ill-formed option",
\end_layout
\begin_layout Scrap
+
"unknown option",
\end_layout
\begin_layout Scrap
+
"Bad format sequence",
\end_layout
\begin_layout Scrap
+
"Can't open output file",
\end_layout
\begin_layout Scrap
+
"Can't open temporary file",
\end_layout
\begin_layout Scrap
+
"Capacity exceeded:",
\end_layout
\begin_layout Scrap
+
"Ignoring unknown option -",
\end_layout
\begin_layout Scrap
+
"This can't happen:",
\end_layout
\begin_layout Scrap
+
"non-numeric line number in")
\end_layout
\begin_layout Scrap
+
for msg in msgs_to_try:
\end_layout
\begin_layout Scrap
+
if string.find(line, msg) != -1:
\end_layout
\begin_layout Scrap
+
write_error(line, "noweb")
\end_layout
\begin_layout Scrap
+
retval = 1
\end_layout
\begin_layout Scrap
+
break
\end_layout
\begin_layout Scrap
+
@
\end_layout
\end_layout
\begin_layout Scrap
+
foo.c:3: `bar' undeclared (first use in this function)
\end_layout
\begin_layout Scrap
+
foo.c:3: (Each undeclared identifier is reported only once
\end_layout
\end_layout
\begin_layout Scrap
+
foo.c:3: for each function it appears in.)
\begin_inset Newline newline
\end_inset
\end_layout
\begin_layout Scrap
+
<<Function Bodies>>=
\end_layout
\begin_layout Scrap
+
def gcc_try(line):
\end_layout
\begin_layout Scrap
+
"""See if line is a gcc error.
Read ahead to handle all the lines.
\end_layout
\end_layout
\begin_layout Scrap
+
Returns 1 on success, 0 otherwise.
Outputs on stdout."""
\end_layout
\begin_layout Scrap
+
retval = 0
\end_layout
\begin_layout Scrap
+
<<Handle the gcc error message>>
\end_layout
\begin_layout Scrap
+
return retval
\end_layout
\end_layout
\begin_layout Scrap
+
@ %def gcc_try
\end_layout
\end_layout
\begin_layout Scrap
+
<<Handle the gcc error message>>=
\begin_inset Newline newline
\end_inset
\end_layout
\begin_layout Scrap
+
<<Accumulate gcc error lines and print it>>=
\end_layout
\begin_layout Scrap
+
num_str = next_line[first_space:num_end]
\end_layout
\begin_layout Scrap
+
msgs = [line[first_space:]]
\end_layout
\begin_layout Scrap
+
msgs.append(next_line[num_end + 1:])
\end_layout
\begin_layout Scrap
+
header_to_see = next_line[:num_end]
\end_layout
\begin_layout Scrap
+
next_line = getline()
\end_layout
\begin_layout Scrap
+
while next_line and next_line[:num_end] == header_to_see:
\end_layout
\begin_layout Scrap
+
msgs.append(next_line[num_end + 1:])
\end_layout
\begin_layout Scrap
+
next_line = getline()
\end_layout
\begin_layout Scrap
+
if next_line: pushline(next_line)
\end_layout
\begin_layout Scrap
+
write_error(msgs, "gcc", int(num_str))
\end_layout
\begin_layout Scrap
+
retval = 1
\end_layout
\begin_layout Scrap
+
@
\end_layout
\end_layout
\begin_layout Scrap
+
<<Function Bodies>>=
\end_layout
\begin_layout Scrap
+
def xlc_try(line):
\end_layout
\begin_layout Scrap
+
"""see if line is an xlc error.
\end_layout
\end_layout
\begin_layout Scrap
+
Returns 1 on success, 0 otherwise.
Outputs on stdout."""
\end_layout
\begin_layout Scrap
+
retval = 0
\end_layout
\begin_layout Scrap
+
if line[0] == '"': # This is the first character of all xlc errors
\end_layout
\begin_layout Scrap
+
next_quote = string.find(line, '"', 1)
\end_layout
\begin_layout Scrap
+
first_space = string.find(line, ' ')
\end_layout
\begin_layout Scrap
+
if (next_quote != -1) and (first_space > next_quote): # no space inisde
quotes
\end_layout
\begin_layout Scrap
+
if line[first_space - 1:first_space + 6] == ", line ":
\end_layout
\begin_layout Scrap
+
num_start = num_end = first_space + 6
\end_layout
\begin_layout Scrap
+
while line[num_end] in string.digits: num_end = num_end + 1
\end_layout
\begin_layout Scrap
+
if num_end > num_start:
\end_layout
\begin_layout Scrap
+
write_error(line, "xlc", int(line[num_start : num_end]))
\end_layout
\begin_layout Scrap
+
retval = 1
\end_layout
\begin_layout Scrap
+
return retval
\end_layout
\begin_layout Scrap
+
\end_layout
\begin_layout Scrap
+
@ %def xlc_try
\end_layout
\end_layout
\begin_layout Scrap
+
<<build-script>>=
\end_layout
\begin_layout Scrap
+
#!/bin/sh
\end_layout
\begin_layout Scrap
+
if [ -z "$NOWEB_SOURCE" ]; then NOWEB_SOURCE=listerrors.nw; fi
\end_layout
\begin_layout Scrap
-notangle -Rlisterrors ${NOWEB_SOURCE} > listerrors
+
+if [ -z "$NOWEB_OUTPUT_DIR" ]; then NOWEB_OUTPUT_DIR=.; fi
\end_layout
\begin_layout Scrap
-chmod +x listerrors
+
+notangle -Rlisterrors ${NOWEB_SOURCE} > ${NOWEB_OUTPUT_DIR}/listerrors
\end_layout
\begin_layout Scrap
+
+chmod +x ${NOWEB_OUTPUT_DIR}/listerrors
+\end_layout
+
+\begin_layout Scrap
+
@
\end_layout