%Start ErrorText ErrorMessage OtherTextEC[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]%{/* moore@wilma.cs.utk.edu * 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]*{/**ignorethis.don'ttreatitaserrortext*/}^{DS}{DS}{DS}\{D5}\\|{/**(optional)nestinglevel,followedbylinenumber,followed*bythesourcecodefragmentthatcausedtheerror*//**savethelinenumberforlater*/line=atoi(yytext+4);if(debug){fprintf(yyout, "line<=%d\n", line);fprintf(yyout, "%s\n", yytext);}/**ifthelastlinewasanerrormessage,toflushoutallof*theoldsourcetextbeforestartingtosavethenewsourcetext.*/if(last_line_was_error){*bufptr='\0';bufptr=bigbuf;while(*bufptr)putc(*bufptr++,yyout);bufptr=bigbuf;last_line_was_error=0;}/**stuffenoughspacesinthetextbuffersothatthe*savedtextwilllineupproperlywhendisplayed.*/spaces(yytext);BEGINErrorText;/*continuebelow*/}<ErrorText>[^\n]*$ {char*ptr;/**Savethetextuntilweseetheerrormessage(s),thenprintit.*Thisbecauseemacsputstheerrormessageatthetopofthe*window,andit'snicetobeabletoseethetextbelowit.*/ptr=yytext;while(*ptr)*bufptr++=*ptr++;*bufptr++='\n';BEGIN0;}^Processing\include\file\.*$ {/**nameofanewincludefilebeingprocessed.Incrementfilenumber*andrememberthefilenamecorrespondingtothisfilenumber.*/current_file=strsave(yytext+24);if(debug){fprintf(yyout, "current_file<=%s\n", current_file);fprintf(yyout, "%s\n", yytext);}}^([a-z]\-)?\*{EC}:{/**errormessage(whichweprintimmediately)precededbyan*errorcode(whichweignore)*/fprintf(yyout, "\"%s\", line %d: %c -", current_file, line, *yytext);last_line_was_error=1;BEGINErrorMessage;}^{D3}\{D5}\{D4}\{EC}:{/**(optional)nestinglevel,followedbylinenumber,followed*bycolumnnumber,followedbyerrormessagetext.*//**savethelinenumberforlater*/line=atoi(yytext+4);if(debug){fprintf(yyout, "line<=%d\n", line);fprintf(yyout, "%s\n", yytext);}/**ifthelastlinewasanerrormessage,flushoutallof*theoldsourcetextbeforeprintingthiserrormessage.*/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;BEGINErrorMessage;}<ErrorMessage>[^\n]*$ {fprintf(yyout, "%s\n", yytext);BEGIN0;}^[^ :]+".c:"\*$ {/*nameofnewsourcefilebeingprocessed*/char*ptr;if(current_file)free(current_file);ptr=strchr(yytext,':');*ptr='\0';current_file=strsave(yytext);}^[^\n]{/**othertextstartingwithanewline.Wehavetobreakitupthis*waytokeepthisrulefrommatchinganyoftheabovepatterns*/if(last_line_was_error){*bufptr='\0';bufptr=bigbuf;while(*bufptr)putc(*bufptr++,yyout);bufptr=bigbuf;last_line_was_error=0;}*bufptr++=*yytext;BEGINOtherText;}<OtherText>[^\n]*$ {char*ptr;ptr=yytext;while(*ptr)*bufptr++=*ptr++;*bufptr++='\n';BEGIN0;}\n;%%main(argc,argv)char**argv;{intpfd[2];intchild_pid;inti;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){intstatus;close(pfd[1]);yyin=fdopen(pfd[0], "r");yyout=stderr;yylex();wait(&status);exit((status>>8)&0xff);}elseif(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);}}