Pelles C forum

Pelles C => Bug reports => Topic started by: Mikehg on November 06, 2004, 11:38:23 PM

Title: fseek not seeking
Post by: Mikehg on November 06, 2004, 11:38:23 PM
Hi Pelle,

Yeah, me again :)

Using fseek to offset from the current position seems to be giving some strange results?
Code: [Select]

int cnt;
WORD ChunkID;
FILE* FP1;
 FP1=fopen(FileName,"rb");
GET(FP1,&ChunkID,sizeof(WORD));
cnt =ftell(FP1);  // cnt = 2 Here
fseek(FP1,10,SEEK_CUR );
cnt =ftell(FP1); // cnt = 0x20A Here
fclose(FP1);


It seems like something weird is going on with the highorder bits of the offset number?

Thanks,
Mike H.
Title: fseek not seeking
Post by: Mikehg on November 06, 2004, 11:42:20 PM
btw, GET is a BCX macro:

#define GET(A,B,C)fread(B,1,C,A)

Also, ths person that wrote the original program stated that the problem started after 2.9 beta 5 if that is any help?

Mike H.
Title: fseek not seeking
Post by: JohnF on November 07, 2004, 08:45:16 AM
Quote from: "Mikehg"
btw, GET is a BCX macro:

#define GET(A,B,C)fread(B,1,C,A)

Also, ths person that wrote the original program stated that the problem started after 2.9 beta 5 if that is any help?

Mike H.


I just ran your code here with no problem.

Code: [Select]

#define GET(A,B,C)fread(B,1,C,A)
int main(void)
{
char FileName[] = "main.c";
int cnt;
WORD ChunkID;
FILE * FP1;
FP1 = fopen(FileName,"rb");
    GET(FP1,&ChunkID,sizeof(WORD));
cnt = ftell(FP1);   // cnt = 2 Here
printf("%d\n", cnt);
fseek(FP1,10,SEEK_CUR );
cnt = ftell(FP1); // cnt = 12 Here
printf("%d\n", cnt);
fclose(FP1);
return 0;
}


John
Title: fseek not seeking
Post by: Mikehg on November 07, 2004, 09:05:43 AM
Hi John,

Are you using the latest version ?

Are you linking with the MS runtime?, it will work correctly.

Using the PellesC runtime I still 2 and 522

Thanks,
Mike H.
Title: fseek not seeking
Post by: JohnF on November 07, 2004, 09:10:52 AM
Quote from: "Mikehg"
Hi John,

Are you using the latest version ?

Are you linking with the MS runtime?, it will work correctly.

Using the PellesC runtime I still 2 and 522

Thanks,
Mike H.


Sorry, yes I was linking with the MS runtime, and with crt.lib your code does produce the problem.

John
Title: fseek not seeking
Post by: Pelle on November 07, 2004, 03:31:50 PM
It's the previous addition of supporting fflush() on input streams that is causing the problem. fflush() is also used internally by several C runtime functions, causing problems with fseek() in this case. I have no solution at the moment...

Pelle
Title: Re: fseek not seeking
Post by: Robert on September 02, 2024, 02:55:47 AM
It's the previous addition of supporting fflush() on input streams that is causing the problem. fflush() is also used internally by several C runtime functions, causing problems with fseek() in this case. I have no solution at the moment...

Pelle

Hi Pelle:

Almost twenty years later :o , senseless idiocy still prevails as the output of the attempted compilation of the .c code in the attached zipped project.  ???

Simple minds, like mine, can't begin to understand any of this:

Code: [Select]
Building get.obj.
C:\Users\irwis\OneDrive\Documents\Pelles C Projects\Get\get.c(11): error #2048: Undeclared identifier 'WORD' (did you mean: ?).
C:\Users\irwis\OneDrive\Documents\Pelles C Projects\Get\get.c(11): error #2001: Syntax error: expected ';' but found 'ChunkID'.
C:\Users\irwis\OneDrive\Documents\Pelles C Projects\Get\get.c(11): error #2048: Undeclared identifier 'ChunkID' (did you mean: ?).
*** Error code: 1 ***
Done.
Title: Re: fseek not seeking
Post by: John Z on September 02, 2024, 03:34:13 AM
Add
typedef unsigned short WORD;

as in:
#include <stdio.h>
#include <stdlib.h>

#define GET(A,B,C)fread(B,1,C,A)
typedef unsigned short WORD;
....


or add
#include minwindef.h


John Z
Title: Re: fseek not seeking
Post by: Robert on September 02, 2024, 05:06:58 AM
Add
typedef unsigned short WORD;

as in:
#include <stdio.h>
#include <stdlib.h>

#define GET(A,B,C)fread(B,1,C,A)
typedef unsigned short WORD;
....


or add
#include minwindef.h


John Z

Thanks for the advice John.

One would think that

Code: [Select]
#include <windows.h>
would solve the problem.

Of course, with the -Ze flag for the compiler.

But no, it is wrong for one to think such a thing. If one think's such a thing this will happen.

