Shop OBEX P1 Docs P2 Docs Learn Events
Having trouble with "ftell()" — Parallax Forums

Having trouble with "ftell()"

ronsherrronsherr Posts: 2
edited 2014-10-30 14:07 in Propeller 1
Hi there!
I'm hoping that someone can point me in the right direction.
I'm not getting expected return from ftell()...it always returns zero on my system.
I've put together the following simplistic example:
#include "simpletools.h"


#define SDDO            22
#define SDCLK           23
#define SDDI            24
#define SDCS            25


int main()              
{
  char textForFile[] = "Testing 123...Add extra data...\n";
  char s[15], t[15];
  unsigned long position;
  sd_mount(SDDO,SDCLK,SDDI,SDCS);
  print("Open file for writing\n");
  FILE* fp = fopen("new1.raw", "wb");
  if(fp==NULL){print("ERROR opening file fro Write\n");}
  print("Write to file\n");
  fwrite(textForFile,1,sizeof(textForFile),fp);
  print("Closing file\n");
  fclose(fp);
  fp = NULL;
  print("Opening file for Read\n");
  fp = fopen("new1.raw","rb");
  if(fp==NULL){print("ERROR opening file for Read\n");}
  position = ftell(fp);
  printf("Current position is %lu \n",position);
  fread(s, 1, 15, fp);
  printf("Reading file data: %s \n",s);
  fseek(fp, 0, SEEK_END);
  print("Seeking to end\n");  
  position = ftell(fp);
  printf("Now current position is %lu \n",position); //On my system I get zero here?
  fread(t, 1, 15, fp);
  printf("Reading file data: %s \n",t);  //shouldn't get good data here...I'm past END           
  print("Rewinding\n");
  rewind(fp);  
  fread(t, 1, 15, fp);
  printf("Read file data after rewind: %s \n",t);  //Now I get good data, which is correct.
  
  while(1)
  {
    
  }   
}


Am I doing this wrong?

Thanks in advance,
Ron

