mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-04 11:40:22 +00:00
Initial revision
This commit is contained in:
parent
3eb43f7140
commit
e5f7865902
300
lib-src/aixcc.lex
Normal file
300
lib-src/aixcc.lex
Normal file
@ -0,0 +1,300 @@
|
||||
%Start ErrorText ErrorMessage OtherText
|
||||
|
||||
EC [0-9][0-9][0-9][0-9]-[0-9][0-9][0-9]
|
||||
D [0-9]
|
||||
D3 [0-9 ][0-9 ][0-9]
|
||||
D4 [0-9 ][0-9 ][0-9 ][0-9]
|
||||
D5 [0-9 ][0-9 ][0-9 ][0-9 ][0-9]
|
||||
DS [0-9 ]
|
||||
|
||||
%{
|
||||
/*
|
||||
* Hack to work around the AIX C compiler's brain-damaged error messages
|
||||
* so that emacs can parse them. It runs /bin/cc as a subprocess, and
|
||||
* tries to rearrange the error messages so that (a) each message contains
|
||||
* both the filename and line number where the error occurred, and (b)
|
||||
* the error message(s) for a particular line get displayed *before* the
|
||||
* line itself.
|
||||
*
|
||||
* to compile:
|
||||
* lex aixcc.lex
|
||||
* cc -o aixcc lex.yy.c
|
||||
*
|
||||
*
|
||||
* Copyright December 1991 by Keith Moore
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
* TODO: figure out how the compiler counts file numbers for included
|
||||
* files, keep track of which file corresponds to which number, and
|
||||
* always output the right file name.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
char *current_file;
|
||||
int line;
|
||||
int debug = 0;
|
||||
char bigbuf[10240];
|
||||
char *bufptr = bigbuf;
|
||||
int last_line_was_error = 0;
|
||||
|
||||
spaces (s)
|
||||
char *s;
|
||||
{
|
||||
while (*s++)
|
||||
*bufptr++ = ' ';
|
||||
}
|
||||
|
||||
char *
|
||||
strsave (s)
|
||||
char *s;
|
||||
{
|
||||
char *ptr = malloc (strlen (s) + 1);
|
||||
strcpy (ptr, s);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
yywrap ()
|
||||
{
|
||||
*bufptr = '\0';
|
||||
bufptr = bigbuf;
|
||||
while (*bufptr)
|
||||
putc (*bufptr++, yyout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
%}
|
||||
%%
|
||||
^File\ Line\ Column\ Message\ text[^\n]* {
|
||||
/*
|
||||
* ignore this. don't treat it as error text
|
||||
*/
|
||||
}
|
||||
|
||||
^{DS}{DS}{DS}\ {D5}\ \| {
|
||||
/*
|
||||
* (optional) nesting level, followed by line number, followed
|
||||
* by the source code fragment that caused the error
|
||||
*/
|
||||
|
||||
/*
|
||||
* save the line number for later
|
||||
*/
|
||||
line = atoi (yytext+4);
|
||||
|
||||
if (debug) {
|
||||
fprintf (yyout, "line <= %d\n", line);
|
||||
fprintf (yyout, "%s\n", yytext);
|
||||
}
|
||||
|
||||
/*
|
||||
* if the last line was an error message, to flush out all of
|
||||
* the old source text before starting to save the new source text.
|
||||
*/
|
||||
if (last_line_was_error) {
|
||||
*bufptr = '\0';
|
||||
bufptr = bigbuf;
|
||||
while (*bufptr)
|
||||
putc (*bufptr++, yyout);
|
||||
bufptr = bigbuf;
|
||||
last_line_was_error = 0;
|
||||
}
|
||||
/*
|
||||
* stuff enough spaces in the text buffer so that the
|
||||
* saved text will line up properly when displayed.
|
||||
*/
|
||||
spaces (yytext);
|
||||
|
||||
BEGIN ErrorText; /* continue below */
|
||||
}
|
||||
|
||||
<ErrorText>[^\n]*$ {
|
||||
char *ptr;
|
||||
|
||||
/*
|
||||
* Save the text until we see the error message(s), then print it.
|
||||
* This because emacs puts the error message at the top of the
|
||||
* window, and it's nice to be able to see the text below it.
|
||||
*/
|
||||
|
||||
ptr = yytext;
|
||||
while (*ptr)
|
||||
*bufptr++ = *ptr++;
|
||||
*bufptr++ = '\n';
|
||||
|
||||
BEGIN 0;
|
||||
}
|
||||
|
||||
^Processing\ include\ file\ .*$ {
|
||||
/*
|
||||
* name of a new include file being processed. Increment file number
|
||||
* and remember the file name corresponding to this file number.
|
||||
*/
|
||||
|
||||
current_file = strsave (yytext+24);
|
||||
|
||||
if (debug) {
|
||||
fprintf (yyout, "current_file <= %s\n", current_file);
|
||||
fprintf (yyout, "%s\n", yytext);
|
||||
}
|
||||
}
|
||||
|
||||
^([a-z]\ -)?\ *{EC}: {
|
||||
/*
|
||||
* error message (which we print immediately) preceeded by an
|
||||
* error code (which we ignore)
|
||||
*/
|
||||
|
||||
fprintf (yyout, "\"%s\", line %d: %c -", current_file, line, *yytext);
|
||||
last_line_was_error = 1;
|
||||
BEGIN ErrorMessage;
|
||||
}
|
||||
|
||||
^{D3}\ {D5}\ {D4}\ {EC}: {
|
||||
/*
|
||||
* (optional) nesting level, followed by line number, followed
|
||||
* by column number, followed by error message text.
|
||||
*/
|
||||
|
||||
/*
|
||||
* save the line number for later
|
||||
*/
|
||||
line = atoi (yytext+4);
|
||||
|
||||
if (debug) {
|
||||
fprintf (yyout, "line <= %d\n", line);
|
||||
fprintf (yyout, "%s\n", yytext);
|
||||
}
|
||||
|
||||
/*
|
||||
* if the last line was an error message, flush out all of
|
||||
* the old source text before printing this error message.
|
||||
*/
|
||||
if (last_line_was_error) {
|
||||
*bufptr = '\0';
|
||||
bufptr = bigbuf;
|
||||
while (*bufptr)
|
||||
putc (*bufptr++, yyout);
|
||||
bufptr = bigbuf;
|
||||
last_line_was_error = 0;
|
||||
}
|
||||
fprintf (yyout, "\"%s\", line %d:", current_file, line);
|
||||
last_line_was_error = 1;
|
||||
BEGIN ErrorMessage;
|
||||
}
|
||||
|
||||
<ErrorMessage>[^\n]*$ {
|
||||
fprintf (yyout, "%s\n", yytext);
|
||||
BEGIN 0;
|
||||
}
|
||||
|
||||
|
||||
^[^ :]+".c:"\ *$ {
|
||||
/* name of new source file being processed */
|
||||
|
||||
char *ptr;
|
||||
|
||||
if (current_file)
|
||||
free (current_file);
|
||||
ptr = strchr (yytext, ':');
|
||||
*ptr = '\0';
|
||||
current_file = strsave (yytext);
|
||||
}
|
||||
|
||||
^[^\n] {
|
||||
/*
|
||||
* other text starting with a newline. We have to break it up this
|
||||
* way to keep this rule from matching any of the above patterns
|
||||
*/
|
||||
|
||||
if (last_line_was_error) {
|
||||
*bufptr = '\0';
|
||||
bufptr = bigbuf;
|
||||
while (*bufptr)
|
||||
putc (*bufptr++, yyout);
|
||||
bufptr = bigbuf;
|
||||
last_line_was_error = 0;
|
||||
}
|
||||
|
||||
*bufptr++ = *yytext;
|
||||
BEGIN OtherText;
|
||||
}
|
||||
|
||||
<OtherText>[^\n]*$ {
|
||||
char *ptr;
|
||||
|
||||
ptr = yytext;
|
||||
while (*ptr)
|
||||
*bufptr++ = *ptr++;
|
||||
*bufptr++ = '\n';
|
||||
|
||||
BEGIN 0;
|
||||
}
|
||||
|
||||
\n ;
|
||||
|
||||
%%
|
||||
|
||||
main (argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
int pfd[2];
|
||||
int child_pid;
|
||||
int i;
|
||||
|
||||
current_file = strsave ("/dev/null");
|
||||
|
||||
line = 0;
|
||||
|
||||
for (i = 1; i < argc; ++i) {
|
||||
char *ptr = strrchr (argv[i], '.');
|
||||
if (ptr && ptr[1] == 'c' && ptr[2] == '\0') {
|
||||
current_file = strsave (argv[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pipe (pfd) < 0) {
|
||||
perror ("pipe");
|
||||
exit (1);
|
||||
}
|
||||
if ((child_pid = fork()) > 0) {
|
||||
int status;
|
||||
|
||||
close (pfd[1]);
|
||||
yyin = fdopen (pfd[0], "r");
|
||||
yyout = stderr;
|
||||
yylex();
|
||||
|
||||
wait (&status);
|
||||
exit ((status >> 8) & 0xff);
|
||||
}
|
||||
else if (child_pid == 0) {
|
||||
dup2 (pfd[1], 2);
|
||||
close (pfd[0]);
|
||||
close (pfd[1]);
|
||||
argv[0] = "cc";
|
||||
execv ("/bin/cc", argv);
|
||||
perror ("/bin/cc");
|
||||
exit (1);
|
||||
}
|
||||
else {
|
||||
perror ("fork");
|
||||
exit (1);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user