Code: [Select]
POLINK: error: Unresolved external symbol '__imp_CloseHandle' - referenced from 'crt64.lib(close.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetLastError' - referenced from 'crt64.lib(close.obj)'.
POLINK: error: Unresolved external symbol '__imp_HeapCreate' - referenced from 'crt64.lib(_bigheap.obj)'.
POLINK: error: Unresolved external symbol '__imp_HeapDestroy' - referenced from 'crt64.lib(_bigheap.obj)'.
POLINK: error: Unresolved external symbol '__imp_HeapAlloc' - referenced from 'crt64.lib(_bigheap.obj)'.
POLINK: error: Unresolved external symbol '__imp_HeapReAlloc' - referenced from 'crt64.lib(_bigheap.obj)'.
POLINK: error: Unresolved external symbol '__imp_HeapFree' - referenced from 'crt64.lib(_bigheap.obj)'.
POLINK: error: Unresolved external symbol '__imp_HeapSize' - referenced from 'crt64.lib(_bigheap.obj)'.
POLINK: error: Unresolved external symbol '__imp_HeapValidate' - referenced from 'crt64.lib(_bigheap.obj)'.
POLINK: error: Unresolved external symbol '__imp_QueryPerformanceFrequency' - referenced from 'crt64.lib(clock.obj)'.
POLINK: error: Unresolved external symbol '__imp_QueryPerformanceCounter' - referenced from 'crt64.lib(clock.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetStartupInfoW' - referenced from 'crt64.lib(_ioinit.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetStdHandle' - referenced from 'crt64.lib(_ioinit.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetFileType' - referenced from 'crt64.lib(_ioinit.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetCurrentProcess' - referenced from 'crt64.lib(_ioinit.obj)'.
POLINK: error: Unresolved external symbol '__imp_DuplicateHandle' - referenced from 'crt64.lib(_ioinit.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetCommandLineA' - referenced from 'crt64.lib(_setargv.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetModuleFileNameA' - referenced from 'crt64.lib(_setargv.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetEnvironmentStrings' - referenced from 'crt64.lib(_setenvp.obj)'.
POLINK: error: Unresolved external symbol '__imp_FreeEnvironmentStringsA' - referenced from 'crt64.lib(_setenvp.obj)'.
POLINK: error: Unresolved external symbol '__imp_IsDebuggerPresent' - referenced from 'crt64.lib(_crtabort.obj)'.
POLINK: error: Unresolved external symbol '__imp_OutputDebugStringA' - referenced from 'crt64.lib(_crtabort.obj)'.
POLINK: error: Unresolved external symbol '__imp_UnhandledExceptionFilter' - referenced from 'crt64.lib(_xcptfilter.obj)'.
POLINK: error: Unresolved external symbol '__imp_RtlUnwindEx' - referenced from 'crt64.lib(_ehandler.obj)'.
POLINK: error: Unresolved external symbol '__imp_SetStdHandle' - referenced from 'crt64.lib(_osfinfo.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetConsoleMode' - referenced from 'crt64.lib(_osfinfo.obj)'.
POLINK: error: Unresolved external symbol '__imp_ReadFile' - referenced from 'crt64.lib(read.obj)'.
POLINK: error: Unresolved external symbol '__imp_ReadConsoleA' - referenced from 'crt64.lib(read.obj)'.
POLINK: error: Unresolved external symbol '__imp_MultiByteToWideChar' - referenced from 'crt64.lib(read.obj)'.
POLINK: error: Unresolved external symbol '__imp_ReadConsoleW' - referenced from 'crt64.lib(read.obj)'.
POLINK: error: Unresolved external symbol '__imp_SetFilePointerEx' - referenced from 'crt64.lib(lseek64.obj)'.
POLINK: error: Unresolved external symbol '__imp_WriteFile' - referenced from 'crt64.lib(write.obj)'.
POLINK: error: Unresolved external symbol '__imp_WriteConsoleW' - referenced from 'crt64.lib(write.obj)'.
POLINK: error: Unresolved external symbol '__imp_WideCharToMultiByte' - referenced from 'crt64.lib(write.obj)'.
POLINK: error: Unresolved external symbol '__imp_DeleteFileA' - referenced from 'crt64.lib(unlink.obj)'.
POLINK: error: Unresolved external symbol '__imp_ExitProcess' - referenced from 'crt64.lib(_exit.obj)'.
POLINK: error: Unresolved external symbol '__imp_SetConsoleCtrlHandler' - referenced from 'crt64.lib(signal.obj)'.
POLINK: error: Unresolved external symbol '__imp_VirtualAlloc' - referenced from 'crt64.lib(_getmem.obj)'.
POLINK: error: Unresolved external symbol '__imp_VirtualQuery' - referenced from 'crt64.lib(_getmem.obj)'.
POLINK: error: Unresolved external symbol '__imp_CreateFileA' - referenced from 'crt64.lib(open.obj)'.
POLINK: error: Unresolved external symbol '__imp_IsDBCSLeadByteEx' - referenced from 'crt64.lib(_mbtoc32.obj)'.
POLINK: error: Unresolved external symbol '__imp_WriteConsoleA' - referenced from 'crt64.lib(_cwrite.obj)'.
POLINK: error: Unresolved external symbol '__imp_SetEndOfFile' - referenced from 'crt64.lib(chsize64.obj)'.
Title: Re: fseek not seeking
Post by: MrBcx on September 02, 2024, 06:39:04 AM
I am responsible for Robert's sudden interest in this ancient thread.

