1 #LyX 2.2 created this file. For more info see http://www.lyx.org/
5 \origin /systemlyxdir/examples/
7 \use_default_options false
11 \maintain_unincluded_children false
13 \language_package default
14 \inputencoding default
16 \font_roman "default" "default"
17 \font_sans "default" "default"
18 \font_typewriter "default" "default"
19 \font_math "auto" "auto"
20 \font_default_family default
21 \use_non_tex_fonts false
24 \font_sf_scale 100 100
25 \font_tt_scale 100 100
27 \default_output_format default
29 \bibtex_command default
30 \index_command default
31 \paperfontsize default
36 \use_package amsmath 0
37 \use_package amssymb 0
40 \use_package mathdots 1
41 \use_package mathtools 0
43 \use_package stackrel 0
44 \use_package stmaryrd 0
45 \use_package undertilde 0
47 \cite_engine_type default
51 \paperorientation portrait
61 \paragraph_separation indent
62 \paragraph_indentation default
63 \quotes_language english
66 \paperpagestyle default
67 \tracking_changes false
77 \SpecialCharNoPassThru LyX
78 and Literate Programming
79 \begin_inset Newline newline
87 \begin_inset Newline newline
90 edmar-w-jr@technologist.com
94 \begin_layout Plain Layout
95 Modified by Bernard Michael Hurley bernardh@westherts.ac.uk \threehyphens
97 Edmar for any errors that have crept in!
105 \begin_layout Abstract
110 This example program is provided for educational use only.
111 The functionality in this C program has been superceded by the equivalent
114 examples/listerrors.lyx
116 which should be installed in the \SpecialCharNoPassThru LyX
124 \begin_layout Plain Layout
136 \begin_layout Standard
137 \begin_inset CommandInset toc
138 LatexCommand tableofcontents
145 \begin_layout Section
149 \begin_layout Standard
150 After typesetting a document, \SpecialCharNoPassThru LyX
151 scans the \SpecialCharNoPassThru LaTeX
152 log file looking for errors.
153 For each error found, the line number is obtained and a error box is displayed
154 in the \SpecialCharNoPassThru LyX
155 screen at that position.
158 \begin_layout Standard
159 To use this feature to view compilation errors while working with literate
160 documents, we need a program that filters the compilation errors and puts
161 them in a format suitable for \SpecialCharNoPassThru LyX
166 \begin_layout Standard
167 In this document we present a filter that recognizes compilation error messages
168 from noweb, gnu C, and the IBM C compiler (xlc).
171 \begin_layout Standard
172 The filter is required to read from standard input, parse for error messages
173 and copy the error messages to the standard output.
174 During the output process, the filter must present the error messages in
175 a format that \SpecialCharNoPassThru LyX
176 can interpret, currently, the \SpecialCharNoPassThru LaTeX
177 error message format.
178 Of course, nothing will prevent future \SpecialCharNoPassThru LyX
179 releases from being able to
180 read other formats as well (like gcc error messages for example).
181 This mechanism is necessary to fully explore the literate programming tool's
185 \begin_layout Section
189 \begin_layout Standard
190 \begin_inset Flex Chunk
193 \begin_layout Plain Layout
195 \begin_inset Argument 1
198 \begin_layout Plain Layout
207 \begin_layout Plain Layout
209 main (int argc, char **argv)
212 \begin_layout Plain Layout
217 \begin_layout Plain Layout
222 \begin_layout Plain Layout
224 switch (argv[1][0]) {
227 \begin_layout Plain Layout
232 \begin_layout Plain Layout
234 <<Scan input for noweb error messages>>
237 \begin_layout Plain Layout
242 \begin_layout Plain Layout
247 \begin_layout Plain Layout
249 <<Scan input for xlc error messages>>
252 \begin_layout Plain Layout
257 \begin_layout Plain Layout
262 \begin_layout Plain Layout
264 <<AIX system using both noweb and xlc>>
267 \begin_layout Plain Layout
272 \begin_layout Plain Layout
277 \begin_layout Plain Layout
282 \begin_layout Plain Layout
284 <<Solaris and Linux systems using both noweb and gcc>>
287 \begin_layout Plain Layout
292 \begin_layout Plain Layout
297 \begin_layout Plain Layout
302 \begin_layout Plain Layout
304 <<Scan input for gcc error messages>>
307 \begin_layout Plain Layout
312 \begin_layout Plain Layout
317 \begin_layout Plain Layout
322 \begin_layout Plain Layout
324 <<Scan input for gcc error messages>>
327 \begin_layout Plain Layout
332 \begin_layout Plain Layout
342 \begin_layout Standard
343 \begin_inset Flex Chunk
346 \begin_layout Plain Layout
348 \begin_inset Argument 1
351 \begin_layout Plain Layout
357 int main (int argc, char **argv);
365 \begin_layout Section
369 \begin_layout Standard
370 We resort to some global variables to allow access from several different
372 These are the buffer and related pointers used during the parse of the
376 \begin_layout Standard
380 \begin_layout Plain Layout
382 <<Global variables>>=
385 \begin_layout Plain Layout
387 char buffer[200][200];
390 \begin_layout Plain Layout
395 \begin_layout Plain Layout
400 \begin_layout Plain Layout
410 \begin_layout Section
414 \begin_layout Standard
415 The output format mimics the \SpecialCharNoPassThru TeX
416 error messages format.
417 This function prints a number of lines residing in the global variable
422 , a program name and line number.
423 There is no special requirement on the input strings, they can be anything.
427 \begin_layout Plain Layout
428 This function has been slightly changed from EW's original to make scanning
429 a bit easier with \SpecialCharNoPassThru LaTeX
431 The test has been added because \SpecialCharNoPassThru LyX
432 can crash if empty lines are allowed
434 I can't figure out why! \threehyphens
443 \begin_layout Standard
444 \begin_inset Flex Chunk
447 \begin_layout Plain Layout
449 \begin_inset Argument 1
452 \begin_layout Plain Layout
461 \begin_layout Plain Layout
463 output_error (int buf_size, int error_line, char *tool)
466 \begin_layout Plain Layout
471 \begin_layout Plain Layout
476 \begin_layout Plain Layout
481 \begin_layout Plain Layout
483 fprintf(stdout, "! Build Error: ==> %s ==>
488 \begin_layout Plain Layout
490 fprintf(stdout, " ...
499 \begin_layout Plain Layout
504 \begin_layout Plain Layout
506 for (i=0; i<buf_size; i++)
509 \begin_layout Plain Layout
511 if (strlen(buffer[i]) != 0)
514 \begin_layout Plain Layout
516 fprintf(stdout, "%s", buffer[i]);
519 \begin_layout Plain Layout
524 \begin_layout Plain Layout
531 \begin_layout Plain Layout
541 \begin_layout Standard
542 \begin_inset Flex Chunk
545 \begin_layout Plain Layout
547 \begin_inset Argument 1
550 \begin_layout Plain Layout
556 void output_error (int buf_size, int error_line, char *tool);
564 \begin_layout Section
565 Functions Implementation
568 \begin_layout Standard
569 Both noweave and notangle routines, always output one single line for each
570 error found, thus to scan the buffer for noweb error messages is enough
571 to exam one input line at a time.
572 Note that the noweb software does not provide a line error number, so all
573 errors boxes related to noweb messages will be displayed at the beginning
577 \begin_layout Standard
578 \begin_inset Flex Chunk
581 \begin_layout Plain Layout
583 \begin_inset Argument 1
586 \begin_layout Plain Layout
587 Scan input for noweb error messages
595 \begin_layout Plain Layout
600 \begin_layout Plain Layout
602 while (fgets(buffer[0], 200, stdin)) {
605 \begin_layout Plain Layout
610 \begin_layout Plain Layout
612 output_error(1, err_line, "noweb");
615 \begin_layout Plain Layout
620 \begin_layout Plain Layout
630 \begin_layout Standard
631 The examination itself is very inefficient.
632 Unfortunately noweb doesn't have any characteristic that would help to
633 identify one of its error messages.
634 The solution is to collect all possible output messages in an array of
635 strings, and turn the examination process into a linear search in this
639 \begin_layout Standard
640 \begin_inset Flex Chunk
643 \begin_layout Plain Layout
647 \begin_layout Plain Layout
649 <<Global variables>>=
652 \begin_layout Plain Layout
654 char *noweb_msgs[] = {
657 \begin_layout Plain Layout
659 "couldn't open file",
662 \begin_layout Plain Layout
664 "couldn't open temporary file",
667 \begin_layout Plain Layout
669 "error writing temporary file",
672 \begin_layout Plain Layout
677 \begin_layout Plain Layout
682 \begin_layout Plain Layout
684 "Bad format sequence",
687 \begin_layout Plain Layout
689 "Can't open output file",
692 \begin_layout Plain Layout
694 "Can't open temporary file",
697 \begin_layout Plain Layout
699 "Capacity exceeded:",
702 \begin_layout Plain Layout
704 "Ignoring unknown option -",
707 \begin_layout Plain Layout
709 "This can't happen:",
712 \begin_layout Plain Layout
714 "non-numeric line number in"
717 \begin_layout Plain Layout
722 \begin_layout Plain Layout
726 \begin_layout Plain Layout
728 char *noweb_msgs_mimic_gcc[] = {
731 \begin_layout Plain Layout
733 ": unescaped << in documentation chunk"
736 \begin_layout Plain Layout
746 \begin_layout Standard
747 A noweb error message can be any string that contains a matching pair of
760 > >, or any of the above strings
763 \begin_layout Standard
767 \begin_layout Plain Layout
772 \begin_layout Plain Layout
774 int noweb_try (int buf_line)
777 \begin_layout Plain Layout
782 \begin_layout Plain Layout
787 \begin_layout Plain Layout
792 \begin_layout Plain Layout
796 \begin_layout Plain Layout
798 b = buffer[buf_line];
801 \begin_layout Plain Layout
806 \begin_layout Plain Layout
810 \begin_layout Plain Layout
812 for (i=0; i<1; i++) {
815 \begin_layout Plain Layout
817 s = (char *)strstr (b, noweb_msgs_mimic_gcc[i]);
820 \begin_layout Plain Layout
825 \begin_layout Plain Layout
827 t = (char *)strchr(buffer[buf_line], ':');
830 \begin_layout Plain Layout
832 err_line = atoi(t+1);
835 \begin_layout Plain Layout
837 t = buffer[buf_line];
840 \begin_layout Plain Layout
845 \begin_layout Plain Layout
847 while (*(t++) = *(s++));
850 \begin_layout Plain Layout
855 \begin_layout Plain Layout
860 \begin_layout Plain Layout
865 \begin_layout Plain Layout
867 s = (char *)strstr(b, "<<");
870 \begin_layout Plain Layout
875 \begin_layout Plain Layout
877 s = (char *)strstr(s+2, ">>");
880 \begin_layout Plain Layout
885 \begin_layout Plain Layout
890 \begin_layout Plain Layout
895 \begin_layout Plain Layout
900 \begin_layout Plain Layout
902 for (i = 0; i < 12; ++i) {
905 \begin_layout Plain Layout
907 s = (char *)strstr (b, noweb_msgs[i]);
910 \begin_layout Plain Layout
915 \begin_layout Plain Layout
920 \begin_layout Plain Layout
925 \begin_layout Plain Layout
930 \begin_layout Plain Layout
935 \begin_layout Plain Layout
940 \begin_layout Plain Layout
945 \begin_layout Plain Layout
955 \begin_layout Standard
959 \begin_layout Plain Layout
961 <<Function prototypes>>=
964 \begin_layout Plain Layout
966 int noweb_try (int buf_line);
969 \begin_layout Plain Layout
979 \begin_layout Standard
980 The xlc compiler always outputs one single line for each error found, thus
981 to scan the buffer for xlc error messages it is enough to exam one input
985 \begin_layout Standard
986 \begin_inset Flex Chunk
989 \begin_layout Plain Layout
991 \begin_inset Argument 1
994 \begin_layout Plain Layout
995 Scan input for xlc error messages
1003 \begin_layout Plain Layout
1008 \begin_layout Plain Layout
1010 while (fgets(buffer[last_buf_line], 200, stdin)) {
1013 \begin_layout Plain Layout
1018 \begin_layout Plain Layout
1020 output_error(1, err_line, "xlc");
1023 \begin_layout Plain Layout
1028 \begin_layout Plain Layout
1038 \begin_layout Standard
1039 A xlc error message is easy to identify.
1040 Every error message starts with a quoted string with no spaces, a comma,
1042 \begin_inset Quotes eld
1046 \begin_inset Quotes erd
1049 , a space, and some variable text.
1050 The following routine tests if a given buffer line matches this criteria:
1053 \begin_layout Standard
1054 \begin_inset Flex Chunk
1057 \begin_layout Plain Layout
1061 \begin_layout Plain Layout
1065 \begin_layout Plain Layout
1067 <<Function bodies>>=
1070 \begin_layout Plain Layout
1075 \begin_layout Plain Layout
1077 xlc_try (int buf_line)
1080 \begin_layout Plain Layout
1085 \begin_layout Plain Layout
1090 \begin_layout Plain Layout
1095 \begin_layout Plain Layout
1097 t = buffer[buf_line];
1100 \begin_layout Plain Layout
1105 \begin_layout Plain Layout
1107 while (*s != '"' && *s != ' ' && *s != '
1112 \begin_layout Plain Layout
1117 \begin_layout Plain Layout
1119 if (*t != '"' || *s != '"' || strncmp(s+1, ", line ", 7) != 0)
1122 \begin_layout Plain Layout
1127 \begin_layout Plain Layout
1132 \begin_layout Plain Layout
1137 \begin_layout Plain Layout
1142 \begin_layout Plain Layout
1152 \begin_layout Standard
1153 \begin_inset Flex Chunk
1156 \begin_layout Plain Layout
1158 \begin_inset Argument 1
1161 \begin_layout Plain Layout
1167 int xlc_try (int buf_line);
1175 \begin_layout Standard
1176 The gcc compiler error messages are more complicated to scan.
1177 Each error can span more than one line in the buffer.
1178 The good news is that every buffer line on each error has the same pattern,
1179 and share the same line number.
1180 Thus the strategy will be to accumulate lines in the buffer while the reported
1181 line number is still the same.
1182 At the time they differ, all the accumulated lines, except the last one,
1183 will belong to one single error message, which now can be output-ed to
1184 \SpecialCharNoPassThru LyX
1188 \begin_layout Standard
1189 Every gcc error message contains a string with no space followed by a
1190 \begin_inset Quotes eld
1194 \begin_inset Quotes eld
1198 If the next character is a space, then this line is a header of a error
1199 message and the next line will detail the line number of the source code
1200 where the error was found.
1201 Otherwise, the next thing is a integer number followed by another
1202 \begin_inset Quotes eld
1206 \begin_inset Quotes eld
1212 \begin_layout Standard
1213 \begin_inset Flex Chunk
1216 \begin_layout Plain Layout
1218 \begin_inset Argument 1
1221 \begin_layout Plain Layout
1222 Scan input for gcc error messages
1230 \begin_layout Plain Layout
1235 \begin_layout Plain Layout
1240 \begin_layout Plain Layout
1245 \begin_layout Plain Layout
1247 while (fgets(buffer[last_buf_line], 200, stdin)) {
1250 \begin_layout Plain Layout
1252 /****** Skip lines until I find an error */
1255 \begin_layout Plain Layout
1257 s = (char *)strpbrk(buffer[last_buf_line], " :");
1260 \begin_layout Plain Layout
1262 if (s == NULL || *s == ' ')
1265 \begin_layout Plain Layout
1267 continue; /* No gcc error found here */
1270 \begin_layout Plain Layout
1275 \begin_layout Plain Layout
1277 <<gcc error message criteria is to find a "...:999:" or a "...: ">>
1280 \begin_layout Plain Layout
1282 /****** OK It is an error message, get line number */
1285 \begin_layout Plain Layout
1287 err_line = atoi(s+1);
1290 \begin_layout Plain Layout
1292 if (last_err_line == 0 || last_err_line == err_line) {
1295 \begin_layout Plain Layout
1297 last_err_line = err_line;
1300 \begin_layout Plain Layout
1302 continue; /* It's either a header or a continuation, don't output
1306 \begin_layout Plain Layout
1311 \begin_layout Plain Layout
1313 /****** Completed the scan of one error message, output it to \SpecialCharNoPassThru LyX
1317 \begin_layout Plain Layout
1319 discharge_buffer(1);
1322 \begin_layout Plain Layout
1327 \begin_layout Plain Layout
1329 } while (fgets(buffer[last_buf_line], 200, stdin));
1332 \begin_layout Plain Layout
1337 \begin_layout Plain Layout
1339 /****** EOF completes the scan of whatever was being scanned */
1342 \begin_layout Plain Layout
1344 discharge_buffer(0);
1347 \begin_layout Plain Layout
1357 \begin_layout Standard
1358 \begin_inset Flex Chunk
1361 \begin_layout Plain Layout
1363 \begin_inset Argument 1
1366 \begin_layout Plain Layout
1367 gcc error message criteria is to find a "...:999:" or a "...: "
1372 /****** Search first ":" in the error number */
1375 \begin_layout Plain Layout
1377 s = (char *)strpbrk(buffer[last_buf_line], " :");
1380 \begin_layout Plain Layout
1385 \begin_layout Plain Layout
1387 if (s == NULL || *s == ' ')
1390 \begin_layout Plain Layout
1392 <<No gcc error found here, but it might terminate the scanning of a previous
1396 \begin_layout Plain Layout
1398 /****** Search second ":" in the error number */
1401 \begin_layout Plain Layout
1403 t = (char *)strpbrk(s+1, " :");if (t == NULL || *t == ' ') <<No gcc error
1404 found here, but it might terminate the scanning of a previous one>>/******
1405 Verify if is all digits between ":" */if (t != s+1+strspn(s+1, "0123456789"))
1406 <<No gcc error found here, but it might terminate the scanning of a previous
1410 \begin_layout Plain Layout
1414 \begin_layout Plain Layout
1418 \begin_layout Plain Layout
1420 <<No gcc error found here, but it might terminate the scanning of a previous
1424 \begin_layout Plain Layout
1429 \begin_layout Plain Layout
1434 \begin_layout Plain Layout
1436 discharge_buffer(1);
1439 \begin_layout Plain Layout
1444 \begin_layout Plain Layout
1454 \begin_layout Standard
1455 As we mentioned, when the scan of one gcc error message is completed everything
1456 in the buffer except the last line is one single error message.
1457 But if the scan terminates with a EOF or through finding one line that
1458 does not match the gcc error message criteria, then there is no
1459 \begin_inset Quotes eld
1463 \begin_inset Quotes erd
1466 in the buffer to be concerned with.
1467 In those cases we empty the buffer completely.
1470 \begin_layout Standard
1471 \begin_inset Flex Chunk
1474 \begin_layout Plain Layout
1478 \begin_layout Plain Layout
1482 \begin_layout Plain Layout
1484 <<Function bodies>>=
1487 \begin_layout Plain Layout
1492 \begin_layout Plain Layout
1494 discharge_buffer (int save_last)
1497 \begin_layout Plain Layout
1502 \begin_layout Plain Layout
1504 if (last_err_line != 0) {
1507 \begin_layout Plain Layout
1509 clean_gcc_messages();
1512 \begin_layout Plain Layout
1514 if (save_last != 0) {
1517 \begin_layout Plain Layout
1519 output_error(last_buf_line-1, last_err_line, "gcc");
1522 \begin_layout Plain Layout
1524 strcpy (buffer[0], buffer[last_buf_line-1]);
1527 \begin_layout Plain Layout
1529 last_err_line = err_line;
1532 \begin_layout Plain Layout
1537 \begin_layout Plain Layout
1542 \begin_layout Plain Layout
1547 \begin_layout Plain Layout
1549 clean_gcc_messages();
1552 \begin_layout Plain Layout
1554 output_error(last_buf_line-1, last_err_line, "gcc");
1557 \begin_layout Plain Layout
1562 \begin_layout Plain Layout
1567 \begin_layout Plain Layout
1572 \begin_layout Plain Layout
1577 \begin_layout Plain Layout
1587 \begin_layout Standard
1588 \begin_inset Flex Chunk
1591 \begin_layout Plain Layout
1593 \begin_inset Argument 1
1596 \begin_layout Plain Layout
1602 void discharge_buffer (int save_last);
1610 \begin_layout Standard
1612 \begin_inset Quotes eld
1616 \begin_inset Quotes erd
1619 superfluous information from gcc messages, namely the name of the noweb
1620 file and the line number of the Error.
1624 \begin_layout Plain Layout
1626 For instance, some way of distinguishing between gcc Errors and Warnings
1635 \begin_layout Standard
1636 \begin_inset Flex Chunk
1639 \begin_layout Plain Layout
1641 \begin_inset Argument 1
1644 \begin_layout Plain Layout
1653 \begin_layout Plain Layout
1655 clean_gcc_messages ()
1658 \begin_layout Plain Layout
1663 \begin_layout Plain Layout
1668 \begin_layout Plain Layout
1673 \begin_layout Plain Layout
1678 \begin_layout Plain Layout
1680 int search_len = sprintf(search, ".nw:%d:", last_err_line);
1683 \begin_layout Plain Layout
1688 \begin_layout Plain Layout
1690 for (index = 0; index < last_buf_line-1; index++) {
1693 \begin_layout Plain Layout
1695 tail = (char *)strstr (buffer[index], search);
1698 \begin_layout Plain Layout
1700 if ( tail == NULL) {
1703 \begin_layout Plain Layout
1705 tail = (char *) strstr (buffer[index], ".nw:");
1708 \begin_layout Plain Layout
1713 \begin_layout Plain Layout
1718 \begin_layout Plain Layout
1723 \begin_layout Plain Layout
1728 \begin_layout Plain Layout
1733 \begin_layout Plain Layout
1738 \begin_layout Plain Layout
1743 \begin_layout Plain Layout
1745 head = buffer[index];
1748 \begin_layout Plain Layout
1750 while (*(head++) = *(tail++));
1753 \begin_layout Plain Layout
1758 \begin_layout Plain Layout
1763 \begin_layout Plain Layout
1773 \begin_layout Standard
1774 \begin_inset Flex Chunk
1777 \begin_layout Plain Layout
1779 \begin_inset Argument 1
1782 \begin_layout Plain Layout
1788 void clean_gcc_messages ();
1796 \begin_layout Standard
1797 To combine the scan of noweb error messages and xlc error messages is very
1799 We just try each one for every input line:
1802 \begin_layout Standard
1806 \begin_layout Plain Layout
1808 <<AIX system using both noweb and xlc>>=
1811 \begin_layout Plain Layout
1816 \begin_layout Plain Layout
1821 \begin_layout Plain Layout
1823 while (fgets(buffer[0], 200, stdin)) {
1826 \begin_layout Plain Layout
1831 \begin_layout Plain Layout
1833 output_error(1, err_line, "noweb");
1836 \begin_layout Plain Layout
1838 else if (xlc_try(0))
1841 \begin_layout Plain Layout
1843 output_error(1, err_line, "xlc");
1846 \begin_layout Plain Layout
1851 \begin_layout Plain Layout
1856 \begin_layout Plain Layout
1866 \begin_layout Standard
1867 To combine the scan of noweb error messages and gcc error messages is simple
1868 if we realize that it is not possible to find a noweb error message in
1869 the middle of a gcc error message.
1870 So we just repeat the gcc procedure and test for noweb error messages in
1871 the beginning of the scan:
1874 \begin_layout Standard
1875 \begin_inset Flex Chunk
1878 \begin_layout Plain Layout
1880 \begin_inset Argument 1
1883 \begin_layout Plain Layout
1884 Solaris and Linux systems using both noweb and gcc
1892 \begin_layout Plain Layout
1897 \begin_layout Plain Layout
1902 \begin_layout Plain Layout
1907 \begin_layout Plain Layout
1909 while (fgets(buffer[last_buf_line], 200, stdin)) {
1912 \begin_layout Plain Layout
1914 /****** Skip lines until I find an error */
1917 \begin_layout Plain Layout
1919 if (last_buf_line == 0 && noweb_try(0)) {
1922 \begin_layout Plain Layout
1924 output_error(1, err_line, "noweb");
1927 \begin_layout Plain Layout
1932 \begin_layout Plain Layout
1937 \begin_layout Plain Layout
1939 s = (char *)strpbrk(buffer[last_buf_line], " :");
1942 \begin_layout Plain Layout
1944 if (s == NULL || *s == ' ')
1947 \begin_layout Plain Layout
1949 continue; /* No gcc error found here */
1952 \begin_layout Plain Layout
1957 \begin_layout Plain Layout
1959 <<gcc error message criteria is to find a "...:999:" or a "...: ">>
1962 \begin_layout Plain Layout
1964 /****** OK It is an error, get line number */
1967 \begin_layout Plain Layout
1969 err_line = atoi(s+1);
1972 \begin_layout Plain Layout
1974 if (last_err_line == 0 || last_err_line == err_line) {
1977 \begin_layout Plain Layout
1979 last_err_line = err_line;
1982 \begin_layout Plain Layout
1984 continue; /* It's either a header or a continuation, don't output
1988 \begin_layout Plain Layout
1993 \begin_layout Plain Layout
1995 /****** Completed the scan of one error message, output it to \SpecialCharNoPassThru LyX
1999 \begin_layout Plain Layout
2001 discharge_buffer(1);
2004 \begin_layout Plain Layout
2009 \begin_layout Plain Layout
2011 } while (fgets(buffer[last_buf_line], 200, stdin));
2014 \begin_layout Plain Layout
2019 \begin_layout Plain Layout
2021 /****** EOF completes the scan of whatever was being scanned */
2024 \begin_layout Plain Layout
2026 discharge_buffer(0);
2029 \begin_layout Plain Layout
2039 \begin_layout Section
2040 Wrapping the code into a file
2043 \begin_layout Standard
2044 \begin_inset Flex Chunk
2047 \begin_layout Plain Layout
2049 \begin_inset Argument 1
2052 \begin_layout Plain Layout
2061 \begin_layout Plain Layout
2063 #include <strings.h>
2066 \begin_layout Plain Layout
2071 \begin_layout Plain Layout
2073 <<Global variables>>
2076 \begin_layout Plain Layout
2078 <<Function prototypes>>
2081 \begin_layout Plain Layout
2091 \begin_layout Standard
2092 To build this program, we want to add the
2093 \begin_inset Quotes eld
2097 \begin_inset Quotes erd
2100 option in the tangle command to force gdb to load the file
2109 In accordance with this, we pass the
2110 \begin_inset Quotes eld
2114 \begin_inset Quotes erd
2120 \begin_layout Standard
2121 \begin_inset Flex Chunk
2124 \begin_layout Plain Layout
2126 \begin_inset Argument 1
2129 \begin_layout Plain Layout
2138 \begin_layout Plain Layout
2140 if [ -z "$NOWEB_SOURCE" ]; then NOWEB_SOURCE=Literate.nw; fi
2143 \begin_layout Plain Layout
2145 if [ -z "$NOWEB_OUTPUT_DIR" ]; then NOWEB_OUTPUT_DIR=.; fi
2148 \begin_layout Plain Layout
2150 notangle -L -Rlisterrors.c ${NOWEB_SOURCE} > ${NOWEB_OUTPUT_DIR}/listerrors.c
2153 \begin_layout Plain Layout
2155 gcc -g -o listerrors listerrors.c
2163 \begin_layout Standard
2164 This project can be tangled and compiled from \SpecialCharNoPassThru LyX
2171 to call a generic script that always extracts a chunk named
2176 Here is a example of such generic script:
2179 \begin_layout LyX-Code
2181 \begin_inset Newline newline
2184 notangle -Rbuild-script $1 | env NOWEB_SOURCE=$1 NOWEB_OUTPUT_DIR=$r sh
2187 \begin_layout LyX-Code