diff --git a/Printf.pas b/Printf.pas index f3b9e63..78b915b 100644 --- a/Printf.pas +++ b/Printf.pas @@ -15,7 +15,7 @@ interface {$LibPrefix '0/obj/'} -uses CCommon; +uses CCommon, Scanner; {$segment 'PRINTF'} @@ -65,9 +65,6 @@ type types = set of baseTypeEnum; -procedure Error (err: integer); extern; {in scanner.pas} - - function FormatClassify {fname: stringPtr): fmt_type}; { @@ -130,9 +127,11 @@ var begin {Warning} if error_count = 0 then begin + WriteLine; Error(124); + WriteLine; if s <> nil then begin - Write(' "'); + Write(' > "'); for i := 1 to s^.length do begin c := s^.str[i]; if (c = '"') or (ord(c) < $20) or (ord(c) > $7f) then c := '.'; @@ -143,11 +142,13 @@ var end; {if} error_count := error_count + 1; 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(' '); Write('^ '); end; {if} - Write('Warning: '); WriteLn(msg^); end; {Warning} @@ -159,11 +160,11 @@ var begin {WarningConversionChar} if (ord(c) >= $20) and (ord(c) <= $7f) then begin new(msg); - msg^ := concat('unknown conversion type character ''', c, ''' in format.'); + msg^ := concat('unknown conversion type character ''', c, ''' in format'); Warning(msg); dispose(msg); end {if} - else Warning(@'unknown conversion type character in format.'); + else Warning(@'unknown conversion type character in format'); end; {WarningConversionChar} procedure WarningExtraArgs(i: integer); @@ -172,7 +173,7 @@ var msg: stringPtr; begin {WarningExtraArgs} new(msg); - msg^ := concat('extra arguments provided (', cnvis(i), ' expected).'); + msg^ := concat('extra argument(s) provided (', cnvis(i), ' expected)'); Warning(msg); dispose(msg); end; {WarningExtraArgs} @@ -200,7 +201,7 @@ var ty := popType; if ty <> nil 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} else begin @@ -217,11 +218,11 @@ var if ty <> nil then begin if (ty^.kind <> scalarType) or not (ty^.baseType in [cgWord, cgUWord, cgByte, cgUByte]) then begin - Warning(@'expected int.'); + Warning(@'expected int'); end; {if} end {if} else begin - Warning(@'argument missing; expected int.'); + Warning(@'argument missing; expected int'); end; {else} end; {expect_int} @@ -235,11 +236,11 @@ var if ty <> nil then begin if (ty^.kind <> scalarType) or not (ty^.baseType in [cgWord, cgUWord, cgByte, cgUByte]) then begin - Warning(@'expected char.'); + Warning(@'expected char'); end; {if} end {if} else begin - Warning(@'argument missing; expected char.'); + Warning(@'argument missing; expected char'); end; {else} end; {expect_char} @@ -254,11 +255,11 @@ var if ty <> nil then begin if (ty^.kind <> scalarType) or not (ty^.baseType in [cgExtended, cgReal, cgDouble]) then begin - Warning(@'expected extended.'); + Warning(@'expected extended'); end; {if} end {if} else begin - Warning(@'argument missing; expected extended.'); + Warning(@'argument missing; expected extended'); end; {else} end; {expect_extended} @@ -271,11 +272,11 @@ var ty := popType; if ty <> nil then begin if (ty^.kind <> pointerType) then begin - Warning(@'expected pointer.'); + Warning(@'expected pointer'); end; {if} end {if} else begin - Warning(@'argument missing; expected pointer.'); + Warning(@'argument missing; expected pointer'); end; {else} end; {expect_pointer} @@ -291,7 +292,7 @@ var msg: stringPtr; begin new(msg); - msg^ := concat(prefix^, name^, '.'); + msg^ := concat(prefix^, name^); Warning(msg); dispose(msg); end; {error} @@ -388,10 +389,10 @@ var if has_length = l then begin expected := [cgWord, cgUWord]; - name := @'wchar'; + name := @'wchar_t'; if not feature_s_long then - Warning(@'%ls not currently supported'); + Warning(@'%ls is not currently supported'); end; {if} @@ -419,11 +420,11 @@ var { ORCALib always treats n as int * } { n.b. - *n is undefined; orcalib pops a parm but doesn't store.} { 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; 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 hh: begin @@ -529,7 +530,7 @@ var has_length := hh; state := st_format; if not feature_hh then - Warning(@'hh modifier not currently supported'); + Warning(@'hh modifier is not currently supported'); end {if} else do_scanf_format; @@ -538,7 +539,7 @@ var has_length := ll; state := st_format; if not feature_ll then - Warning(@'ll modifier not currently supported'); + Warning(@'ll modifier is not currently supported'); end {if} else do_scanf_format; @@ -561,7 +562,7 @@ var end; { for } if state <> st_text then - Warning(@'incomplete format specifier.'); + Warning(@'incomplete format specifier'); if args <> nil then begin offset := 0; @@ -601,16 +602,16 @@ var 'b', 's': if has_length = l then begin 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} else expect_pointer_to([cgByte, cgUByte], @'char'); 'n': begin 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 hh: @@ -627,7 +628,7 @@ var 'c': 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; end else begin @@ -733,7 +734,7 @@ var has_length := hh; state := st_format; if not feature_hh then - Warning(@'hh modifier not currently supported'); + Warning(@'hh modifier is not currently supported'); end else do_printf_format; @@ -742,7 +743,7 @@ var has_length := ll; state := st_format; if not feature_ll then - Warning(@'ll modifier not currently supported'); + Warning(@'ll modifier is not currently supported'); end else do_printf_format; @@ -755,7 +756,7 @@ var end; { for i } if state <> st_text then - Warning(@'incomplete format specifier.'); + Warning(@'incomplete format specifier'); if args <> nil then begin offset := 0; diff --git a/Scanner.asm b/Scanner.asm index 3183f67..3ae466c 100644 --- a/Scanner.asm +++ b/Scanner.asm @@ -171,12 +171,14 @@ la3 stz ch ! if needWriteLine then begin {do eol processing} ! WriteLine; +! wroteLine := false; ! lineNumber := lineNumber+1; ! firstPtr := chPtr; ! end; {if} lda needWriteLine beq lb1 jsl WriteLine + stz wroteLine inc lineNumber move4 chPtr,firstPtr lb1 anop @@ -273,12 +275,14 @@ lb5 anop ! if needWriteLine then begin {do eol processing} ! WriteLine; +! wroteLine := false; ! lineNumber := lineNumber+1; ! firstPtr := chPtr; ! end; {if} lda needWriteLine beq lb6 jsl WriteLine + stz wroteLine inc lineNumber move4 chPtr,firstPtr lb6 anop @@ -392,6 +396,7 @@ lc2b move4 chPtr,p1 sta ch ! if charKinds[ord(ch)] = ch_eol then begin ! WriteLine; +! wroteLine := false; ! lineNumber := lineNumber+1; ! firstPtr := pointer(ord4(chPtr)+1); ! end; {if} @@ -401,6 +406,7 @@ lc2b move4 chPtr,p1 cmp #ch_eol bne lc3 jsl WriteLine + stz wroteLine inc lineNumber add4 chPtr,#1,firstPtr lc3 anop diff --git a/Scanner.pas b/Scanner.pas index a07f87a..2f86446 100644 --- a/Scanner.pas +++ b/Scanner.pas @@ -155,6 +155,8 @@ procedure TermScanner; { Shut down the scanner. } +procedure WriteLine; + {---------------------------------------------------------------} implementation @@ -240,6 +242,7 @@ var includeCount: 0..maxint; {nested include files (for EndInclude)} macroFound: macroRecordPtr; {last macro found by IsDefined} 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} oneStr: string[2]; {string form of __STDC__} ispstring: boolean; {is the current string a p-string?} @@ -473,14 +476,16 @@ var begin {WriteLine} if list or (numErr <> 0) then begin - write(lineNumber:4, ' '); {write the line #} - cp := firstPtr; {write the characters in the line} - while cp <> chPtr do begin - if cp^ <> RETURN then - write(chr(cp^)); - cp := pointer(ord4(cp) + 1); - end; {while} - writeln; {write the end of line character} + if not wroteLine then begin + write(lineNumber:4, ' '); {write the line #} + cp := firstPtr; {write the characters in the line} + while (cp <> eofPtr) and (cp^ <> RETURN) and (cp^ <> NEWLINE) do begin + write(chr(cp^)); + cp := pointer(ord4(cp) + 1); + end; {while} + writeln; {write the end of line character} + wroteLine := true; + end; {if} for i := 1 to numErr do {write any errors} with errors[i] do begin if line = lineNumber then begin @@ -614,8 +619,8 @@ if list or (numErr <> 0) then begin 121: msg := @'invalid digit for binary constant'; 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'; - 124: msg := @'invalid format string'; - 125: msg := @'format string is not a string literal'; + 124: msg := @'lint: invalid format string or arguments'; + 125: msg := @'lint: format string is not a string literal'; 126: msg := @'scope rules may not be changed within a function'; 127: msg := @'illegal storage class for declaration in for loop'; 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} writeln('Including ', workString); WriteLine; {write the source line} + wroteLine := false; lineNumber := lineNumber+1; firstPtr := pointer(ord4(chPtr)+2); needWriteLine := false; @@ -3400,6 +3406,7 @@ includeCount := 0; {no pending calls to EndInclude} lint := 0; {turn off lint checks} ch := chr(RETURN); {set the initial character} needWriteLine := false; {no lines are pending} +wroteLine := false; {current line has not been written} switchLanguages := false; {not switching languages} lastWasReturn := false; {last char was not return} doingstring := false; {not doing a string} diff --git a/make b/make index 1fbf264..babad39 100644 --- a/make +++ b/make @@ -114,6 +114,7 @@ if {#} == 0 set parser parser set symbol symbol set header header + set printf printf end Newer obj/symbol.a symbol.pas symbol.print symbol.asm @@ -157,6 +158,7 @@ if {#} == 0 if {status} != 0 set cc cc set printf printf + set expression expression end else @@ -182,7 +184,7 @@ if "{table}" == table end 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} {gen} {dag}