I recently added a new function to BCX named LookAhead() that uses _ftelli64 and _fseeki64.

LookAhead performs perfectly when BCX is compiled with Mingw(g++), MSVC, Clang, Embarcadero, and Lcc-Win32
but I cannot even build BCX using Pelles C when LookAhead is in place.  I've spent days trying to get an understanding of
what's happening.  I went so far as to write replacement FTELL and FSEEK functions by using fsetpos() and fgetpos() but
whatever is happening to ftell and fseek affects those functions too.  My replacements worked fine with the other compilers.

I sent Robert the following synopsis earlier this evening.


If ftell and fseek are NEVER used in a Pelles compiled program (including BCX),
everything works great.  But as soon as those functions are called, other file related functions,
notably fgets() and possibly feof(), become corrupted somehow and malfunction. 
But you might not see the corruption immediately.

It might take LINE INPUTTING hundreds of lines of source code, for example, before you can detect
the corruption.  The corrupt lines (missing first character on the left) are actually corrupt
-BEFORE- they hit LookAhead().  Yep ... that was a surprise to me too.  But it only occurs when
using a Pelles C compiled version of BCX.   When BCX is built with all other compilers, LookAhead
 and the rest of BCX works perfectly.

I've taken BCX 8.1.5, and added the following fixups to SUB Final_Transforms and then rebuilt BCX
using Pelles C
.  I was hoping to see some patterns, beyond the left-most character being gobbled up.
I don't see any other patterns.

 
Code: [Select]
 
 DO WHILE NOT EOF(FP1)
        LINE INPUT FP1, Source$

        $IFDEF __POCC__
            IF         Source$ = "num"           THEN Source$ = "enum"
            IF LEFTSTR(Source$, "/ ")            THEN Source$ = "/" + Source$
            IF LEFTSTR(Source$, "IZE* ")         THEN Source$ = "S" + Source$
            IF LEFTSTR(Source$, "NT_PTR ")       THEN Source$ = "I" + Source$
            IF LEFTSTR(Source$, "RESULT CALL")   THEN Source$ = "L" + Source$
            IF LEFTSTR(Source$, "RESULT COM_")   THEN Source$ = "I" + Source$
            IF LEFTSTR(Source$, "WND BCX_")      THEN Source$ = "H" + Source$
            IF LEFTSTR(Source$, "_IMPORT ")      THEN Source$ = "C" + Source$
            IF LEFTSTR(Source$, "define ")       THEN Source$ = "#" + Source$
            IF LEFTSTR(Source$, "har *")         THEN Source$ = "c" + Source$
            IF LEFTSTR(Source$, "har* ")         THEN Source$ = "c" + Source$
            IF LEFTSTR(Source$, "ifndef ")       THEN Source$ = "#" + Source$
            IF LEFTSTR(Source$, "lass ")         THEN Source$ = "c" + Source$
            IF LEFTSTR(Source$, "loat ")         THEN Source$ = "f" + Source$
            IF LEFTSTR(Source$, "nt ")           THEN Source$ = "i" + Source$
            IF LEFTSTR(Source$, "oid ")          THEN Source$ = "v" + Source$
            IF LEFTSTR(Source$, "ong double")    THEN Source$ = "l" + Source$
            IF LEFTSTR(Source$, "ouble ")        THEN Source$ = "d" + Source$
            IF LEFTSTR(Source$, "tatic ")        THEN Source$ = "s" + Source$
            IF LEFTSTR(Source$, "ypedef ")       THEN Source$ = "t" + Source$
        $ENDIF

        '******************************************************************************
        '               Do Some quick beautification of the output
        '******************************************************************************
        IF LTRIM$(Source$) = "" AND LTRIM$(LOOKAHEAD$(FP1)) = "" THEN ITERATE
        IF LTRIM$(Source$) = "" AND LTRIM$(LOOKAHEAD$(FP1)) = "#endif" THEN ITERATE
        '******************************************************************************

With those fixups, I successfully compiled BCX using Pelles and then used that version of BCX to successfully
compile well over 300 test apps, large and small.  But I'm certain that the list of fixups can never be complete
nor is it even practical to have such fixups in an application.  BCX has, until recently, never relied on FTELL or FSEEK,
so Pelles C was always a reliable testing tool.  But my LookAhead() function has changed that.  The work that
 LookAhead() does is non-critical and could be skipped over like so in BCX:

$IFNDEF __POCC__
     IF LTRIM$(Source$) = "" AND LTRIM$(LOOKAHEAD$(FP1)) = "" THEN ITERATE
     IF LTRIM$(Source$) = "" AND LTRIM$(LOOKAHEAD$(FP1)) = "#endif" THEN ITERATE
$ENDIF
 

But I've never needed to do such a thing in BCX and I'm reluctant to start doing it now.

Sorry for the long post but it's been a very complicated subject for me to get to this point.
Title: Re: fseek not seeking
Post by: John Z on September 02, 2024, 07:22:04 AM
Very interesting - a bit concerning  I used:
function  Hits
feof        27
fgetc      18
fseek     20
ftell       23
fflush    93
fgets      1  Not used referenced because I made a zgets to ignore CRLF when in quotes.

