mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2025-01-02 19:29:21 +00:00
Make sure #pragma expand is properly applied in all cases.
There were various places where the flag for macro expansions was saved, set to false, and then later restored. If #pragma expand was used within those areas, it would not be properly applied. Here is an example showing that problem: void f(void #pragma expand 1 ) {} This could also affect some uses of #pragma expand within precompiled headers, e.g.: #pragma expand 1 #include "a.h" #undef foobar #include "b.h" ... Also, add a note saying that code in precompiled headers will not be expanded. (This has always been the case, but was not clearly documented.)
This commit is contained in:
parent
8c0d65616c
commit
3893db1346
40
Parser.pas
40
Parser.pas
@ -436,7 +436,7 @@ label 1;
|
|||||||
|
|
||||||
var
|
var
|
||||||
lToken,tToken: tokenType; {for look-ahead}
|
lToken,tToken: tokenType; {for look-ahead}
|
||||||
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
|
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
|
||||||
|
|
||||||
|
|
||||||
function GetSwitchRecord: statementPtr;
|
function GetSwitchRecord: statementPtr;
|
||||||
@ -981,14 +981,14 @@ case token.kind of
|
|||||||
gotosy: GotoStatement;
|
gotosy: GotoStatement;
|
||||||
typedef,
|
typedef,
|
||||||
ident: begin
|
ident: begin
|
||||||
lPrintMacroExpansions := printMacroExpansions;
|
lSuppressMacroExpansions := suppressMacroExpansions;
|
||||||
printMacroExpansions := false;
|
suppressMacroExpansions := true;
|
||||||
lToken := token;
|
lToken := token;
|
||||||
NextToken;
|
NextToken;
|
||||||
tToken := token;
|
tToken := token;
|
||||||
PutBackToken(token, true);
|
PutBackToken(token, true);
|
||||||
token := lToken;
|
token := lToken;
|
||||||
printMacroExpansions := lPrintMacroExpansions;
|
suppressMacroExpansions := lSuppressMacroExpansions;
|
||||||
if tToken.kind = colonch then begin
|
if tToken.kind = colonch then begin
|
||||||
LabelStatement;
|
LabelStatement;
|
||||||
goto 1;
|
goto 1;
|
||||||
@ -1099,7 +1099,7 @@ var
|
|||||||
ltoken: tokenType; {for putting ; on stack}
|
ltoken: tokenType; {for putting ; on stack}
|
||||||
stPtr: statementPtr; {work pointer}
|
stPtr: statementPtr; {work pointer}
|
||||||
tl,tk: tokenStackPtr; {for forming expression list}
|
tl,tk: tokenStackPtr; {for forming expression list}
|
||||||
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
|
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
|
||||||
|
|
||||||
begin {EndForStatement}
|
begin {EndForStatement}
|
||||||
if c99Scope then PopTable;
|
if c99Scope then PopTable;
|
||||||
@ -1118,13 +1118,13 @@ if tl <> nil then begin
|
|||||||
tl := tl^.next;
|
tl := tl^.next;
|
||||||
dispose(tk);
|
dispose(tk);
|
||||||
end; {while}
|
end; {while}
|
||||||
lPrintMacroExpansions := printMacroExpansions; {inhibit token echo}
|
lSuppressMacroExpansions := suppressMacroExpansions; {inhibit token echo}
|
||||||
printMacroExpansions := false;
|
suppressMacroExpansions := true;
|
||||||
NextToken; {evaluate the expression}
|
NextToken; {evaluate the expression}
|
||||||
Expression(normalExpression, [semicolonch]);
|
Expression(normalExpression, [semicolonch]);
|
||||||
Gen0t(pc_pop, UsualUnaryConversions);
|
Gen0t(pc_pop, UsualUnaryConversions);
|
||||||
NextToken; {skip the semicolon}
|
NextToken; {skip the semicolon}
|
||||||
printMacroExpansions := lPrintMacroExpansions;
|
suppressMacroExpansions := lSuppressMacroExpansions;
|
||||||
end; {if}
|
end; {if}
|
||||||
|
|
||||||
Gen1(pc_ujp, stPtr^.forLoop); {loop to the test}
|
Gen1(pc_ujp, stPtr^.forLoop); {loop to the test}
|
||||||
@ -1329,7 +1329,7 @@ var
|
|||||||
lstorageClass: tokenEnum; {storage class of the declaration}
|
lstorageClass: tokenEnum; {storage class of the declaration}
|
||||||
ltypeSpec: typePtr; {type specifier}
|
ltypeSpec: typePtr; {type specifier}
|
||||||
luseGlobalPool: boolean; {local copy of useGlobalPool}
|
luseGlobalPool: boolean; {local copy of useGlobalPool}
|
||||||
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
|
lSuppressMacroExpansions: boolean;{local copy of suppressMacroExpansions}
|
||||||
|
|
||||||
begin {StackDeclarations}
|
begin {StackDeclarations}
|
||||||
lastWasIdentifier := false; {used to see if the declaration is a fn}
|
lastWasIdentifier := false; {used to see if the declaration is a fn}
|
||||||
@ -1458,10 +1458,10 @@ var
|
|||||||
if token.symbolPtr^.itype^.baseType = cgVoid then
|
if token.symbolPtr^.itype^.baseType = cgVoid then
|
||||||
isVoid := true;
|
isVoid := true;
|
||||||
if isVoid then begin {check for a void prototype}
|
if isVoid then begin {check for a void prototype}
|
||||||
lPrintMacroExpansions := printMacroExpansions;
|
lSuppressMacroExpansions := suppressMacroExpansions;
|
||||||
printMacroExpansions := false;
|
suppressMacroExpansions := true;
|
||||||
NextToken;
|
NextToken;
|
||||||
printMacroExpansions := lPrintMacroExpansions;
|
suppressMacroExpansions := lSuppressMacroExpansions;
|
||||||
if token.kind = rparench then begin
|
if token.kind = rparench then begin
|
||||||
PutBackToken(token, false);
|
PutBackToken(token, false);
|
||||||
NextToken;
|
NextToken;
|
||||||
@ -2392,7 +2392,7 @@ var
|
|||||||
ip: identPtr; {for tracing field lists}
|
ip: identPtr; {for tracing field lists}
|
||||||
kind: typeKind; {base type of an initializer}
|
kind: typeKind; {base type of an initializer}
|
||||||
ktp: typePtr; {array type with definedTypes removed}
|
ktp: typePtr; {array type with definedTypes removed}
|
||||||
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
|
lSuppressMacroExpansions: boolean;{local copy of suppressMacroExpansions}
|
||||||
stringElementType: typePtr; {element type of string literal}
|
stringElementType: typePtr; {element type of string literal}
|
||||||
stringLength: integer; {elements in a string literal}
|
stringLength: integer; {elements in a string literal}
|
||||||
|
|
||||||
@ -2618,12 +2618,12 @@ var
|
|||||||
count := tp^.size;
|
count := tp^.size;
|
||||||
ip := tp^.fieldList;
|
ip := tp^.fieldList;
|
||||||
bitCount := 0;
|
bitCount := 0;
|
||||||
lPrintMacroExpansions := printMacroExpansions;
|
lSuppressMacroExpansions := suppressMacroExpansions;
|
||||||
while (ip <> nil) and (ip^.itype^.size > 0) do begin
|
while (ip <> nil) and (ip^.itype^.size > 0) do begin
|
||||||
if ip^.isForwardDeclared then
|
if ip^.isForwardDeclared then
|
||||||
ResolveForwardReference(ip);
|
ResolveForwardReference(ip);
|
||||||
if token.kind = rbracech then begin {initialize this field to 0}
|
if token.kind = rbracech then begin {initialize this field to 0}
|
||||||
printMacroExpansions := false; {inhibit token echo}
|
suppressMacroExpansions := true; {inhibit token echo}
|
||||||
PutBackToken(token, false);
|
PutBackToken(token, false);
|
||||||
PutBackToken(token, false);
|
PutBackToken(token, false);
|
||||||
token.kind := intconst;
|
token.kind := intconst;
|
||||||
@ -2672,7 +2672,7 @@ var
|
|||||||
if count > 0 then
|
if count > 0 then
|
||||||
if variable^.storage in [external,global,private] then
|
if variable^.storage in [external,global,private] then
|
||||||
Fill(count, sCharPtr);
|
Fill(count, sCharPtr);
|
||||||
printMacroExpansions := lPrintMacroExpansions;
|
suppressMacroExpansions := lSuppressMacroExpansions;
|
||||||
end {if}
|
end {if}
|
||||||
else {struct/union assignment initializer}
|
else {struct/union assignment initializer}
|
||||||
GetInitializerValue(tp, bitsize, bitdisp);
|
GetInitializerValue(tp, bitsize, bitdisp);
|
||||||
@ -4245,7 +4245,7 @@ var
|
|||||||
lToken: tokenType; {temporary copy of old token}
|
lToken: tokenType; {temporary copy of old token}
|
||||||
nToken: tokenType; {new token}
|
nToken: tokenType; {new token}
|
||||||
hasStatementNext: boolean; {is a stmt next within a compound stmt?}
|
hasStatementNext: boolean; {is a stmt next within a compound stmt?}
|
||||||
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
|
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
|
||||||
|
|
||||||
begin {DoStatement}
|
begin {DoStatement}
|
||||||
case statementList^.kind of
|
case statementList^.kind of
|
||||||
@ -4264,10 +4264,10 @@ case statementList^.kind of
|
|||||||
DoDeclaration(false)
|
DoDeclaration(false)
|
||||||
else begin
|
else begin
|
||||||
lToken := token;
|
lToken := token;
|
||||||
lPrintMacroExpansions := printMacroExpansions; {inhibit token echo}
|
lSuppressMacroExpansions := suppressMacroExpansions;
|
||||||
printMacroExpansions := false;
|
suppressMacroExpansions := true; {inhibit token echo}
|
||||||
NextToken;
|
NextToken;
|
||||||
printMacroExpansions := lPrintMacroExpansions;
|
suppressMacroExpansions := lSuppressMacroExpansions;
|
||||||
nToken := token;
|
nToken := token;
|
||||||
PutBackToken(nToken, false);
|
PutBackToken(nToken, false);
|
||||||
token := lToken;
|
token := lToken;
|
||||||
|
44
Scanner.pas
44
Scanner.pas
@ -77,6 +77,7 @@ var
|
|||||||
macros: ^macroTable; {preprocessor macro list}
|
macros: ^macroTable; {preprocessor macro list}
|
||||||
pathList: pathRecordPtr; {additional search paths}
|
pathList: pathRecordPtr; {additional search paths}
|
||||||
printMacroExpansions: boolean; {print the token list?}
|
printMacroExpansions: boolean; {print the token list?}
|
||||||
|
suppressMacroExpansions: boolean; {suppress printing even if requested?}
|
||||||
reportEOL: boolean; {report eolsy as a token?}
|
reportEOL: boolean; {report eolsy as a token?}
|
||||||
token: tokenType; {next token to process}
|
token: tokenType; {next token to process}
|
||||||
|
|
||||||
@ -1098,7 +1099,7 @@ while mPtr <> nil do begin
|
|||||||
FindMacro := mPtr
|
FindMacro := mPtr
|
||||||
else if tokenList = nil then begin
|
else if tokenList = nil then begin
|
||||||
while charKinds[ord(ch)] in [ch_white, ch_eol] do begin
|
while charKinds[ord(ch)] in [ch_white, ch_eol] do begin
|
||||||
if printMacroExpansions then
|
if printMacroExpansions and not suppressMacroExpansions then
|
||||||
if charKinds[ord(ch)] = ch_eol then
|
if charKinds[ord(ch)] = ch_eol then
|
||||||
writeln
|
writeln
|
||||||
else
|
else
|
||||||
@ -1559,7 +1560,7 @@ var
|
|||||||
i: integer; {loop counter}
|
i: integer; {loop counter}
|
||||||
inhibit: boolean; {inhibit parameter expansion?}
|
inhibit: boolean; {inhibit parameter expansion?}
|
||||||
lexpandMacros: boolean; {local copy of expandMacros}
|
lexpandMacros: boolean; {local copy of expandMacros}
|
||||||
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
|
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
|
||||||
mPtr: macroRecordPtr; {for checking list of macros}
|
mPtr: macroRecordPtr; {for checking list of macros}
|
||||||
newParm: parameterPtr; {for building a new parameter entry}
|
newParm: parameterPtr; {for building a new parameter entry}
|
||||||
tlPtr, tPtr, tcPtr, lastPtr: tokenListRecordPtr; {work pointers}
|
tlPtr, tPtr, tcPtr, lastPtr: tokenListRecordPtr; {work pointers}
|
||||||
@ -1573,8 +1574,8 @@ var
|
|||||||
endParmTokens: tokenSet; {tokens that end a parameter}
|
endParmTokens: tokenSet; {tokens that end a parameter}
|
||||||
|
|
||||||
begin {Expand}
|
begin {Expand}
|
||||||
lPrintMacroExpansions := printMacroExpansions; {inhibit token printing}
|
lSuppressMacroExpansions := suppressMacroExpansions; {inhibit token printing}
|
||||||
printMacroExpansions := false;
|
suppressMacroExpansions := true;
|
||||||
lexpandMacros := expandMacros; {prevent expansion of parameters}
|
lexpandMacros := expandMacros; {prevent expansion of parameters}
|
||||||
expandMacros := false;
|
expandMacros := false;
|
||||||
saveNumber := true; {save numeric strings}
|
saveNumber := true; {save numeric strings}
|
||||||
@ -1859,7 +1860,7 @@ while parms <> nil do begin {dispose of the parameter list}
|
|||||||
parms := parmEnd;
|
parms := parmEnd;
|
||||||
end; {while}
|
end; {while}
|
||||||
expandMacros := lexpandMacros; {restore the flags}
|
expandMacros := lexpandMacros; {restore the flags}
|
||||||
printMacroExpansions := lPrintMacroExpansions;
|
suppressMacroExpansions := lSuppressMacroExpansions;
|
||||||
saveNumber := false; {stop saving numeric strings}
|
saveNumber := false; {stop saving numeric strings}
|
||||||
end; {Expand}
|
end; {Expand}
|
||||||
|
|
||||||
@ -2202,7 +2203,7 @@ procedure PreProcess;
|
|||||||
label 2;
|
label 2;
|
||||||
|
|
||||||
var
|
var
|
||||||
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
|
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
|
||||||
lReportEOL: boolean; {local copy of reportEOL}
|
lReportEOL: boolean; {local copy of reportEOL}
|
||||||
tSkipping: boolean; {temp copy of the skipping variable}
|
tSkipping: boolean; {temp copy of the skipping variable}
|
||||||
val: integer; {expression value}
|
val: integer; {expression value}
|
||||||
@ -2990,8 +2991,8 @@ var
|
|||||||
|
|
||||||
|
|
||||||
begin {PreProcess}
|
begin {PreProcess}
|
||||||
lPrintMacroExpansions := printMacroExpansions; {inhibit token printing}
|
lSuppressMacroExpansions := suppressMacroExpansions; {inhibit token printing}
|
||||||
printMacroExpansions := false;
|
suppressMacroExpansions := true;
|
||||||
lReportEOL := reportEOL; {we need to see eol's}
|
lReportEOL := reportEOL; {we need to see eol's}
|
||||||
reportEOL := true;
|
reportEOL := true;
|
||||||
tSkipping := skipping; {don't skip the directive name!}
|
tSkipping := skipping; {don't skip the directive name!}
|
||||||
@ -3153,7 +3154,7 @@ if ch in ['a','d','e','i','l','p','u','w'] then begin
|
|||||||
else if token.name^ = 'expand' then begin
|
else if token.name^ = 'expand' then begin
|
||||||
FlagPragmas(p_expand);
|
FlagPragmas(p_expand);
|
||||||
NumericDirective;
|
NumericDirective;
|
||||||
lPrintMacroExpansions := expressionValue <> 0;
|
printMacroExpansions := expressionValue <> 0;
|
||||||
if token.kind <> eolsy then
|
if token.kind <> eolsy then
|
||||||
Error(11);
|
Error(11);
|
||||||
end {else if}
|
end {else if}
|
||||||
@ -3349,7 +3350,7 @@ flagOverflows := true;
|
|||||||
expandMacros := true;
|
expandMacros := true;
|
||||||
charKinds[ord('#')] := illegal; {don't allow # as a token}
|
charKinds[ord('#')] := illegal; {don't allow # as a token}
|
||||||
reportEOL := lReportEOL; {restore flags}
|
reportEOL := lReportEOL; {restore flags}
|
||||||
printMacroExpansions := lPrintMacroExpansions;
|
suppressMacroExpansions := lSuppressMacroExpansions;
|
||||||
skipping := tskipping;
|
skipping := tskipping;
|
||||||
if nextLineNumber >= 0 then
|
if nextLineNumber >= 0 then
|
||||||
lineNumber := nextLineNumber;
|
lineNumber := nextLineNumber;
|
||||||
@ -4082,6 +4083,7 @@ var
|
|||||||
|
|
||||||
begin {InitScanner}
|
begin {InitScanner}
|
||||||
printMacroExpansions := false; {don't print the token list}
|
printMacroExpansions := false; {don't print the token list}
|
||||||
|
suppressMacroExpansions := false; {...but do not suppress token printing}
|
||||||
skipIllegalTokens := false; {flag illegal tokens in skipped code}
|
skipIllegalTokens := false; {flag illegal tokens in skipped code}
|
||||||
allowLongIntChar := false; {allow long int char constants}
|
allowLongIntChar := false; {allow long int char constants}
|
||||||
allowTokensAfterEndif := false; {allow tokens after #endif}
|
allowTokensAfterEndif := false; {allow tokens after #endif}
|
||||||
@ -4420,7 +4422,7 @@ var
|
|||||||
mPtr: macroRecordPtr; {for checking list of macros}
|
mPtr: macroRecordPtr; {for checking list of macros}
|
||||||
rword: tokenEnum; {loop variable}
|
rword: tokenEnum; {loop variable}
|
||||||
sp: stringPtr; {for saving identifier names}
|
sp: stringPtr; {for saving identifier names}
|
||||||
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
|
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
|
||||||
|
|
||||||
begin {CheckIdentifier}
|
begin {CheckIdentifier}
|
||||||
if expandMacros then {handle macro expansions}
|
if expandMacros then {handle macro expansions}
|
||||||
@ -4428,10 +4430,10 @@ if expandMacros then {handle macro expansions}
|
|||||||
mPtr := FindMacro(@workstring);
|
mPtr := FindMacro(@workstring);
|
||||||
if mPtr <> nil then begin
|
if mPtr <> nil then begin
|
||||||
Expand(mPtr);
|
Expand(mPtr);
|
||||||
lPrintMacroExpansions := printMacroExpansions;
|
lSuppressMacroExpansions := suppressMacroExpansions;
|
||||||
printMacroExpansions := false;
|
suppressMacroExpansions := true;
|
||||||
NextToken;
|
NextToken;
|
||||||
printMacroExpansions := lPrintMacroExpansions;
|
suppressMacroExpansions := lSuppressMacroExpansions;
|
||||||
goto 1;
|
goto 1;
|
||||||
end;
|
end;
|
||||||
end; {if}
|
end; {if}
|
||||||
@ -4487,7 +4489,7 @@ var
|
|||||||
i,j: 0..maxint; {loop/index counter}
|
i,j: 0..maxint; {loop/index counter}
|
||||||
inhibit: boolean; {inhibit macro expansion?}
|
inhibit: boolean; {inhibit macro expansion?}
|
||||||
lExpandMacros: boolean; {local copy of expandMacros}
|
lExpandMacros: boolean; {local copy of expandMacros}
|
||||||
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
|
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
|
||||||
mPtr: macroRecordPtr; {for checking list of macros}
|
mPtr: macroRecordPtr; {for checking list of macros}
|
||||||
setLength: boolean; {is the current string a p-string?}
|
setLength: boolean; {is the current string a p-string?}
|
||||||
tPtr: tokenListRecordPtr; {for removing tokens from putback buffer}
|
tPtr: tokenListRecordPtr; {for removing tokens from putback buffer}
|
||||||
@ -4805,7 +4807,7 @@ while charKinds[ord(ch)] in [illegal,ch_white,ch_eol] do begin
|
|||||||
goto 2;
|
goto 2;
|
||||||
end {if}
|
end {if}
|
||||||
else begin {skip white space}
|
else begin {skip white space}
|
||||||
if printMacroExpansions then
|
if printMacroExpansions and not suppressMacroExpansions then
|
||||||
if charKinds[ord(ch)] = ch_eol then begin
|
if charKinds[ord(ch)] = ch_eol then begin
|
||||||
StopSpin;
|
StopSpin;
|
||||||
writeln;
|
writeln;
|
||||||
@ -5254,12 +5256,12 @@ if (token.kind = stringconst) and not mergingStrings {handle adjacent strings}
|
|||||||
goto 1;
|
goto 1;
|
||||||
end; {if}
|
end; {if}
|
||||||
tToken := token;
|
tToken := token;
|
||||||
lPrintMacroExpansions := printMacroExpansions;
|
lSuppressMacroExpansions := suppressMacroExpansions;
|
||||||
printMacroExpansions := false;
|
suppressMacroExpansions := true;
|
||||||
mergingStrings := true;
|
mergingStrings := true;
|
||||||
NextToken;
|
NextToken;
|
||||||
mergingStrings := false;
|
mergingStrings := false;
|
||||||
printMacroExpansions := lPrintMacroExpansions;
|
suppressMacroExpansions := lSuppressMacroExpansions;
|
||||||
if token.kind = stringconst then begin
|
if token.kind = stringconst then begin
|
||||||
Merge(tToken, token);
|
Merge(tToken, token);
|
||||||
done := false;
|
done := false;
|
||||||
@ -5280,8 +5282,8 @@ if doingPPExpression then begin
|
|||||||
if token.kind = typedef then
|
if token.kind = typedef then
|
||||||
token.kind := ident;
|
token.kind := ident;
|
||||||
end; {if}
|
end; {if}
|
||||||
if printMacroExpansions then {print the token stream}
|
if printMacroExpansions and not suppressMacroExpansions then
|
||||||
PrintToken(token);
|
PrintToken(token); {print the token stream}
|
||||||
end; {NextToken}
|
end; {NextToken}
|
||||||
|
|
||||||
|
|
||||||
|
4
cc.notes
4
cc.notes
@ -185,6 +185,8 @@ p. 257
|
|||||||
|
|
||||||
The #pragma expand directive has been changed to use three-digit octal escape sequences (rather than hexadecimal ones) in strings it outputs. (This ensures that subsequent characters in the string cannot be interpreted as part of the escape sequence.)
|
The #pragma expand directive has been changed to use three-digit octal escape sequences (rather than hexadecimal ones) in strings it outputs. (This ensures that subsequent characters in the string cannot be interpreted as part of the escape sequence.)
|
||||||
|
|
||||||
|
If precompiled headers are being used, #pragma expand will not print the tokens for the portion of the code that has been precompiled and represented in the .sym file. It will still print the tokens for the remainder of the code (including all functions). If you want to see the tokens for all of the code, you can use the -I flag to make ORCA/C ignore the .sym file.
|
||||||
|
|
||||||
p. 258
|
p. 258
|
||||||
|
|
||||||
The #pragma ignore directive supports several new bits.
|
The #pragma ignore directive supports several new bits.
|
||||||
@ -1778,6 +1780,8 @@ int foo(int[42]);
|
|||||||
|
|
||||||
180. Certain #undef directives might be ignored when using a .sym file.
|
180. Certain #undef directives might be ignored when using a .sym file.
|
||||||
|
|
||||||
|
181. #pragma expand might not work correctly when used in certain places.
|
||||||
|
|
||||||
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
|
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
|
||||||
|
|
||||||
1. In some situations, fread() reread the first 1K or so of the file.
|
1. In some situations, fread() reread the first 1K or so of the file.
|
||||||
|
Loading…
Reference in New Issue
Block a user