Adjust how messages from the printf/scanf format checker are displayed.

Mainly, this causes the messages from the format checker to be displayed after the relevant line is printed, along with any other error messages. The wording and formatting of some of the messages is also slightly adjusted, but there should be no substantive change in what is warned about.
This commit is contained in:
Stephen Heumann 2018-09-01 19:53:08 -05:00
parent 9ff3407c60
commit 69f086367c
4 changed files with 61 additions and 45 deletions

View File

@ -15,7 +15,7 @@ interface
{$LibPrefix '0/obj/'} {$LibPrefix '0/obj/'}
uses CCommon; uses CCommon, Scanner;
{$segment 'PRINTF'} {$segment 'PRINTF'}
@ -65,9 +65,6 @@ type
types = set of baseTypeEnum; types = set of baseTypeEnum;
procedure Error (err: integer); extern; {in scanner.pas}
function FormatClassify {fname: stringPtr): fmt_type}; function FormatClassify {fname: stringPtr): fmt_type};
{ {
@ -130,9 +127,11 @@ var
begin {Warning} begin {Warning}
if error_count = 0 then begin if error_count = 0 then begin
WriteLine;
Error(124); Error(124);
WriteLine;
if s <> nil then begin if s <> nil then begin
Write(' "'); Write(' > "');
for i := 1 to s^.length do begin for i := 1 to s^.length do begin
c := s^.str[i]; c := s^.str[i];
if (c = '"') or (ord(c) < $20) or (ord(c) > $7f) then c := '.'; if (c = '"') or (ord(c) < $20) or (ord(c) > $7f) then c := '.';
@ -143,11 +142,13 @@ var
end; {if} end; {if}
error_count := error_count + 1; error_count := error_count + 1;
Write(' '); Write(' ');
if offset <> 0 then begin if offset = 0 then
if s <> nil then
offset := s^.length + 1;
if offset > 0 then begin
for i := 1 to offset do Write(' '); for i := 1 to offset do Write(' ');
Write('^ '); Write('^ ');
end; {if} end; {if}
Write('Warning: ');
WriteLn(msg^); WriteLn(msg^);
end; {Warning} end; {Warning}
@ -159,11 +160,11 @@ var
begin {WarningConversionChar} begin {WarningConversionChar}
if (ord(c) >= $20) and (ord(c) <= $7f) then begin if (ord(c) >= $20) and (ord(c) <= $7f) then begin
new(msg); new(msg);
msg^ := concat('unknown conversion type character ''', c, ''' in format.'); msg^ := concat('unknown conversion type character ''', c, ''' in format');
Warning(msg); Warning(msg);
dispose(msg); dispose(msg);
end {if} end {if}
else Warning(@'unknown conversion type character in format.'); else Warning(@'unknown conversion type character in format');
end; {WarningConversionChar} end; {WarningConversionChar}
procedure WarningExtraArgs(i: integer); procedure WarningExtraArgs(i: integer);
@ -172,7 +173,7 @@ var
msg: stringPtr; msg: stringPtr;
begin {WarningExtraArgs} begin {WarningExtraArgs}
new(msg); new(msg);
msg^ := concat('extra arguments provided (', cnvis(i), ' expected).'); msg^ := concat('extra argument(s) provided (', cnvis(i), ' expected)');
Warning(msg); Warning(msg);
dispose(msg); dispose(msg);
end; {WarningExtraArgs} end; {WarningExtraArgs}
@ -200,7 +201,7 @@ var
ty := popType; ty := popType;
if ty <> nil then begin if ty <> nil then begin
if (ty^.kind <> scalarType) or (not (ty^.baseType in [cgLong, cgULong])) then begin if (ty^.kind <> scalarType) or (not (ty^.baseType in [cgLong, cgULong])) then begin
Warning(@'expected long int.'); Warning(@'expected long int');
end; {if} end; {if}
end {if} end {if}
else begin else begin
@ -217,11 +218,11 @@ var
if ty <> nil then begin if ty <> nil then begin
if (ty^.kind <> scalarType) or if (ty^.kind <> scalarType) or
not (ty^.baseType in [cgWord, cgUWord, cgByte, cgUByte]) then begin not (ty^.baseType in [cgWord, cgUWord, cgByte, cgUByte]) then begin
Warning(@'expected int.'); Warning(@'expected int');
end; {if} end; {if}
end {if} end {if}
else begin else begin
Warning(@'argument missing; expected int.'); Warning(@'argument missing; expected int');
end; {else} end; {else}
end; {expect_int} end; {expect_int}
@ -235,11 +236,11 @@ var
if ty <> nil then begin if ty <> nil then begin
if (ty^.kind <> scalarType) or if (ty^.kind <> scalarType) or
not (ty^.baseType in [cgWord, cgUWord, cgByte, cgUByte]) then begin not (ty^.baseType in [cgWord, cgUWord, cgByte, cgUByte]) then begin
Warning(@'expected char.'); Warning(@'expected char');
end; {if} end; {if}
end {if} end {if}
else begin else begin
Warning(@'argument missing; expected char.'); Warning(@'argument missing; expected char');
end; {else} end; {else}
end; {expect_char} end; {expect_char}
@ -254,11 +255,11 @@ var
if ty <> nil then begin if ty <> nil then begin
if (ty^.kind <> scalarType) or if (ty^.kind <> scalarType) or
not (ty^.baseType in [cgExtended, cgReal, cgDouble]) then begin not (ty^.baseType in [cgExtended, cgReal, cgDouble]) then begin
Warning(@'expected extended.'); Warning(@'expected extended');
end; {if} end; {if}
end {if} end {if}
else begin else begin
Warning(@'argument missing; expected extended.'); Warning(@'argument missing; expected extended');
end; {else} end; {else}
end; {expect_extended} end; {expect_extended}
@ -271,11 +272,11 @@ var
ty := popType; ty := popType;
if ty <> nil then begin if ty <> nil then begin
if (ty^.kind <> pointerType) then begin if (ty^.kind <> pointerType) then begin
Warning(@'expected pointer.'); Warning(@'expected pointer');
end; {if} end; {if}
end {if} end {if}
else begin else begin
Warning(@'argument missing; expected pointer.'); Warning(@'argument missing; expected pointer');
end; {else} end; {else}
end; {expect_pointer} end; {expect_pointer}
@ -291,7 +292,7 @@ var
msg: stringPtr; msg: stringPtr;
begin begin
new(msg); new(msg);
msg^ := concat(prefix^, name^, '.'); msg^ := concat(prefix^, name^);
Warning(msg); Warning(msg);
dispose(msg); dispose(msg);
end; {error} end; {error}
@ -388,10 +389,10 @@ var
if has_length = l then begin if has_length = l then begin
expected := [cgWord, cgUWord]; expected := [cgWord, cgUWord];
name := @'wchar'; name := @'wchar_t';
if not feature_s_long then if not feature_s_long then
Warning(@'%ls not currently supported'); Warning(@'%ls is not currently supported');
end; {if} end; {if}
@ -419,11 +420,11 @@ var
{ ORCALib always treats n as int * } { ORCALib always treats n as int * }
{ n.b. - *n is undefined; orcalib pops a parm but doesn't store.} { n.b. - *n is undefined; orcalib pops a parm but doesn't store.}
{ C99 - support for length modifiers } { C99 - support for length modifiers }
if has_suppress then Warning(@'*n is undefined.'); if has_suppress then Warning(@'behavior of %*n is undefined');
has_suppress := false; has_suppress := false;
if (not feature_n_size) and (has_length <> default) then if (not feature_n_size) and (has_length <> default) then
Warning(@'size modifier for %n not currently supported.'); Warning(@'size modifier for %n is not currently supported');
case has_length of case has_length of
hh: begin hh: begin
@ -529,7 +530,7 @@ var
has_length := hh; has_length := hh;
state := st_format; state := st_format;
if not feature_hh then if not feature_hh then
Warning(@'hh modifier not currently supported'); Warning(@'hh modifier is not currently supported');
end {if} end {if}
else do_scanf_format; else do_scanf_format;
@ -538,7 +539,7 @@ var
has_length := ll; has_length := ll;
state := st_format; state := st_format;
if not feature_ll then if not feature_ll then
Warning(@'ll modifier not currently supported'); Warning(@'ll modifier is not currently supported');
end {if} end {if}
else do_scanf_format; else do_scanf_format;
@ -561,7 +562,7 @@ var
end; { for } end; { for }
if state <> st_text then if state <> st_text then
Warning(@'incomplete format specifier.'); Warning(@'incomplete format specifier');
if args <> nil then begin if args <> nil then begin
offset := 0; offset := 0;
@ -601,16 +602,16 @@ var
'b', 's': 'b', 's':
if has_length = l then begin if has_length = l then begin
if not feature_s_long then if not feature_s_long then
Warning(@'%ls not currently supported.'); Warning(@'%ls is not currently supported');
expect_pointer_to([cgWord, cgUWord], @'wchar') expect_pointer_to([cgWord, cgUWord], @'wchar_t')
end {if} end {if}
else expect_pointer_to([cgByte, cgUByte], @'char'); else expect_pointer_to([cgByte, cgUByte], @'char');
'n': begin 'n': begin
if (not feature_n_size) and (has_length <> default) then if (not feature_n_size) and (has_length <> default) then
Warning(@'size modifier for %n not currently supported.'); Warning(@'size modifier for %n is not currently supported');
case has_length of case has_length of
hh: hh:
@ -627,7 +628,7 @@ var
'c': 'c':
if has_length = l then begin if has_length = l then begin
if not feature_s_long then Warning(@'%lc not currently supported'); if not feature_s_long then Warning(@'%lc is not currently supported');
expect_int; expect_int;
end end
else begin else begin
@ -733,7 +734,7 @@ var
has_length := hh; has_length := hh;
state := st_format; state := st_format;
if not feature_hh then if not feature_hh then
Warning(@'hh modifier not currently supported'); Warning(@'hh modifier is not currently supported');
end end
else do_printf_format; else do_printf_format;
@ -742,7 +743,7 @@ var
has_length := ll; has_length := ll;
state := st_format; state := st_format;
if not feature_ll then if not feature_ll then
Warning(@'ll modifier not currently supported'); Warning(@'ll modifier is not currently supported');
end end
else do_printf_format; else do_printf_format;
@ -755,7 +756,7 @@ var
end; { for i } end; { for i }
if state <> st_text then if state <> st_text then
Warning(@'incomplete format specifier.'); Warning(@'incomplete format specifier');
if args <> nil then begin if args <> nil then begin
offset := 0; offset := 0;

View File

@ -171,12 +171,14 @@ la3 stz ch
! if needWriteLine then begin {do eol processing} ! if needWriteLine then begin {do eol processing}
! WriteLine; ! WriteLine;
! wroteLine := false;
! lineNumber := lineNumber+1; ! lineNumber := lineNumber+1;
! firstPtr := chPtr; ! firstPtr := chPtr;
! end; {if} ! end; {if}
lda needWriteLine lda needWriteLine
beq lb1 beq lb1
jsl WriteLine jsl WriteLine
stz wroteLine
inc lineNumber inc lineNumber
move4 chPtr,firstPtr move4 chPtr,firstPtr
lb1 anop lb1 anop
@ -273,12 +275,14 @@ lb5 anop
! if needWriteLine then begin {do eol processing} ! if needWriteLine then begin {do eol processing}
! WriteLine; ! WriteLine;
! wroteLine := false;
! lineNumber := lineNumber+1; ! lineNumber := lineNumber+1;
! firstPtr := chPtr; ! firstPtr := chPtr;
! end; {if} ! end; {if}
lda needWriteLine lda needWriteLine
beq lb6 beq lb6
jsl WriteLine jsl WriteLine
stz wroteLine
inc lineNumber inc lineNumber
move4 chPtr,firstPtr move4 chPtr,firstPtr
lb6 anop lb6 anop
@ -392,6 +396,7 @@ lc2b move4 chPtr,p1
sta ch sta ch
! if charKinds[ord(ch)] = ch_eol then begin ! if charKinds[ord(ch)] = ch_eol then begin
! WriteLine; ! WriteLine;
! wroteLine := false;
! lineNumber := lineNumber+1; ! lineNumber := lineNumber+1;
! firstPtr := pointer(ord4(chPtr)+1); ! firstPtr := pointer(ord4(chPtr)+1);
! end; {if} ! end; {if}
@ -401,6 +406,7 @@ lc2b move4 chPtr,p1
cmp #ch_eol cmp #ch_eol
bne lc3 bne lc3
jsl WriteLine jsl WriteLine
stz wroteLine
inc lineNumber inc lineNumber
add4 chPtr,#1,firstPtr add4 chPtr,#1,firstPtr
lc3 anop lc3 anop

View File

@ -155,6 +155,8 @@ procedure TermScanner;
{ Shut down the scanner. } { Shut down the scanner. }
procedure WriteLine;
{---------------------------------------------------------------} {---------------------------------------------------------------}
implementation implementation
@ -240,6 +242,7 @@ var
includeCount: 0..maxint; {nested include files (for EndInclude)} includeCount: 0..maxint; {nested include files (for EndInclude)}
macroFound: macroRecordPtr; {last macro found by IsDefined} macroFound: macroRecordPtr; {last macro found by IsDefined}
needWriteLine: boolean; {is there a line that needs to be written?} needWriteLine: boolean; {is there a line that needs to be written?}
wroteLine: boolean; {has the current line already been written?}
numErr: 0..maxErr; {number of errors in this line} numErr: 0..maxErr; {number of errors in this line}
oneStr: string[2]; {string form of __STDC__} oneStr: string[2]; {string form of __STDC__}
ispstring: boolean; {is the current string a p-string?} ispstring: boolean; {is the current string a p-string?}
@ -473,14 +476,16 @@ var
begin {WriteLine} begin {WriteLine}
if list or (numErr <> 0) then begin if list or (numErr <> 0) then begin
write(lineNumber:4, ' '); {write the line #} if not wroteLine then begin
cp := firstPtr; {write the characters in the line} write(lineNumber:4, ' '); {write the line #}
while cp <> chPtr do begin cp := firstPtr; {write the characters in the line}
if cp^ <> RETURN then while (cp <> eofPtr) and (cp^ <> RETURN) and (cp^ <> NEWLINE) do begin
write(chr(cp^)); write(chr(cp^));
cp := pointer(ord4(cp) + 1); cp := pointer(ord4(cp) + 1);
end; {while} end; {while}
writeln; {write the end of line character} writeln; {write the end of line character}
wroteLine := true;
end; {if}
for i := 1 to numErr do {write any errors} for i := 1 to numErr do {write any errors}
with errors[i] do begin with errors[i] do begin
if line = lineNumber then begin if line = lineNumber then begin
@ -614,8 +619,8 @@ if list or (numErr <> 0) then begin
121: msg := @'invalid digit for binary constant'; 121: msg := @'invalid digit for binary constant';
122: msg := @'arithmetic is not allowed on a pointer to an incomplete or function type'; 122: msg := @'arithmetic is not allowed on a pointer to an incomplete or function type';
123: msg := @'array element type may not be an incomplete or function type'; 123: msg := @'array element type may not be an incomplete or function type';
124: msg := @'invalid format string'; 124: msg := @'lint: invalid format string or arguments';
125: msg := @'format string is not a string literal'; 125: msg := @'lint: format string is not a string literal';
126: msg := @'scope rules may not be changed within a function'; 126: msg := @'scope rules may not be changed within a function';
127: msg := @'illegal storage class for declaration in for loop'; 127: msg := @'illegal storage class for declaration in for loop';
otherwise: Error(57); otherwise: Error(57);
@ -1780,6 +1785,7 @@ if gotName then begin {read the file name from the line}
if doInclude and progress then {note our progress} if doInclude and progress then {note our progress}
writeln('Including ', workString); writeln('Including ', workString);
WriteLine; {write the source line} WriteLine; {write the source line}
wroteLine := false;
lineNumber := lineNumber+1; lineNumber := lineNumber+1;
firstPtr := pointer(ord4(chPtr)+2); firstPtr := pointer(ord4(chPtr)+2);
needWriteLine := false; needWriteLine := false;
@ -3400,6 +3406,7 @@ includeCount := 0; {no pending calls to EndInclude}
lint := 0; {turn off lint checks} lint := 0; {turn off lint checks}
ch := chr(RETURN); {set the initial character} ch := chr(RETURN); {set the initial character}
needWriteLine := false; {no lines are pending} needWriteLine := false; {no lines are pending}
wroteLine := false; {current line has not been written}
switchLanguages := false; {not switching languages} switchLanguages := false; {not switching languages}
lastWasReturn := false; {last char was not return} lastWasReturn := false; {last char was not return}
doingstring := false; {not doing a string} doingstring := false; {not doing a string}

4
make
View File

@ -114,6 +114,7 @@ if {#} == 0
set parser parser set parser parser
set symbol symbol set symbol symbol
set header header set header header
set printf printf
end end
Newer obj/symbol.a symbol.pas symbol.print symbol.asm Newer obj/symbol.a symbol.pas symbol.print symbol.asm
@ -157,6 +158,7 @@ if {#} == 0
if {status} != 0 if {status} != 0
set cc cc set cc cc
set printf printf set printf printf
set expression expression
end end
else else
@ -182,7 +184,7 @@ if "{table}" == table
end end
set list "" set list ""
set list {ccommon} {mm} {printf} {cgi} {scanner} {symbol} {header} set list {ccommon} {mm} {cgi} {scanner} {symbol} {header} {printf}
set list {list} {expression} {cgc} {asm} {parser} {cc} {objout} {native} set list {list} {expression} {cgc} {asm} {parser} {cc} {objout} {native}
set list {list} {gen} {dag} set list {list} {gen} {dag}