I don't 'seem' to have run into an issue, but maybe I just don't know it... but I do extensive file parsing, manipulation on files from 1 to about 8000 entries .... megabyte file too a line at a time.

I don't know "LINE INPUTTING" though I will look closely for a missing left (initial) character.  Is it the start of a line that always ends up missing? Like 1st character after a CRLF ?

John Z

Maybe points to fgets as the possible issue??
Title: Re: fseek not seeking
Post by: frankie on September 02, 2024, 10:47:14 AM
Add
typedef unsigned short WORD;

as in:
#include <stdio.h>
#include <stdlib.h>

#define GET(A,B,C)fread(B,1,C,A)
typedef unsigned short WORD;
....


or add
#include minwindef.h


John Z

Thanks for the advice John.

One would think that

Code: [Select]
#include <windows.h>
would solve the problem.

Of course, with the -Ze flag for the compiler.

But no, it is wrong for one to think such a thing. If one think's such a thing this will happen.

Code: [Select]
POLINK: error: Unresolved external symbol '__imp_CloseHandle' - referenced from 'crt64.lib(close.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetLastError' - referenced from 'crt64.lib(close.obj)'.
POLINK: error: Unresolved external symbol '__imp_HeapCreate' - referenced from 'crt64.lib(_bigheap.obj)'.
POLINK: error: Unresolved external symbol '__imp_HeapDestroy' - referenced from 'crt64.lib(_bigheap.obj)'.
POLINK: error: Unresolved external symbol '__imp_HeapAlloc' - referenced from 'crt64.lib(_bigheap.obj)'.
POLINK: error: Unresolved external symbol '__imp_HeapReAlloc' - referenced from 'crt64.lib(_bigheap.obj)'.
POLINK: error: Unresolved external symbol '__imp_HeapFree' - referenced from 'crt64.lib(_bigheap.obj)'.
POLINK: error: Unresolved external symbol '__imp_HeapSize' - referenced from 'crt64.lib(_bigheap.obj)'.
POLINK: error: Unresolved external symbol '__imp_HeapValidate' - referenced from 'crt64.lib(_bigheap.obj)'.
POLINK: error: Unresolved external symbol '__imp_QueryPerformanceFrequency' - referenced from 'crt64.lib(clock.obj)'.
POLINK: error: Unresolved external symbol '__imp_QueryPerformanceCounter' - referenced from 'crt64.lib(clock.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetStartupInfoW' - referenced from 'crt64.lib(_ioinit.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetStdHandle' - referenced from 'crt64.lib(_ioinit.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetFileType' - referenced from 'crt64.lib(_ioinit.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetCurrentProcess' - referenced from 'crt64.lib(_ioinit.obj)'.
POLINK: error: Unresolved external symbol '__imp_DuplicateHandle' - referenced from 'crt64.lib(_ioinit.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetCommandLineA' - referenced from 'crt64.lib(_setargv.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetModuleFileNameA' - referenced from 'crt64.lib(_setargv.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetEnvironmentStrings' - referenced from 'crt64.lib(_setenvp.obj)'.
POLINK: error: Unresolved external symbol '__imp_FreeEnvironmentStringsA' - referenced from 'crt64.lib(_setenvp.obj)'.
POLINK: error: Unresolved external symbol '__imp_IsDebuggerPresent' - referenced from 'crt64.lib(_crtabort.obj)'.
POLINK: error: Unresolved external symbol '__imp_OutputDebugStringA' - referenced from 'crt64.lib(_crtabort.obj)'.
POLINK: error: Unresolved external symbol '__imp_UnhandledExceptionFilter' - referenced from 'crt64.lib(_xcptfilter.obj)'.
POLINK: error: Unresolved external symbol '__imp_RtlUnwindEx' - referenced from 'crt64.lib(_ehandler.obj)'.
POLINK: error: Unresolved external symbol '__imp_SetStdHandle' - referenced from 'crt64.lib(_osfinfo.obj)'.
POLINK: error: Unresolved external symbol '__imp_GetConsoleMode' - referenced from 'crt64.lib(_osfinfo.obj)'.
POLINK: error: Unresolved external symbol '__imp_ReadFile' - referenced from 'crt64.lib(read.obj)'.
POLINK: error: Unresolved external symbol '__imp_ReadConsoleA' - referenced from 'crt64.lib(read.obj)'.
POLINK: error: Unresolved external symbol '__imp_MultiByteToWideChar' - referenced from 'crt64.lib(read.obj)'.
POLINK: error: Unresolved external symbol '__imp_ReadConsoleW' - referenced from 'crt64.lib(read.obj)'.
POLINK: error: Unresolved external symbol '__imp_SetFilePointerEx' - referenced from 'crt64.lib(lseek64.obj)'.
POLINK: error: Unresolved external symbol '__imp_WriteFile' - referenced from 'crt64.lib(write.obj)'.
POLINK: error: Unresolved external symbol '__imp_WriteConsoleW' - referenced from 'crt64.lib(write.obj)'.
POLINK: error: Unresolved external symbol '__imp_WideCharToMultiByte' - referenced from 'crt64.lib(write.obj)'.
POLINK: error: Unresolved external symbol '__imp_DeleteFileA' - referenced from 'crt64.lib(unlink.obj)'.
POLINK: error: Unresolved external symbol '__imp_ExitProcess' - referenced from 'crt64.lib(_exit.obj)'.
POLINK: error: Unresolved external symbol '__imp_SetConsoleCtrlHandler' - referenced from 'crt64.lib(signal.obj)'.
POLINK: error: Unresolved external symbol '__imp_VirtualAlloc' - referenced from 'crt64.lib(_getmem.obj)'.
POLINK: error: Unresolved external symbol '__imp_VirtualQuery' - referenced from 'crt64.lib(_getmem.obj)'.
POLINK: error: Unresolved external symbol '__imp_CreateFileA' - referenced from 'crt64.lib(open.obj)'.
POLINK: error: Unresolved external symbol '__imp_IsDBCSLeadByteEx' - referenced from 'crt64.lib(_mbtoc32.obj)'.
POLINK: error: Unresolved external symbol '__imp_WriteConsoleA' - referenced from 'crt64.lib(_cwrite.obj)'.
POLINK: error: Unresolved external symbol '__imp_SetEndOfFile' - referenced from 'crt64.lib(chsize64.obj)'.