Comments

  • DavidZemonDavidZemon Posts: 2,973
    edited 2014-10-20 18:18
    First, you're using both printf and print. Though it may not be obvious to a new user that this is bad, it is very bad. Though they are functionaly equivalent, they call very different functions. Choose one and stick with it (print or printi is recommended - much smaller than printf).

    I seem to have replicated the problem here. I changed the code up to check for errors along the way. here's the results:
    Open file for writing
    Write to file
    Closing file
    Opening file for Read
    
    
    Position at start: 0
    Read data from file: "Testing 123...A"
    
    
    Seeking to end
    Now current position is 0
    
    
    No data expected and no data read. That's good.
    
    
    Rewinding
    Read file data after rewind: "Testing 123...A"
    

    Which is a result of this code:
    #include <simpletools.h>
    
    #define MISO            1
    #define SCLK            2
    #define MOSI            0
    #define CS              4
    
    
    int createTestFile ();
    
    
    const char textForFile[] = "Testing 123...Add extra data...\n";
    
    
    int main () {
        char s[15], t[15];
        int  position;
        int err;
        FILE *fp;
    
    
        if ((err = sd_mount(MISO, SCLK, MOSI, CS))) {
            print("Error mounting SD card: %d. Now exiting.\n", err);
            return 1;
        }
    
    
        // Create a test file. Exit if it failed
        if (createTestFile())
            return 1;
    
    
        // Open file for read
        print("Opening file for Read\n");
        fp = fopen("new1.raw", "rb");
        if (fp == NULL) {
            print("ERROR opening file for Read\n");
            return 1;
        }
    
    
        // Read some bytes from the file
        position = ftell(fp);
        print("\nPosition at start: %d\n", position);
        fread(s, 1, 15, fp);
        print("Read data from file: \"%s\"\n", s);
    
    
        // Seek to end
        print("\nSeeking to end\n");
        if ((err = fseek(fp, 0, SEEK_END))) {
            print("Error during seek: %d\n", err);
            return 1;
        }
        position = ftell(fp);
        print("Now current position is %d\n", position);
    
    
        //shouldn't get good data here...I'm past END
        if ((err = fread(t, 1, 15, fp))) {
            print("\nWas not expecting to read anything. Instead, read %d bytes\n",
                  err);
            print("Read data from file: \"%s\"\n", t);
        } else
            print("\nNo data expected and no data read. That's good.\n");
    
    
        print("\nRewinding\n");
        rewind(fp);
        fread(t, 1, 15, fp);
        //Now I get good data, which is correct.
        print("Read file data after rewind: \"%s\"\n", t);
    
    
        return 0;
    }
    
    
    int createTestFile () {// Attempt to open file
        print("Open file for writing\n");
        FILE *fp = fopen("new1.raw", "wb");
        if (fp == NULL) {
            print("ERROR opening file fro Write\n");
            return 1;
        }
    
    
        // Write some stuff to the file
        print("Write to file\n");
        fwrite(textForFile, 1, sizeof(textForFile), fp);
    
    
        // Close the file
        print("Closing file\n");
        fclose(fp);
    
    
        return 0;
    }
    
  • DavidZemonDavidZemon Posts: 2,973
    edited 2014-10-20 18:24
    It seems everything is working except the return value of ftell. Time to dig into the propgcc source code I guess? :confused:
  • DavidZemonDavidZemon Posts: 2,973
    edited 2014-10-20 18:44
    The code for ftell is fine. Unfortunately, ftell relies on the driver's implementation of File_fseek, and that is not fine. Based on ftell, it looks like File_fseek is supposed to return the current position, but PropGCC's implementation returns 0 upon success or -1 for error.

    Sorry... you've written your code correctly, but this is a bug/not-yet-written-piece in PropGCC.
    // function called by fseek
    static int File_fseek(FILE *fp, long int offset, int origin)
    {
        // This code needs to be enabled and tested
        PFILEINFO dfs_fp = (PFILEINFO)fp->drvarg[0];
        if (origin == SEEK_CUR)
            offset += dfs_fp->pointer;
        else if (origin == SEEK_END)
            offset += dfs_fp->filelen;
        else if (origin != SEEK_SET)
        {
            errno = EIO;
            return -1;
        }
        if (offset < 0)
            offset = 0;
        DFS_Seek(dfs_fp, offset, dfs_scratch);
        return 0;
    }
    
  • ronsherrronsherr Posts: 2
    edited 2014-10-21 05:05
    Hi SwimDude0614,

    Thanks very much for your time/help!

    If I understand you correctly, I should file this as a bug against propgcc on the code.google.com project site?
  • DavidZemonDavidZemon Posts: 2,973
    edited 2014-10-21 06:26
    ronsherr wrote: »
    Hi SwimDude0614,

    Thanks very much for your time/help!

    If I understand you correctly, I should file this as a bug against propgcc on the code.google.com project site?

    Yep, that would be good. If/when a fix gets committed, let me know and I'll rebuild the versions of PropGCC on my site.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-10-21 11:09
    I'm away from home this week, otherwise I would check in the fix for fseek/ftell. I'll look at it next week when I get back.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-10-21 11:11
    Dave Hein wrote: »
    I'm away from home this week, otherwise I would check in the fix for fseek/ftell. I'll look at it next week when I get back.
    Thanks Dave!
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-10-29 11:08
    I've modified the seek routine in FileDriver.c to return the file position so that ftell works correctly. I've included it in the test program that is in the attached zip file. For now, you can add FileDriver.c to your project, and it will override the version that is in the library. Test it out and let me know if it works OK for you and I'll check it into the repository.

    David, I plan on checking it into the default branch. Are there any other branches that I should add it to?
  • David BetzDavid Betz Posts: 14,516
    edited 2014-10-29 11:31
    Dave Hein wrote: »
    I've modified the seek routine in FileDriver.c to return the file position so that ftell works correctly. I've included it in the test program that is in the attached zip file. For now, you can add FileDriver.c to your project, and it will override the version that is in the library. Test it out and let me know if it works OK for you and I'll check it into the repository.

    David, I plan on checking it into the default branch. Are there any other branches that I should add it to?
    Hi Dave,

    Thanks for fixing this! Yes, you should probably also add it to the release_1_0 branch because that is what is currently used in the SimpleIDE releases.

    Thanks,
    David
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-10-30 12:35
    I committed the changes to the default and release_1_0 branches.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-10-30 14:07
    Dave Hein wrote: »
    I committed the changes to the default and release_1_0 branches.
    Thanks Dave!
Sign In or Register to comment.