*** empty log message ***
[emacs/old-mirror.git] / lib-src / =aixcc.lex
blobb7b44701b18790a3e30f71ffe26ab7b1a51d24a2
1 %Start ErrorText ErrorMessage OtherText
3 EC      [0-9][0-9][0-9][0-9]-[0-9][0-9][0-9]
4 D       [0-9]
5 D3      [0-9 ][0-9 ][0-9]
6 D4      [0-9 ][0-9 ][0-9 ][0-9]
7 D5      [0-9 ][0-9 ][0-9 ][0-9 ][0-9]
8 DS      [0-9 ]
11 /* moore@wilma.cs.utk.edu
13  * Hack to work around the AIX C compiler's brain-damaged error messages
14  * so that emacs can parse them.  It runs /bin/cc as a subprocess, and
15  * tries to rearrange the error messages so that (a) each message contains
16  * both the filename and line number where the error occurred, and (b)
17  * the error message(s) for a particular line get displayed *before* the
18  * line itself.
19  *
20  * to compile: 
21  * lex aixcc.lex
22  * cc -o aixcc lex.yy.c
23  *
24  *
25  * Copyright December 1991 by Keith Moore
26  *
27  * This program is free software; you can redistribute it and/or modify
28  * it under the terms of the GNU General Public License as published by
29  * the Free Software Foundation; either version 2 of the License, or
30  * (at your option) any later version.
31  * 
32  * This program is distributed in the hope that it will be useful,
33  * but WITHOUT ANY WARRANTY; without even the implied warranty of
34  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
35  * GNU General Public License for more details.
36  * 
37  * You should have received a copy of the GNU General Public License
38  * along with this program; if not, write to the Free Software
39  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
40  *
41  *
42  * TODO: figure out how the compiler counts file numbers for included
43  * files, keep track of which file corresponds to which number, and
44  * always output the right file name.
45  */
47 #include <stdio.h>
48 #include <string.h>
50 char *current_file;
51 int line;
52 int debug = 0;
53 char bigbuf[10240];
54 char *bufptr = bigbuf;
55 int last_line_was_error = 0;
57 spaces (s)
58 char *s;
60     while (*s++)
61         *bufptr++ = ' ';
64 char *
65 strsave (s)
66 char *s;
68     char *ptr = malloc (strlen (s) + 1);
69     strcpy (ptr, s);
70     return ptr;
73 yywrap ()
75     *bufptr = '\0';
76     bufptr = bigbuf;
77     while (*bufptr)
78         putc (*bufptr++, yyout);
79     return 1;
84 ^File\ Line\ Column\ Message\ text[^\n]*        {
85    /*
86     * ignore this.  don't treat it as error text
87     */
90 ^{DS}{DS}{DS}\ {D5}\ \| {
91     /*
92      * (optional) nesting level, followed by line number, followed
93      * by the source code fragment that caused the error
94      */
96     /*
97      * save the line number for later
98      */
99     line = atoi (yytext+4);
101     if (debug) {
102         fprintf (yyout, "line <= %d\n", line);
103         fprintf (yyout, "%s\n", yytext);
104     }
106     /*
107      * if the last line was an error message, to flush out all of
108      * the old source text before starting to save the new source text.
109      */
110     if (last_line_was_error) {
111         *bufptr = '\0';
112         bufptr = bigbuf;
113         while (*bufptr)
114             putc (*bufptr++, yyout);
115         bufptr = bigbuf;
116         last_line_was_error = 0;
117     }
118     /*
119      * stuff enough spaces in the text buffer so that the
120      * saved text will line up properly when displayed.
121      */
122     spaces (yytext);
124     BEGIN ErrorText;    /* continue below */
127 <ErrorText>[^\n]*$      {
128     char *ptr;
130     /* 
131      * Save the text until we see the error message(s), then print it.
132      * This because emacs puts the error message at the top of the
133      * window, and it's nice to be able to see the text below it.
134      */
136     ptr = yytext;
137     while (*ptr)
138         *bufptr++ = *ptr++;
139     *bufptr++ = '\n';
141     BEGIN 0;
144 ^Processing\ include\ file\ .*$ {
145     /*
146      * name of a new include file being processed.  Increment file number
147      * and remember the file name corresponding to this file number.
148      */
150     current_file = strsave (yytext+24);
151     
152     if (debug) {
153         fprintf (yyout, "current_file <= %s\n", current_file);
154         fprintf (yyout, "%s\n", yytext);
155     }
158 ^([a-z]\ -)?\ *{EC}:    {
159     /* 
160      * error message (which we print immediately) preceded by an
161      * error code (which we ignore)
162      */
164     fprintf (yyout, "\"%s\", line %d: %c -", current_file, line, *yytext);
165     last_line_was_error = 1;
166     BEGIN ErrorMessage;
169 ^{D3}\ {D5}\ {D4}\ {EC}:        {
170     /*
171      * (optional) nesting level, followed by line number, followed
172      * by column number, followed by error message text.
173      */
175     /*
176      * save the line number for later
177      */
178     line = atoi (yytext+4);
180     if (debug) {
181         fprintf (yyout, "line <= %d\n", line);
182         fprintf (yyout, "%s\n", yytext);
183     }
185     /*
186      * if the last line was an error message, flush out all of
187      * the old source text before printing this error message.
188      */
189     if (last_line_was_error) {
190         *bufptr = '\0';
191         bufptr = bigbuf;
192         while (*bufptr)
193             putc (*bufptr++, yyout);
194         bufptr = bigbuf;
195         last_line_was_error = 0;
196     }
197     fprintf (yyout, "\"%s\", line %d:", current_file, line);
198     last_line_was_error = 1;
199     BEGIN ErrorMessage;
202 <ErrorMessage>[^\n]*$   {
203     fprintf (yyout, "%s\n", yytext);
204     BEGIN 0;
208 ^[^ :]+".c:"\ *$        {
209     /* name of new source file being processed */
211     char *ptr;
213     if (current_file)
214         free (current_file);
215     ptr = strchr (yytext, ':');
216     *ptr = '\0';
217     current_file = strsave (yytext);
220 ^[^\n]  {
221     /*
222      * other text starting with a newline.  We have to break it up this
223      * way to keep this rule from matching any of the above patterns
224      */
226     if (last_line_was_error) {
227         *bufptr = '\0';
228         bufptr = bigbuf;
229         while (*bufptr)
230             putc (*bufptr++, yyout);
231         bufptr = bigbuf;
232         last_line_was_error = 0;
233     }
235     *bufptr++ = *yytext;
236     BEGIN OtherText;
239 <OtherText>[^\n]*$      {
240     char *ptr;
242     ptr = yytext;
243     while (*ptr)
244         *bufptr++ = *ptr++;
245     *bufptr++ = '\n';
247     BEGIN 0;
250 \n      ;
254 main (argc, argv)
255 char **argv;
257     int pfd[2];
258     int child_pid;
259     int i;
261     current_file = strsave ("/dev/null");
263     line = 0;
265     for (i = 1; i < argc; ++i) {
266         char *ptr = strrchr (argv[i], '.');
267         if (ptr && ptr[1] == 'c' && ptr[2] == '\0') {
268             current_file = strsave (argv[i]);
269             break;
270         }
271     }
273     if (pipe (pfd) < 0) {
274         perror ("pipe");
275         exit (1);
276     }
277     if ((child_pid = fork()) > 0) {
278         int status;
280         close (pfd[1]);
281         yyin = fdopen (pfd[0], "r");
282         yyout = stderr;
283         yylex();
285         wait (&status);
286         exit ((status >> 8) & 0xff);
287     }
288     else if (child_pid == 0) {
289         dup2 (pfd[1], 2);
290         close (pfd[0]);
291         close (pfd[1]);
292         argv[0] = "cc";
293         execv ("/bin/cc", argv);
294         perror ("/bin/cc");
295         exit (1);
296     }
297     else {
298         perror ("fork");
299         exit (1);
300     }