The suggestion from JohnZ is correct, WORD isn't defined in non Windows application. I suggest to use size_t instead of WORD (size_t is the return type of fread()), in this case the printed values will correctly be 8 and 18.

The unresolved symbols seem to be an IDE bug. I haven't understood yet what, but, on my system, if I change the executable properties to "Win32 Program Console (EXE) " then back to "Win64 Program Console (EXE) " it compiles without problems...  :o

The program output seems correct to me. If you define WORD as unsigned short after first reading the position is 2 as the 2 bytes of the size of the unsigned short, while advancing of 10 bytes it reads 10+2=12.

For the problem relative to LookAhead() posted by MrBCX I need the C code of the function to investigate.

EDIT:
The project type is:
Code: [Select]
POC_PROJECT_TYPE = 3#
3 is a 32bits console program.
The problem is due to incompatibility on machine type in Release mode where CC and LINK flags are set for a 64bits compilation:
Code: [Select]
!if "$(POC_PROJECT_MODE)" == "Release"
CCFLAGS = -Tx64-coff -std:C17 -Ot -Ob1 -fp:precise -W1 -Gd -Go#
ASFLAGS = -AIA32 -Gd#
RCFLAGS = #
LINKFLAGS = -machine:x64 -subsystem:console -safeseh kernel32.lib advapi32.lib delayimp.lib#
If you switch to Debug mode, then clean the project it will compile successfully.
If you seelect Release  mode and switch between 32 to 64 bytes compilation the IDE will fix the ppj file.

Not sure if this happens due to a bug in the IDE, but sometimes creating a new project I had that problem, but I didn't checked the .ppj so I can't tell. In the future I'll check.
Title: Re: fseek not seeking
Post by: MrBcx on September 02, 2024, 04:36:25 PM

For the problem relative to LookAhead() posted by MrBCX I need the C code of the function to investigate.


Hi Frankie - I sent you a message via this forum's message system. 

The message contains a download to help you experiment with the reported problem.

Thank you and good luck.
Title: Re: fseek not seeking
Post by: frankie on September 02, 2024, 07:45:09 PM

For the problem relative to LookAhead() posted by MrBCX I need the C code of the function to investigate.


Hi Frankie - I sent you a message via this forum's message system. 

The message contains a download to help you experiment with the reported problem.

Thank you and good luck.
Kevin I had a look to your files.
In the meanwhile I wrote a sample test below that reproduce the problem:
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define POSITIONS 10

long long pos[POSITIONS];
char sInput[1024];

int main(void)
{
FILE *fp = fopen("Ftell_Study.c", "r");
if (!fp)
{
printf("Error. Can't open file.\n");
return 1;
}

printf ("================ Read input ===============================================\n");
for (int i=0; i<POSITIONS; i++)
{
pos[i] = _ftell64(fp);
if (!fgets(sInput, sizeof(sInput), fp))
{
printf("Error readin input.\n");
return 1;
}
#if 0 //Set to 1 and declare a 'long len' after 'sInput' above to solve the issue
len = strlen(sInput);
if (sInput[len-1] == '\n')
sInput[len-1] = '\0';
#else
if (sInput[strlen(sInput)-1] == '\n')
sInput[strlen(sInput)-1] = '\0';
#endif
printf("Off: %-8lld \"%s\"\n", pos[i], sInput);
}

printf ("================ RE-Read input ===============================================\n");
for (int i=0; i<POSITIONS; i++)
{
_fseek64(fp, pos[i], SEEK_SET);
if (!fgets(sInput, sizeof(sInput), fp))
{
printf("Error readin input.\n");
return 1;
}
if (sInput[strlen(sInput)-1] == '\n')
sInput[strlen(sInput)-1] = '\0';
printf("Off: %-8lld \"%s\"\n", pos[i], sInput);
}

return 0;
}
What is strange is that by just adding a line, even a comment, as:
Code: [Select]
long long pos[POSITIONS];
char sInput[1024];
// blah blah ...
And recompile it works.
Even if you add:
Code: [Select]
long long pos[POSITIONS];
char sInput[1024];
long len;
And set to '1' the if:
Code: [Select]
#if 0 //Set to 1 and declare a 'long len' after 'sInput' above to solve the issue
len = strlen(sInput);
if (sInput[len-1] == '\n')
sInput[len-1] = '\0';
#else
if (sInput[strlen(sInput)-1] == '\n')
sInput[strlen(sInput)-1] = '\0';
#endif
It works.
But if you define len inside the for loop as:
Code: [Select]
#if 1 //Set to 1 and declare a 'long len' after 'sInput' above to solve the issue
long len = strlen(sInput);
if (sInput[len-1] == '\n')
sInput[len-1] = '\0';
#else
if (sInput[strlen(sInput)-1] == '\n')
sInput[strlen(sInput)-1] = '\0';
#endif
printf("Off: %-8lld \"%s\"\n", pos[i], sInput);
}
It fails again.

