Merge branch 'master' into m7-trial
This commit is contained in:
+23
-14
@@ -1,5 +1,14 @@
|
|||||||
#include "diag.h"
|
#include "diag.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
FILE *fe_diag_stream(void)
|
||||||
|
{
|
||||||
|
static FILE *stream=0;
|
||||||
|
if(!stream) stream=getenv("FE_DIAG_STDOUT") ? stdout : stderr;
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned long digits(unsigned long n)
|
static unsigned long digits(unsigned long n)
|
||||||
{
|
{
|
||||||
unsigned long count=1;
|
unsigned long count=1;
|
||||||
@@ -27,21 +36,21 @@ static void excerpt(const FeDiags *d, FeLoc loc)
|
|||||||
end=start;
|
end=start;
|
||||||
while(end<len && src[end]!='\n' && src[end]!='\r')++end;
|
while(end<len && src[end]!='\n' && src[end]!='\r')++end;
|
||||||
gutter=digits(loc.line);
|
gutter=digits(loc.line);
|
||||||
fputs(" ",stderr);
|
fputs(" ",fe_diag_stream());
|
||||||
fprintf(stderr,"%lu | ",loc.line);
|
fprintf(fe_diag_stream(),"%lu | ",loc.line);
|
||||||
if(end>start) fwrite(src+start,1,(size_t)(end-start),stderr);
|
if(end>start) fwrite(src+start,1,(size_t)(end-start),fe_diag_stream());
|
||||||
fputc('\n',stderr);
|
fputc('\n',fe_diag_stream());
|
||||||
fputs(" ",stderr);
|
fputs(" ",fe_diag_stream());
|
||||||
for(i=0;i<gutter;++i) fputc(' ',stderr);
|
for(i=0;i<gutter;++i) fputc(' ',fe_diag_stream());
|
||||||
fputs(" | ",stderr);
|
fputs(" | ",fe_diag_stream());
|
||||||
col=1;
|
col=1;
|
||||||
i=start;
|
i=start;
|
||||||
while(i<end && col<loc.col){
|
while(i<end && col<loc.col){
|
||||||
c=src[i++];
|
c=src[i++];
|
||||||
fputc(c=='\t' ? '\t' : ' ',stderr);
|
fputc(c=='\t' ? '\t' : ' ',fe_diag_stream());
|
||||||
++col;
|
++col;
|
||||||
}
|
}
|
||||||
fputs("^\n",stderr);
|
fputs("^\n",fe_diag_stream());
|
||||||
}
|
}
|
||||||
|
|
||||||
void fe_diags_init(FeDiags *d, const char *source, unsigned long source_len)
|
void fe_diags_init(FeDiags *d, const char *source, unsigned long source_len)
|
||||||
@@ -55,22 +64,22 @@ void fe_diags_init(FeDiags *d, const char *source, unsigned long source_len)
|
|||||||
void fe_diag_error(FeDiags *d, FeLoc loc, const char *msg)
|
void fe_diag_error(FeDiags *d, FeLoc loc, const char *msg)
|
||||||
{
|
{
|
||||||
d->errors++;
|
d->errors++;
|
||||||
fprintf(stderr, "%s:%lu:%lu: error: %s\n", loc.file ? loc.file : "<source>", loc.line, loc.col, msg);
|
fprintf(fe_diag_stream(), "%s:%lu:%lu: error: %s\n", loc.file ? loc.file : "<source>", loc.line, loc.col, msg);
|
||||||
excerpt(d,loc);
|
excerpt(d,loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fe_diag_errorf(FeDiags *d, FeLoc loc, const char *msg, const char *arg)
|
void fe_diag_errorf(FeDiags *d, FeLoc loc, const char *msg, const char *arg)
|
||||||
{
|
{
|
||||||
d->errors++;
|
d->errors++;
|
||||||
fprintf(stderr, "%s:%lu:%lu: error: ", loc.file ? loc.file : "<source>", loc.line, loc.col);
|
fprintf(fe_diag_stream(), "%s:%lu:%lu: error: ", loc.file ? loc.file : "<source>", loc.line, loc.col);
|
||||||
fprintf(stderr, msg, arg);
|
fprintf(fe_diag_stream(), msg, arg);
|
||||||
fputc('\n', stderr);
|
fputc('\n', fe_diag_stream());
|
||||||
excerpt(d,loc);
|
excerpt(d,loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fe_diag_note(FeLoc loc, const char *msg)
|
void fe_diag_note(FeLoc loc, const char *msg)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s:%lu:%lu: note: %s\n", loc.file ? loc.file : "<source>", loc.line, loc.col, msg);
|
fprintf(fe_diag_stream(), "%s:%lu:%lu: note: %s\n", loc.file ? loc.file : "<source>", loc.line, loc.col, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fe_diag_note_src(FeDiags *d, FeLoc loc, const char *msg)
|
void fe_diag_note_src(FeDiags *d, FeLoc loc, const char *msg)
|
||||||
|
|||||||
@@ -16,6 +16,13 @@ typedef struct FeDiags {
|
|||||||
unsigned long source_len;
|
unsigned long source_len;
|
||||||
} FeDiags;
|
} FeDiags;
|
||||||
|
|
||||||
|
/* Stream diagnostics are written to. Defaults to stderr; returns stdout when
|
||||||
|
FE_DIAG_STDOUT is set in the environment. DOS offers no way to redirect
|
||||||
|
handle 2 -- COMMAND.COM understands ">" and nothing else -- so under the test
|
||||||
|
runner every error message would otherwise be written straight to the screen
|
||||||
|
and lost. Interactive use is unaffected: both streams reach the console. */
|
||||||
|
FILE *fe_diag_stream(void);
|
||||||
|
|
||||||
void fe_diags_init(FeDiags *d, const char *source, unsigned long source_len);
|
void fe_diags_init(FeDiags *d, const char *source, unsigned long source_len);
|
||||||
void fe_diag_error(FeDiags *d, FeLoc loc, const char *msg);
|
void fe_diag_error(FeDiags *d, FeLoc loc, const char *msg);
|
||||||
void fe_diag_errorf(FeDiags *d, FeLoc loc, const char *msg, const char *arg);
|
void fe_diag_errorf(FeDiags *d, FeLoc loc, const char *msg, const char *arg);
|
||||||
|
|||||||
+6
-6
@@ -8,7 +8,7 @@
|
|||||||
static char *read_file(const char *name, unsigned long *size)
|
static char *read_file(const char *name, unsigned long *size)
|
||||||
{
|
{
|
||||||
FILE *f; long n; char *p;
|
FILE *f; long n; char *p;
|
||||||
f=fopen(name,"rb"); if(!f){fprintf(stderr,"fec: cannot open %s\n",name);return 0;}
|
f=fopen(name,"rb"); if(!f){fprintf(fe_diag_stream(),"fec: cannot open %s\n",name);return 0;}
|
||||||
if(fseek(f,0L,SEEK_END)!=0){fclose(f);return 0;} n=ftell(f); if(n<0){fclose(f);return 0;} rewind(f);
|
if(fseek(f,0L,SEEK_END)!=0){fclose(f);return 0;} n=ftell(f); if(n<0){fclose(f);return 0;} rewind(f);
|
||||||
p=(char *)malloc((unsigned long)n+1); if(!p){fclose(f);return 0;}
|
p=(char *)malloc((unsigned long)n+1); if(!p){fclose(f);return 0;}
|
||||||
if(n && fread(p,1,(size_t)n,f)!=(size_t)n){free(p);fclose(f);return 0;} fclose(f);p[n]='\0';*size=(unsigned long)n;return p;
|
if(n && fread(p,1,(size_t)n,f)!=(size_t)n){free(p);fclose(f);return 0;} fclose(f);p[n]='\0';*size=(unsigned long)n;return p;
|
||||||
@@ -54,7 +54,7 @@ int main(int argc, char **argv)
|
|||||||
else if(strcmp(argv[i],"--dump-tokens")==0) dump_tok=1;
|
else if(strcmp(argv[i],"--dump-tokens")==0) dump_tok=1;
|
||||||
else if(strcmp(argv[i],"--check")==0) check_only=1;
|
else if(strcmp(argv[i],"--check")==0) check_only=1;
|
||||||
else if(strcmp(argv[i],"--emit-c")==0) emit=1;
|
else if(strcmp(argv[i],"--emit-c")==0) emit=1;
|
||||||
else if(strcmp(argv[i],"-o")==0){if(i+1>=argc){fprintf(stderr,"fec: -o needs a path\n");return 2;}outname=argv[++i];}
|
else if(strcmp(argv[i],"-o")==0){if(i+1>=argc){fprintf(fe_diag_stream(),"fec: -o needs a path\n");return 2;}outname=argv[++i];}
|
||||||
else if(strncmp(argv[i],"-o",2)==0 && argv[i][2]) outname=argv[i]+2;
|
else if(strncmp(argv[i],"-o",2)==0 && argv[i][2]) outname=argv[i]+2;
|
||||||
else if(strncmp(argv[i],"--target=bits16",15)==0) pointer_bits=16;
|
else if(strncmp(argv[i],"--target=bits16",15)==0) pointer_bits=16;
|
||||||
else if(strncmp(argv[i],"--target=bits32",15)==0) pointer_bits=32;
|
else if(strncmp(argv[i],"--target=bits32",15)==0) pointer_bits=32;
|
||||||
@@ -62,13 +62,13 @@ int main(int argc, char **argv)
|
|||||||
else if(strncmp(argv[i],"--target=",9)==0 || strncmp(argv[i],"--model=",8)==0 || strcmp(argv[i],"--strip-error-names")==0) { }
|
else if(strncmp(argv[i],"--target=",9)==0 || strncmp(argv[i],"--model=",8)==0 || strcmp(argv[i],"--strip-error-names")==0) { }
|
||||||
else if(argv[i][0]!='-') file=argv[i];
|
else if(argv[i][0]!='-') file=argv[i];
|
||||||
else if(strcmp(argv[i],"--help")==0){usage();return 0;}
|
else if(strcmp(argv[i],"--help")==0){usage();return 0;}
|
||||||
else {fprintf(stderr,"fec: unknown option %s\n",argv[i]);return 2;}
|
else {fprintf(fe_diag_stream(),"fec: unknown option %s\n",argv[i]);return 2;}
|
||||||
}
|
}
|
||||||
if((dump?1:0)+(dump_tok?1:0)+(check_only?1:0)+(emit?1:0)>1){
|
if((dump?1:0)+(dump_tok?1:0)+(check_only?1:0)+(emit?1:0)>1){
|
||||||
fprintf(stderr,"fec: choose only one output mode\n");
|
fprintf(fe_diag_stream(),"fec: choose only one output mode\n");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
if(!file){fprintf(stderr,"fec: no input file\n");return 2;}
|
if(!file){fprintf(fe_diag_stream(),"fec: no input file\n");return 2;}
|
||||||
src=read_file(file,&n);
|
src=read_file(file,&n);
|
||||||
if(!src)return 2;
|
if(!src)return 2;
|
||||||
fe_diags_init(&d,src,n);
|
fe_diags_init(&d,src,n);
|
||||||
@@ -98,7 +98,7 @@ int main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
out=outname?fopen(outname,"w"):stdout;
|
out=outname?fopen(outname,"w"):stdout;
|
||||||
if(!out){fprintf(stderr,"fec: cannot create %s\n",outname);fe_ast_destroy(&ast);free(src);return 2;}
|
if(!out){fprintf(fe_diag_stream(),"fec: cannot create %s\n",outname);fe_ast_destroy(&ast);free(src);return 2;}
|
||||||
fe_emit_c_init(&emitter,out,&check,pointer_bits,no_checks);
|
fe_emit_c_init(&emitter,out,&check,pointer_bits,no_checks);
|
||||||
fe_emit_c_program(&emitter);
|
fe_emit_c_program(&emitter);
|
||||||
if(outname)fclose(out);
|
if(outname)fclose(out);
|
||||||
|
|||||||
@@ -159,6 +159,9 @@ def _batch(cases: list[Case], *, show_dos: bool, trace_dos: bool) -> str:
|
|||||||
"@echo off", "if not exist RESULTS md RESULTS", "if not exist OUT md OUT",
|
"@echo off", "if not exist RESULTS md RESULTS", "if not exist OUT md OUT",
|
||||||
"set WATCOM=W:", "set INCLUDE=W:\\H",
|
"set WATCOM=W:", "set INCLUDE=W:\\H",
|
||||||
"set LIB=W:\\LIB286\\DOS;W:\\LIB286;W:\\LIB386\\DOS;W:\\LIB386",
|
"set LIB=W:\\LIB286\\DOS;W:\\LIB286;W:\\LIB386\\DOS;W:\\LIB386",
|
||||||
|
# COMMAND.COM can only redirect handle 1, so fec diagnostics written to
|
||||||
|
# stderr never reach RESULTS\<key>.LOG. Ask it for stdout instead.
|
||||||
|
"set FE_DIAG_STDOUT=1",
|
||||||
build, "if not exist BUILD.OK goto BUILDFAIL",
|
build, "if not exist BUILD.OK goto BUILDFAIL",
|
||||||
"echo PASS>RESULTS\\BUILD.RES",
|
"echo PASS>RESULTS\\BUILD.RES",
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user