mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-25 02:49:46 +00:00
2318 lines
32 KiB
Plaintext
2318 lines
32 KiB
Plaintext
#LyX 2.4 created this file. For more info see https://www.lyx.org/
|
|
\lyxformat 620
|
|
\begin_document
|
|
\begin_header
|
|
\save_transient_properties true
|
|
\origin /systemlyxdir/examples/Modules/
|
|
\textclass article
|
|
\use_default_options false
|
|
\begin_modules
|
|
noweb
|
|
\end_modules
|
|
\maintain_unincluded_children no
|
|
\language english
|
|
\language_package default
|
|
\inputencoding utf8
|
|
\fontencoding auto
|
|
\font_roman "lmodern" "default"
|
|
\font_sans "default" "default"
|
|
\font_typewriter "default" "default"
|
|
\font_math "auto" "auto"
|
|
\font_default_family default
|
|
\use_non_tex_fonts false
|
|
\font_sc false
|
|
\font_roman_osf false
|
|
\font_sans_osf false
|
|
\font_typewriter_osf false
|
|
\font_sf_scale 100 100
|
|
\font_tt_scale 100 100
|
|
\use_microtype false
|
|
\use_dash_ligatures false
|
|
\graphics default
|
|
\default_output_format default
|
|
\output_sync 0
|
|
\bibtex_command default
|
|
\index_command default
|
|
\paperfontsize default
|
|
\spacing single
|
|
\use_hyperref false
|
|
\papersize default
|
|
\use_geometry false
|
|
\use_package amsmath 1
|
|
\use_package amssymb 1
|
|
\use_package cancel 1
|
|
\use_package esint 1
|
|
\use_package mathdots 1
|
|
\use_package mathtools 1
|
|
\use_package mhchem 1
|
|
\use_package stackrel 1
|
|
\use_package stmaryrd 1
|
|
\use_package undertilde 1
|
|
\cite_engine basic
|
|
\cite_engine_type default
|
|
\biblio_style plain
|
|
\use_bibtopic false
|
|
\use_indices false
|
|
\paperorientation portrait
|
|
\suppress_date true
|
|
\justification true
|
|
\use_refstyle 0
|
|
\use_minted 0
|
|
\use_lineno 0
|
|
\index Index
|
|
\shortcut idx
|
|
\color #008000
|
|
\end_index
|
|
\secnumdepth 3
|
|
\tocdepth 3
|
|
\paragraph_separation indent
|
|
\paragraph_indentation default
|
|
\is_math_indent 0
|
|
\math_numbering_side default
|
|
\quotes_style english
|
|
\dynamic_quotes 0
|
|
\papercolumns 1
|
|
\papersides 1
|
|
\paperpagestyle default
|
|
\tablestyle default
|
|
\tracking_changes false
|
|
\output_changes false
|
|
\change_bars false
|
|
\postpone_fragile_content false
|
|
\html_math_output 0
|
|
\html_css_as_file 0
|
|
\html_be_strict false
|
|
\docbook_table_output 0
|
|
\docbook_mathml_prefix 1
|
|
\end_header
|
|
|
|
\begin_body
|
|
|
|
\begin_layout Title
|
|
\SpecialChar LyX
|
|
and Literate Programming
|
|
\begin_inset Newline newline
|
|
\end_inset
|
|
|
|
An example program
|
|
\end_layout
|
|
|
|
\begin_layout Author
|
|
Edmar Wienskoski Jr.
|
|
\begin_inset Newline newline
|
|
\end_inset
|
|
|
|
edmar-w-jr@technologist.com
|
|
\begin_inset Foot
|
|
status collapsed
|
|
|
|
\begin_layout Plain Layout
|
|
Modified by Bernard Michael Hurley bernardh@westherts.ac.uk —
|
|
- Don't blame Edmar for any errors that have crept in!
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Abstract
|
|
|
|
\series bold
|
|
Note:
|
|
|
|
\series default
|
|
This example program is provided for educational use only.
|
|
The functionality in this C program has been superceded by the equivalent Python code in
|
|
\emph on
|
|
scripts/listerrors
|
|
\emph default
|
|
which should be installed in the \SpecialChar LyX
|
|
scripts directory.
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset CommandInset toc
|
|
LatexCommand tableofcontents
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Section
|
|
Introduction
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
After typesetting a document,
|
|
\SpecialChar LyX
|
|
scans the \SpecialChar LaTeX
|
|
log file looking for errors.
|
|
For each error found,
|
|
the line number is obtained and a error box is displayed in the \SpecialChar LyX
|
|
screen at that position.
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
To use this feature to view compilation errors while working with literate documents,
|
|
we need a program that filters the compilation errors and puts them in a format suitable for \SpecialChar LyX
|
|
reading it.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
In this document we present a filter that recognizes compilation error messages from noweb,
|
|
gnu C,
|
|
and the IBM C compiler (xlc).
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The filter is required to read from standard input,
|
|
parse for error messages and copy the error messages to the standard output.
|
|
During the output process,
|
|
the filter must present the error messages in a format that \SpecialChar LyX
|
|
can interpret,
|
|
currently,
|
|
the \SpecialChar LaTeX
|
|
error message format.
|
|
Of course,
|
|
nothing will prevent future \SpecialChar LyX
|
|
releases from being able to read other formats as well (like gcc error messages for example).
|
|
This mechanism is necessary to fully explore the literate programming tool's capabilities.
|
|
\end_layout
|
|
|
|
\begin_layout Section
|
|
Algorithm
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Function bodies
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
int
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
main (int argc,
|
|
char **argv)
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
{
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (argc == 2) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
switch (argv[1][0]) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
case 'n':
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<Scan input for noweb error messages>>
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
break;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
case 'x':
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<Scan input for xlc error messages>>
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
break;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
case 'a':
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<AIX system using both noweb and xlc>>
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
break;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
case 's':
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
case 'b':
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<Solaris and Linux systems using both noweb and gcc>>
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
break;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
case 'g':
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
default:
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<Scan input for gcc error messages>>
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
break;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
} else {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<Scan input for gcc error messages>>
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Function prototypes
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
int main (int argc,
|
|
char **argv);
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Section
|
|
Data Structures
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
We resort to some global variables to allow access from several different routines.
|
|
These are the buffer and related pointers used during the parse of the input.
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset ERT
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<Global variables>>=
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
char buffer[200][200];
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
int last_buf_line;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
int last_err_line;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
int err_line;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
@
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Section
|
|
The output format
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The output format mimics the \SpecialChar TeX
|
|
error messages format.
|
|
This function prints a number of lines residing in the global variable
|
|
\family typewriter
|
|
buffer
|
|
\family default
|
|
,
|
|
a program name and line number.
|
|
There is no special requirement on the input strings,
|
|
they can be anything.
|
|
\begin_inset Foot
|
|
status collapsed
|
|
|
|
\begin_layout Plain Layout
|
|
This function has been slightly changed from EW's original to make scanning a bit easier with \SpecialChar LaTeX
|
|
::scanLogFile().
|
|
The test has been added because \SpecialChar LyX
|
|
can crash if empty lines are allowed here —
|
|
I can't figure out why!
|
|
—
|
|
BMH
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Function bodies
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
void
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
output_error (int buf_size,
|
|
int error_line,
|
|
char *tool)
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
{
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
int i;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
fprintf(stdout,
|
|
"!
|
|
Build Error:
|
|
==> %s ==>
|
|
\backslash
|
|
n",
|
|
tool);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
fprintf(stdout,
|
|
" ...
|
|
\backslash
|
|
n
|
|
\backslash
|
|
nl.%d ...
|
|
\backslash
|
|
n",
|
|
error_line);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
for (i=0;
|
|
i<buf_size;
|
|
i++)
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (strlen(buffer[i]) != 0)
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
fprintf(stdout,
|
|
"%s",
|
|
buffer[i]);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
fprintf(stdout,
|
|
"
|
|
\backslash
|
|
n");
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Function prototypes
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
void output_error (int buf_size,
|
|
int error_line,
|
|
char *tool);
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Section
|
|
Functions Implementation
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
Both noweave and notangle routines,
|
|
always output one single line for each error found,
|
|
thus to scan the buffer for noweb error messages is enough to exam one input line at a time.
|
|
Note that the noweb software does not provide a line error number,
|
|
so all errors boxes related to noweb messages will be displayed at the beginning of the file.
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Scan input for noweb error messages
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
{
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
last_buf_line = 0;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
while (fgets(buffer[0],
|
|
200,
|
|
stdin)) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (noweb_try(0))
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
output_error(1,
|
|
err_line,
|
|
"noweb");
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The examination itself is very inefficient.
|
|
Unfortunately noweb doesn't have any characteristic that would help to identify one of its error messages.
|
|
The solution is to collect all possible output messages in an array of strings,
|
|
and turn the examination process into a linear search in this array.
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Global variables
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
char *noweb_msgs[] = {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
"couldn't open file",
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
"couldn't open temporary file",
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
"error writing temporary file",
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
"ill-formed option",
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
"unknown option",
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
"Bad format sequence",
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
"Can't open output file",
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
"Can't open temporary file",
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
"Capacity exceeded:",
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
"Ignoring unknown option -",
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
"This can't happen:",
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
"non-numeric line number in"
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
};
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
char *noweb_msgs_mimic_gcc[] = {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
":
|
|
unescaped << in documentation chunk"
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
};
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
A noweb error message can be any string that contains a matching pair of < <
|
|
\begin_inset space ~
|
|
\end_inset
|
|
|
|
|
|
\begin_inset space ~
|
|
\end_inset
|
|
|
|
|
|
\begin_inset space ~
|
|
\end_inset
|
|
|
|
> >,
|
|
or any of the above strings
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset ERT
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<Function bodies>>=
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
int noweb_try (int buf_line)
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
{
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
char *s,
|
|
*t,
|
|
*b;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
int i;
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
b = buffer[buf_line];
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
err_line = 0;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
for (i=0;
|
|
i<1;
|
|
i++) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
s = (char *)strstr (b,
|
|
noweb_msgs_mimic_gcc[i]);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (s != NULL) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
t = (char *)strchr(buffer[buf_line],
|
|
':');
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
err_line = atoi(t+1);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
t = buffer[buf_line];
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
++s;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
while (*(t++) = *(s++));
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
return 1;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
s = (char *)strstr(b,
|
|
"<<");
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (s != NULL) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
s = (char *)strstr(s+2,
|
|
">>");
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (s != NULL) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
return 1;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
} else {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
for (i = 0;
|
|
i < 12;
|
|
++i) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
s = (char *)strstr (b,
|
|
noweb_msgs[i]);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (s != NULL) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
return 1;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
return 0;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
@
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset ERT
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<Function prototypes>>=
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
int noweb_try (int buf_line);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
@
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The xlc compiler always outputs one single line for each error found,
|
|
thus to scan the buffer for xlc error messages it is enough to exam one input line at a time.
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Scan input for xlc error messages
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
{
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
last_buf_line = 0;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
while (fgets(buffer[last_buf_line],
|
|
200,
|
|
stdin)) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (xlc_try(0))
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
output_error(1,
|
|
err_line,
|
|
"xlc");
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\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
|
|
|
|
line
|
|
\begin_inset Quotes erd
|
|
\end_inset
|
|
|
|
,
|
|
a space,
|
|
and some variable text.
|
|
The following routine tests if a given buffer line matches this criteria:
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Function bodies
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
int
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
xlc_try (int buf_line)
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
{
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
char *s,
|
|
*t;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
t = buffer[buf_line];
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
s = t+1;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
while (*s != '"' && *s != ' ' && *s != '
|
|
\backslash
|
|
0')
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
s++;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (*t != '"' || *s != '"' || strncmp(s+1,
|
|
",
|
|
line ",
|
|
7) != 0)
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
return 0;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
s += 8;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
err_line = atoi(s);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
return 1;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Function prototypes
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
int xlc_try (int buf_line);
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The gcc compiler error messages are more complicated to scan.
|
|
Each error can span more than one line in the buffer.
|
|
The good news is that every buffer line on each error has the same pattern,
|
|
and share the same line number.
|
|
Thus the strategy will be to accumulate lines in the buffer while the reported line number is still the same.
|
|
At the time they differ,
|
|
all the accumulated lines,
|
|
except the last one,
|
|
will belong to one single error message,
|
|
which now can be output-ed to \SpecialChar LyX
|
|
.
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
Every gcc error message contains a string with no space followed by a
|
|
\begin_inset Quotes eld
|
|
\end_inset
|
|
|
|
:
|
|
\begin_inset Quotes eld
|
|
\end_inset
|
|
|
|
.
|
|
If the next character is a space,
|
|
then this line is a header of a error message and the next line will detail the line number of the source code where the error was found.
|
|
Otherwise,
|
|
the next thing is a integer number followed by another
|
|
\begin_inset Quotes eld
|
|
\end_inset
|
|
|
|
:
|
|
\begin_inset Quotes eld
|
|
\end_inset
|
|
|
|
.
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Scan input for gcc error messages
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
{
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
char *s,
|
|
*t;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
last_buf_line = 0;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
while (fgets(buffer[last_buf_line],
|
|
200,
|
|
stdin)) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
/****** Skip lines until I find an error */
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
s = (char *)strpbrk(buffer[last_buf_line],
|
|
" :");
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (s == NULL || *s == ' ')
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
continue;
|
|
/* No gcc error found here */
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
do {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<gcc error message criteria is to find a "...:999:" or a "...:
|
|
">>
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
/****** OK It is an error message,
|
|
get line number */
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
err_line = atoi(s+1);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (last_err_line == 0 || last_err_line == err_line) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
last_err_line = err_line;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
continue;
|
|
/* It's either a header or a continuation,
|
|
don't output yet */
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
/****** Completed the scan of one error message,
|
|
output it to LyX */
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
discharge_buffer(1);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
break;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
} while (fgets(buffer[last_buf_line],
|
|
200,
|
|
stdin));
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
/****** EOF completes the scan of whatever was being scanned */
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
discharge_buffer(0);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
gcc error message criteria is to find a "...:999:" or a "...:
|
|
"
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
/****** Search first ":" in the error number */
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
s = (char *)strpbrk(buffer[last_buf_line],
|
|
" :");
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
last_buf_line++;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (s == NULL || *s == ' ')
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<No gcc error found here,
|
|
but it might terminate the scanning of a previous one>>
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
/****** Search second ":" in the error number */
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
t = (char *)strpbrk(s+1,
|
|
" :");if (t == NULL || *t == ' ') <<No gcc error found here,
|
|
but it might terminate the scanning of a previous one>>/****** Verify if is all digits between ":" */if (t != s+1+strspn(s+1,
|
|
"0123456789")) <<No gcc error found here,
|
|
but it might terminate the scanning of a previous one>>@
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<No gcc error found here,
|
|
but it might terminate the scanning of a previous one>>=
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
{
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
err_line = 0;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
discharge_buffer(1);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
continue;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
As we mentioned,
|
|
when the scan of one gcc error message is completed everything in the buffer except the last line is one single error message.
|
|
But if the scan terminates with a EOF or through finding one line that does not match the gcc error message criteria,
|
|
then there is no
|
|
\begin_inset Quotes eld
|
|
\end_inset
|
|
|
|
last line
|
|
\begin_inset Quotes erd
|
|
\end_inset
|
|
|
|
in the buffer to be concerned with.
|
|
In those cases we empty the buffer completely.
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Function bodies
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
void
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
discharge_buffer (int save_last)
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
{
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (last_err_line != 0) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
clean_gcc_messages();
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (save_last != 0) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
output_error(last_buf_line-1,
|
|
last_err_line,
|
|
"gcc");
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
strcpy (buffer[0],
|
|
buffer[last_buf_line-1]);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
last_err_line = err_line;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
last_buf_line = 1;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
} else {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
++last_buf_line;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
clean_gcc_messages();
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
output_error(last_buf_line-1,
|
|
last_err_line,
|
|
"gcc");
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
last_err_line = 0;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
last_buf_line = 0;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Function prototypes
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
void discharge_buffer (int save_last);
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The next function
|
|
\begin_inset Quotes eld
|
|
\end_inset
|
|
|
|
cleans
|
|
\begin_inset Quotes erd
|
|
\end_inset
|
|
|
|
superfluous information from gcc messages,
|
|
namely the name of the noweb file and the line number of the Error.
|
|
\begin_inset Foot
|
|
status collapsed
|
|
|
|
\begin_layout Plain Layout
|
|
More could be done.
|
|
For instance,
|
|
some way of distinguishing between gcc Errors and Warnings should be devised.
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Function bodies
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
void
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
clean_gcc_messages ()
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
{
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
int index;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
char search [30];
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
char *tail,
|
|
*head;
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
int search_len = sprintf(search,
|
|
".nw:%d:",
|
|
last_err_line);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
for (index = 0;
|
|
index < last_buf_line-1;
|
|
index++) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
tail = (char *)strstr (buffer[index],
|
|
search);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if ( tail == NULL) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
tail = (char *) strstr (buffer[index],
|
|
".nw:");
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (tail) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
tail += 4;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
} else {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
tail += search_len;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (tail != NULL) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
head = buffer[index];
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
while (*(head++) = *(tail++));
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Function prototypes
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
void clean_gcc_messages ();
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
To combine the scan of noweb error messages and xlc error messages is very simple.
|
|
We just try each one for every input line:
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset ERT
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<AIX system using both noweb and xlc>>=
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
{
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
last_buf_line = 0;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
while (fgets(buffer[0],
|
|
200,
|
|
stdin)) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (noweb_try(0))
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
output_error(1,
|
|
err_line,
|
|
"noweb");
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
else if (xlc_try(0))
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
output_error(1,
|
|
err_line,
|
|
"xlc");
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
@
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
To combine the scan of noweb error messages and gcc error messages is simple if we realize that it is not possible to find a noweb error message in the middle of a gcc error message.
|
|
So we just repeat the gcc procedure and test for noweb error messages in the beginning of the scan:
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
Solaris and Linux systems using both noweb and gcc
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
{
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
char *s,
|
|
*t;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
last_buf_line = 0;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
while (fgets(buffer[last_buf_line],
|
|
200,
|
|
stdin)) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
/****** Skip lines until I find an error */
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (last_buf_line == 0 && noweb_try(0)) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
output_error(1,
|
|
err_line,
|
|
"noweb");
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
continue;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
s = (char *)strpbrk(buffer[last_buf_line],
|
|
" :");
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (s == NULL || *s == ' ')
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
continue;
|
|
/* No gcc error found here */
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
do {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<gcc error message criteria is to find a "...:999:" or a "...:
|
|
">>
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
/****** OK It is an error,
|
|
get line number */
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
err_line = atoi(s+1);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if (last_err_line == 0 || last_err_line == err_line) {
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
last_err_line = err_line;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
continue;
|
|
/* It's either a header or a continuation,
|
|
don't output yet */
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
/****** Completed the scan of one error message,
|
|
output it to LyX */
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
discharge_buffer(1);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
break;
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
} while (fgets(buffer[last_buf_line],
|
|
200,
|
|
stdin));
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
/****** EOF completes the scan of whatever was being scanned */
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
discharge_buffer(0);
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
}
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Section
|
|
Wrapping the code into a file
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
listerrors.c
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
#include <stdio.h>
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
#include <strings.h>
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<Global variables>>
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<Function prototypes>>
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
<<Function bodies>>
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
To build this program,
|
|
we want to add the
|
|
\begin_inset Quotes eld
|
|
\end_inset
|
|
|
|
-L
|
|
\begin_inset Quotes erd
|
|
\end_inset
|
|
|
|
option in the tangle command to force gdb to load the file
|
|
\family typewriter
|
|
Literate.nw
|
|
\family default
|
|
instead of
|
|
\family typewriter
|
|
listerrors.c
|
|
\family default
|
|
.
|
|
In accordance with this,
|
|
we pass the
|
|
\begin_inset Quotes eld
|
|
\end_inset
|
|
|
|
-g
|
|
\begin_inset Quotes erd
|
|
\end_inset
|
|
|
|
option to gcc.
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Flex Chunk
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
\begin_inset Argument 1
|
|
status open
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
build-script
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
#!/bin/sh
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if [ -z "$NOWEB_SOURCE" ];
|
|
then NOWEB_SOURCE=Literate.nw;
|
|
fi
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
if [ -z "$NOWEB_OUTPUT_DIR" ];
|
|
then NOWEB_OUTPUT_DIR=.;
|
|
fi
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
notangle -L -Rlisterrors.c ${NOWEB_SOURCE} > ${NOWEB_OUTPUT_DIR}/listerrors.c
|
|
\end_layout
|
|
|
|
\begin_layout Plain Layout
|
|
|
|
gcc -g -o listerrors listerrors.c
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
This project can be tangled and compiled from \SpecialChar LyX
|
|
if you set
|
|
\family typewriter
|
|
|
|
\backslash
|
|
build_command
|
|
\family default
|
|
to call a generic script that always extracts a chunk named
|
|
\family typewriter
|
|
build-script
|
|
\family default
|
|
and executes it.
|
|
Here is a example of such generic script:
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
#!/bin/sh
|
|
\begin_inset Newline newline
|
|
\end_inset
|
|
|
|
notangle -Rbuild-script $1 | env NOWEB_SOURCE=$1 NOWEB_OUTPUT_DIR=$r sh
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
\end_layout
|
|
|
|
\end_body
|
|
\end_document
|