All please check on your machines to confirm the behavior.

Actual conclusion is that there is a bug in the compiler that seems to influence local (auto) variables. To investigate the differences in code emission is an heavy job that I can't do now.
The optimizations seems to have no influence on the result, nor the bitness.
It would be nice if Pelle could have a look.

P.S.
It seems that the issue happen following empty lines...
Code: [Select]
================ RE-Read input ===============================================
Off: 0        "#include <stdio.h>"
Off: 21       "include <stdlib.h>"
Off: 42       "include <string.h>"
Off: 63       ""
Off: 65       "define POSITIONS 10"
Off: 87       ""
Off: 89       "ong long pos[POSITIONS];"
Off: 116      "har sInput[1024];"
Off: 136      ""
Off: 138      "nt main(void)"
Press any key to continue...
Title: Re: fseek not seeking
Post by: MrBcx on September 02, 2024, 09:03:39 PM

All please check on your machines to confirm the behavior.
 

Frankie - thank you for confirming my report.  I observed similar behaviors during 
my investigations regarding adding/removing blank lines, lines ending in '\n", etc. 
Head scratching, to be sure.

With any luck, Pelle will take a crack at this puzzle.

Title: Re: fseek not seeking
Post by: John Z on September 02, 2024, 10:05:41 PM

All please check on your machines to confirm the behavior.
 

Well  - confirmed on my i7.

However I also did some additional testing - all results attached.

In summary changing _ftell64 to ftell and the problem goes away.
"_ftell64 function [not standard C] [8.00]"

Easy to confirm with frankie's demo program.

Also points to why in my program using so many f.... functions yet I never experienced the issue,
well that plus I could not use fgets anyway  :(

John Z
Title: Re: fseek not seeking
Post by: frankie on September 02, 2024, 10:25:43 PM
Kevin I made a fast compare on code disassembly, and I found no differences between the two. So the issue isn't in the code generation (attache the 2 disassembly).
Then I changed the fopen to binary mode, and it seems to work well:
Code: [Select]
FILE *fp = fopen("test.txt", "rb");
Could you try to change the function Final_Transforms () as follow:
Code: [Select]
void Final_Transforms (void)
{
  char    Source[BCXSTRSIZE];
  char    Dll_Orig[BCXSTRSIZE];
  strcpy(Dll_Orig,vchr(30,67,95,69,88,80,79,82,84,32,105,110,116,32,95,95,115,116,100,99,97,108,108,32,68,108,108,77,97,105,110));
  char    Dll_Repl[BCXSTRSIZE];
  ....
// If compiling for PellesC open file in binary mode.
#ifdef __POCC__
  if((FP1=fopen(FileOut, "rb"))==0)
#else
  if((FP1=fopen(FileOut, "r"))==0)
#endif
   {
  fprintf(stderr, "Error: Cannot Access File or File Not Found. %s\n", FileOut); exit(1);
   }
  if((FP2=fopen("$Bcx$Temp$File$", "w"))==0)
   {
  fprintf(stderr, "Error: Cannot Access File or File Not Found. %s\n", "$Bcx$Temp$File$"); exit(1);
   }
  while(!EoF(FP1)){
      Source[0]=0;
      fgets(Source,  2048, FP1);
        if(feof(FP1) || (Source[strlen(Source)-1]==10))
          {
           Source[strcspn(Source,"\r\n")] = 0;
          }
         else
          {
            printf("%s%d while reading file: %s\n","Error! - LINE INPUT truncation detected at PROGRAM line: ",__LINE__-7, NamePathFromFP(FP1));
            printf("%s\n","The actual truncated line of text:");
            printf("%s",Source);
            exit(1);
          }
      if(strcmp(ltrim(Source),"")==0  && strcmp(ltrim(LookAhead(FP1)),"")==0){
          continue;
        }
      if(strcmp(ltrim(Source),"")==0  && strcmp(ltrim(LookAhead(FP1)),"#endif")==0){
          continue;
        }
      strcpy(Source,replace(Source,chr(15),":"));
      strcpy(Source,replace(Source,QQF,QQR));
      strcpy(Source,replace(Source,Dll_Orig,Dll_Repl));
  ...
}

You can also try changing _ftell64() to ftell() as suggested by John (you already use ftell() when compiling for LCC-Win32).

You can check on the sample I posted before, you can change the file opening to binary and check results.

At this point the issue is in the PellesC I/O library. Probably the cr/lf translation sometime fails, maybe when the cr and the lf are on a sector boundary (adding something in the file shift them and remove the problem).
Title: Re: fseek not seeking
Post by: frankie on September 02, 2024, 10:28:42 PM

All please check on your machines to confirm the behavior.
 

Well  - confirmed on my i7.

However I also did some additional testing - all results attached.

In summary changing _ftell64 to ftell and the problem goes away.
"_ftell64 function [not standard C] [8.00]"

Easy to confirm with frankie's demo program.

Also points to why in my program using so many f.... functions yet I never experienced the issue,
well that plus I could not use fgets anyway  :(

John Z
Thanks John.
This confirms the I/O system failure.
Title: Re: fseek not seeking
Post by: John Z on September 02, 2024, 11:28:24 PM
Then I changed the fopen to binary mode, and it seems to work well:

Confirmed working on my system.

Also BTW in my program I always opened in binary except when checking access.  So another reason why I would not experience the issue had I even used _ftell64.

John Z
Title: Re: fseek not seeking
Post by: MrBcx on September 03, 2024, 12:17:57 AM
Kevin I made a fast compare on code disassembly, and I found no differences between the two. So the issue isn't in the code generation (attache the 2 disassembly).
Then I changed the fopen to binary mode, and it seems to work well:
Code: [Select]
FILE *fp = fopen("test.txt", "rb");
Could you try to change the function Final_Transforms () as follow:
Code: [Select]
void Final_Transforms (void)
{
  char    Source[BCXSTRSIZE];
  char    Dll_Orig[BCXSTRSIZE];
  strcpy(Dll_Orig,vchr(30,67,95,69,88,80,79,82,84,32,105,110,116,32,95,95,115,116,100,99,97,108,108,32,68,108,108,77,97,105,110));
  char    Dll_Repl[BCXSTRSIZE];
  ....
// If compiling for PellesC open file in binary mode.
#ifdef __POCC__
  if((FP1=fopen(FileOut, "rb"))==0)
#else
  if((FP1=fopen(FileOut, "r"))==0)
#endif
   {
  fprintf(stderr, "Error: Cannot Access File or File Not Found. %s\n", FileOut); exit(1);
   }
  if((FP2=fopen("$Bcx$Temp$File$", "w"))==0)
   {
  fprintf(stderr, "Error: Cannot Access File or File Not Found. %s\n", "$Bcx$Temp$File$"); exit(1);
   }
  while(!EoF(FP1)){
      Source[0]=0;
      fgets(Source,  2048, FP1);
        if(feof(FP1) || (Source[strlen(Source)-1]==10))
          {
           Source[strcspn(Source,"\r\n")] = 0;
          }
         else
          {
            printf("%s%d while reading file: %s\n","Error! - LINE INPUT truncation detected at PROGRAM line: ",__LINE__-7, NamePathFromFP(FP1));
            printf("%s\n","The actual truncated line of text:");
            printf("%s",Source);
            exit(1);
          }
      if(strcmp(ltrim(Source),"")==0  && strcmp(ltrim(LookAhead(FP1)),"")==0){
          continue;
        }
      if(strcmp(ltrim(Source),"")==0  && strcmp(ltrim(LookAhead(FP1)),"#endif")==0){
          continue;
        }
      strcpy(Source,replace(Source,chr(15),":"));
      strcpy(Source,replace(Source,QQF,QQR));
      strcpy(Source,replace(Source,Dll_Orig,Dll_Repl));
  ...
}

You can also try changing _ftell64() to ftell() as suggested by John (you already use ftell() when compiling for LCC-Win32).

You can check on the sample I posted before, you can change the file opening to binary and check results.

At this point the issue is in the PellesC I/O library. Probably the cr/lf translation sometime fails, maybe when the cr and the lf are on a sector boundary (adding something in the file shift them and remove the problem).

Frankie -- I tried the various forms of ftell and fseek days ago with no success.  However,  taking your
suggestion about conditionally using binary read mode when compiling with Pelles did the trick!

I removed the earlier "fixups", added the compiler conditional, and rebuilt using Pelles successfully.  Not only did it
compile without warnings/errors but LookAhead() functioned as it should.  I can live with this workaround in BCX,
although it would be great if the root cause can still be found and fixed by Mr. Wizard himself  :-)

Thank you very much for taking an interest in this - I very much appreciate your expertise.


    ! #ifndef __POCC__
         OPEN FileOut$ FOR INPUT AS FP1
    ! #else
         OPEN FileOut$ FOR BINARY READ AS FP1
    ! #endif

    OPEN "$Bcx$Temp$File$" FOR OUTPUT AS FP2
    '**********************************************************************************
    DO WHILE NOT EOF(FP1)
        LINE INPUT FP1, Source$
        '******************************************************************************
        '               Do Some quick beautification of the output
        '******************************************************************************
        IF LTRIM$(Source$) = "" AND LTRIM$(LOOKAHEAD$(FP1)) = "" THEN ITERATE
        IF LTRIM$(Source$) = "" AND LTRIM$(LOOKAHEAD$(FP1)) = "#endif" THEN ITERATE
        '******************************************************************************
Title: Re: fseek not seeking
Post by: frankie on September 03, 2024, 09:55:02 AM
Frankie -- I tried the various forms of ftell and fseek days ago with no success.  However,  taking your
suggestion about conditionally using binary read mode when compiling with Pelles did the trick!

I removed the earlier "fixups", added the compiler conditional, and rebuilt using Pelles successfully.  Not only did it
compile without warnings/errors but LookAhead() functioned as it should.  I can live with this workaround in BCX,
although it would be great if the root cause can still be found and fixed by Mr. Wizard himself  :-)

Thank you very much for taking an interest in this - I very much appreciate your expertise.


    ! #ifndef __POCC__
         OPEN FileOut$ FOR INPUT AS FP1
    ! #else
         OPEN FileOut$ FOR BINARY READ AS FP1
    ! #endif

    OPEN "$Bcx$Temp$File$" FOR OUTPUT AS FP2
    '**********************************************************************************
    DO WHILE NOT EOF(FP1)
        LINE INPUT FP1, Source$
        '******************************************************************************
        '               Do Some quick beautification of the output
        '******************************************************************************
        IF LTRIM$(Source$) = "" AND LTRIM$(LOOKAHEAD$(FP1)) = "" THEN ITERATE
        IF LTRIM$(Source$) = "" AND LTRIM$(LOOKAHEAD$(FP1)) = "#endif" THEN ITERATE
        '******************************************************************************


░░░░░░░░░░░░░░░░░░░░░░█████████
░░███████░░░░░░░░░░███▒▒▒▒▒▒▒▒███
░░█▒▒▒▒▒▒█░░░░░░░███▒▒▒▒▒▒▒▒▒▒▒▒▒███
░░░█▒▒▒▒▒▒█░░░░██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██
░░░░█▒▒▒▒▒█░░░██▒▒▒▒▒██▒▒▒▒▒▒██▒▒▒▒▒███
░░░░░█▒▒▒█░░░█▒▒▒▒▒▒████▒▒▒▒████▒▒▒▒▒▒██
░░░█████████████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██
░░░█▒▒▒▒▒▒▒▒▒▒▒▒█▒▒▒▒▒▒▒▒▒█▒▒▒▒▒▒▒▒▒▒▒██
░██▒▒▒▒▒▒▒▒▒▒▒▒▒█▒▒▒██▒▒▒▒▒▒▒▒▒▒██▒▒▒▒██
██▒▒▒███████████▒▒▒▒▒██▒▒▒▒▒▒▒▒██▒▒▒▒▒██
█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒█▒▒▒▒▒▒████████▒▒▒▒▒▒▒██
██▒▒▒▒▒▒▒▒▒▒▒▒▒▒█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██
░█▒▒▒███████████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██
░██▒▒▒▒▒▒▒▒▒▒████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒█
░░████████████░░░█████████████████
Title: Re: fseek not seeking
Post by: MrBcx on September 03, 2024, 05:59:14 PM
We have a separate thread on the BCX forum tracking the progress of this thread.
Expanding on a BCX user's suggestion this morning, I posted the following on our forum:

I asked ChatGpt to identify any potential pitfalls that could result
from changing "r" to "rb" for reading normal lines of text, including
utf-8
. The primary warning is that Windows does not automatically
transform "\r\n" to "\n" line endings in "rb" mode.

That won't be a problem because BCX has never relied on Windows for that
translation, instead BCX uses the crt function "strcspn" to detect those
line endings and BCX itself handles termination, so very little to change.

In fact what I have changed and I'm testing now, is simply changing the
"r" file mode to "rb" when using:  OPEN "filename" FOR INPUT AS #1


That means instead of needing to change our habits to use:

    OPEN "filename" FOR BINARY READ AS #1

we continue to use

    OPEN "filename" FOR INPUT AS #1

as we always have.


This also means that "FOR INPUT" and "FOR BINARY READ" are treated identically by BCX.

I like this solution a lot.
Title: Re: fseek not seeking
Post by: John Z on September 03, 2024, 10:05:34 PM
You can also try changing _ftell64() to ftell() as suggested by John (you already use ftell() when compiling for LCC-Win32).
Frankie -- I tried the various forms of ftell and fseek days ago with no success. 

Yes I realize _ftell64 was a false result now. The output result does show the issue when changing to just ftell, BUT it was just the result of shortening the C code text by three bytes.  Since the C code was also the input to the test program a minor change to the code lead to the false result. 
Add the three bytes back as
Code: [Select]
pos[i] = ftell(fp);/// and the issue reappears.

Another grand slam home run for frankie on the change to rb as a workaround!

John Z
Title: Re: fseek not seeking
Post by: MrBcx on September 03, 2024, 11:52:46 PM
Finding people willing to participate in confirming a bug report is both fortunate and helpful.

Finding people with the willingness and experience to mitigate / defeat the bug is priceless.

You guys are fantastic!