Announcement

Collapse
No announcement yet.

file_GetS or file_GetW is overwriting array

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • file_GetS or file_GetW is overwriting array

    Compile and test this code on your own screens

    You will find the first four elements in the private attTitle array are reset to 0 for some unknown reason, the number of elements overwritten is related to the number of CONST definitions. If there is only two, everything behaves. Once you include more, more elements of the top array are overwritten and point to position 0 (which will then print my constant "att_adv.cfg" the name of my file.

    We've being working hard on this and it just doesn't make any sense. The only thing it could be is file_GetS or file_GetW is miss-behaving, as it's at that point that the pointers are being reset to 0.

    I've blown too many hours on this. Can anyone help? I need this state function.

    #platform "uLCD-32PT_GFX2"
    #inherit "4DGL_16bitColours.fnc"
    // Global Constants ************************************************************************************************

    func main()
    var D;
    gosub init_SD;
    txt_Set(FONT_SIZE, FONT3);

    state_RESET();
    state();
    //state_Write();
    //state();

    var index, subIn;
    for(index:=0;index<15;index++)
    print(state.attTitle[index], " ,");
    print([STR]state.attTitle[index]);
    print(" ,");
    for(subIn:=0;subIn<STATENUMATTS;subIn++)
    print(state.att[index][subIn], " ");
    next
    print("\n");
    next

    repeat // Main loop that looks for button press events.

    forever

    /* ------------------------------------------------ SUB ROUTINES ---------------------------------------------------------------------------------*/

    init_SD: // initialize SD card
    if (!(D:=file_Mount()))
    while(!(D:=file_Mount()))
    print("Drive not mounted...");
    pause(500);
    gfx_Cls();
    wend
    endif
    gfx_Cls(); //end mount SD card
    endsub;

    endfunc


    /***************************************************************
    * Filename: hydraulic_project.4dg
    * Created: 2011/08/17
    * Author: Harley Carr + Alex Bruce @ Scorpion Technologies LTD.
    * Description: State control functions. Manages file IO.
    * Not Fully implemented in all functions.
    * Will replace default.cfg eventually
    ***************************************************************/
    #constant STATEFNAME := "att_adv.cfg"

    #CONST
    STATEATTDIV
    STATEATTAUX
    STATEATTBNGBNG
    STATESINGLE
    STATEATTIMG
    STATENUMATTS
    #END

    //Loads data from SD card.
    func state()
    var private att[15];
    var private attTitle[15];
    var private noMem := 1; //do we need to declare memory?
    var index,subIn;
    var toss[10];
    if(noMem) //check if we have memory alocated
    for(index:=0; index<15;index++) //if not, alocate it
    attTitle[index] := mem_AllocZ(15);

    next
    for(index:=0; index<15;index++)
    att[index] := mem_AllocZ(STATENUMATTS*3);
    next
    noMem := 0; //it's declared now so we wont do this again unless we clear
    endif

    gfx_Cls();

    var stateFile; //open a lovely little file.
    stateFile := file_Open(STATEFNAME, 'r');

    txt_MoveCursor(0,0);
    for(index:=0;index<15;index++)
    if(index > 3)
    file_GetS(toss,15,stateFile);
    else
    file_GetS(attTitle[index],15,stateFile);
    endif
    print("READ:", [STR]attTitle[index], " 1:", attTitle[0]," 2:", attTitle[1], "\n");
    pause(50);
    //load all the attachment info
    for(subIn:=0;subIn<STATENUMATTS;subIn++)
    att[index][subIn] := file_GetW(stateFile);
    next
    next
    pause(4000);
    gfx_Cls();
    txt_MoveCursor(0,0);
    for(index:=0;index<15;index++)
    print("2READ:", [STR]attTitle[index], " AT:", attTitle[index], "\n");
    pause(50);

    next
    pause(2000);
    gfx_Cls();
    txt_MoveCursor(0,0);
    file_Close(stateFile);
    endfunc

    //Writes data too SD card
    func state_Write()
    var index, subIn;
    var stateFile;
    var mystring[12];

    if (file_Exists(STATEFNAME)) // file won't open for write if it already exists
    file_Erase(STATEFNAME);
    endif

    stateFile := file_Open(STATEFNAME, 'w');

    for(index:=0;index<15;index++)
    to(mystring); print([STR]state.attTitle[index],"\n");
    file_PutS(mystring,stateFile);
    for(subIn:=0; subIn<STATENUMATTS; subIn++)
    file_PutW(state.att[index][subIn],stateFile);
    next
    next

    file_Close(stateFile);
    endfunc

    //Writes factor default values to SD card
    func state_RESET()
    var index, subIn;
    var stateFile;
    var mystring[12];

    if (file_Exists(STATEFNAME)) // file won't open for write if it already exists
    file_Erase(STATEFNAME);
    endif

    stateFile := file_Open(STATEFNAME, 'w');

    for(index:=0;index<14;index++)
    to(mystring); print("ATT - ", index + 1 ,"\n");
    file_PutS(mystring,stateFile);

    for(subIn:=0; subIn<STATENUMATTS; subIn++)
    file_PutW(subIn+(index*100),stateFile);
    next
    next

    file_PutS("NO ATT\n",stateFile);
    for(subIn:=0; subIn<STATENUMATTS; subIn++)
    file_PutW(3,stateFile);
    next
    file_Close(stateFile);

    endfunc

    //Clears memory used by state. state() will realocate it if it needs it.
    func state_Clear()
    var index;
    for(index:=0; index<15;index++) //if not, alocate it
    mem_Free(state.att[index]);
    mem_Free(state.attTitle[index]);
    state.noMem := 1; //you'll have to get it again now
    next
    endfunc

    func hextostr(var inHex)
    var buffer[5]; // 200 character buffer for a source string
    var p; // string pointer
    var converted; // for our results
    to(buffer); print([HEX4] inHex," ");
    p := str_Ptr(buffer); // raise a string pointer so we can use the
    // string functions
    str_GetHexW(&amp;p, &amp;converted);// read all the hex numbers
    // till we get a non number
    return converted;
    endfunc
    strange strange strange strange strange.

    *EDIT: Updated test code for maximum strangeness
    file_GetW Is 100% confirmed for broken

    Here's the hex file state_RESET generates.
    00041 54 54 20 2d 20 31 0a 00 00 01 00 02 00 03 00 04 00 ATT - 1...........
    01241 54 54 20 2d 20 32 0a 64 00 65 00 66 00 67 00 68 00 ATT - 2.d.e.f.g.h.
    02441 54 54 20 2d 20 33 0a c8 00 c9 00 ca 00 cb 00 cc 00 ATT - 3.È.É.Ê.Ë.Ì.
    03641 54 54 20 2d 20 34 0a 2c 01 2d 01 2e 01 2f 01 30 01 ATT - 4.,.-.../.0.
    04841 54 54 20 2d 20 35 0a 90 01 91 01 92 01 93 01 94 01 ATT - 5...‘.’.....
    05a41 54 54 20 2d 20 36 0a f4 01 f5 01 f6 01 f7 01 f8 01 ATT - 6.ô.õ.ö.÷.ø.
    06c41 54 54 20 2d 20 37 0a 58 02 59 02 5a 02 5b 02 5c 02 ATT - 7.X.Y.Z.[.\.
    07e41 54 54 20 2d 20 38 0a bc 02 bd 02 be 02 bf 02 c0 02 ATT - 8.¼.½.¾.¿.À.
    09041 54 54 20 2d 20 39 0a 20 03 21 03 22 03 23 03 24 03 ATT - 9. .!.".#.$.
    0a241 54 54 20 2d 20 31 30 0a 84 03 85 03 86 03 87 03 88 ATT - 10..........
    0b403 41 54 54 20 2d 20 31 31 0a e8 03 e9 03 ea 03 eb 03 .ATT - 11.è.é.ê.ë.
    0c6ec 03 41 54 54 20 2d 20 31 32 0a 4c 04 4d 04 4e 04 4f ì.ATT - 12.L.M.N.O
    0d804 50 04 41 54 54 20 2d 20 31 33 0a b0 04 b1 04 b2 04 .P.ATT - 13.°.±.².
    0eab3 04 b4 04 41 54 54 20 2d 20 31 34 0a 14 05 15 05 16 ³.´.ATT - 14......
    0fc05 17 05 18 05 4e 4f 20 41 54 54 0a 03 00 03 00 03 00 .....NO ATT.......
    10e03 00 03 00 ....
    Is that not the screwiest thing ever? file_GetW is advancing the length of the record!!! What the hell?!

  • #2


    Bug: 4dgl does not handle jagged arrays with any semblance of sensibility, and I'm pretty sure mem_Alloc functions are busted up as well. That was a painful 4 hours.

    Workaround: Use C style 2D arrays

    array[x*width + y] := whatever

    I am not enjoying this language.

    Comment


    • #3


      I thought the language reference manual says arrays can only have one dimension, see Ch4 'Variables and Constants'.



      Just to clarify, is your problem now solved?
      Mark

      Comment


      • #4


        Jagged arrays arn't supported? Seems odd.

        Jagged arrays would be an array of pointers to other arrays
        One should be able to traverse this structure like so: array[a][b]. Infact we have done that in several sections of our program. However when we used dynamic memory it broke.

        It would be very preferable to be able to use arrays like this, because our recourse is functions.

        OH, and we're not very solid on the documentation.

        Did you know str_Copy is listed in the 4dgl internal reference? Doesn't exist. Looks like it's being replaced by the "to(stream); print(foobar);" style.

        Comment


        • #5
          I'm not quite sure what you wish to achieve, so I cant suggest an optimum solution,
          but here is a few examples that may help you to decide the best coding methods.

          Please note that the str_Copy function is a new addition in the latest PmmC,
          http://4d.websitetoolbox.com/post/4DGL-PmmC-Release-%28R28%29-PICASOGFX2-5721966

          Because of the small memory capacity, dynamic allocation of any arrays is preferred.

          In 4DGL, there is only 1 variable type - 16bit signed integer, and only single dimension arrays.

          A sequence of square brackets will only give the addition of the sequence, but is supported for readability.

          eg [a][b][c] is the equivalent of [a+b+c]




          #platform "uLCD-32PT_GFX2"

          #DATA
          word strings str1, str2, str3, str4, str5, str6, str7
          byte str1 "Bananas\0"
          byte str2 "Apples\0"
          byte str3 "Oranges\0"
          byte str4 "Grapes\0"
          byte str5 "Plums\0"
          byte str6 "Mandarin\0"
          byte str7 "Cantelope\0"
          #END

          #constant FALSE, TRUE

          #constant ARRAYSIZE 7 // size of array of objects
          #constant OBJSIZE 5 // word size of each object
          var array[ARRAYSIZE*OBJSIZE]; // set the array size

          var dynamic[ARRAYSIZE]; // a dynamic array

          var c, x, y, n;

          //=============================================================
          // a string compare function
          //=============================================================
          func str_Cmp (var s1, var s2)
          var c1, c2;
          s1 := str_Ptr(s1); // make string pointer
          s2 := str_Ptr(s2); // make string pointer
          repeat
          c1 := str_GetByte(s1++);
          c2 := str_GetByte(s2++);
          if (c1 == '\0') return c1 - c2;
          until (c1 != c2);
          return c1 - c2;
          endfunc

          // Demo
          func main()

          //=============================================================
          // load the static array with incremental values
          //=============================================================
          for(y:=0; y<ARRAYSIZE; y++)
          for(x:=0; x<OBJSIZE; x++)
          //array[y*OBJSIZE][x] := n++;
          array[y * OBJSIZE + x] := n++; // same as
          next
          next

          //=============================================================
          // print the results
          //=============================================================
          for(y:=0; y<ARRAYSIZE; y++)
          for(x:=0; x<OBJSIZE; x++)
          print([HEX4] array[y*OBJSIZE][x], " ");
          //print([HEX4] array[y*OBJSIZE + x], " "); // same as
          next
          putch('\n');
          next

          print("mem = ", mem_Heap(),"\n"); // show current heap size

          //=============================================================
          // create a dynamic array
          //=============================================================
          for(y:=0; y<ARRAYSIZE; y++)
          dynamic[y] := mem_Alloc(10); // allocate 10 bytes for each string
          next
          print("mem now = ", mem_Heap(),"\n"); // show the reduced heap

          //=============================================================
          // load the dynamic array
          //=============================================================
          for(y:=0; y<ARRAYSIZE; y++)
          //to(dynamic[y]); putstr(strings[y]); // using the to function
          str_Copy(str_Ptr(dynamic[y]), strings[y]); // or using str_Copy
          next

          putstr("[UNSORTED]\n");


          //=============================================================
          // print the unsorted array elements
          //=============================================================
          for(y:=0; y<ARRAYSIZE; y++)
          putstr(dynamic[y]);
          putch('\n');
          next

          //=============================================================
          // sort the string array
          //=============================================================
          var i, from;
          n := sizeof(dynamic); // get size of the string array
          repeat
          i := 0;
          from := 0;
          while(i++ < n-1)
          if (str_Cmp(dynamic[i-1], dynamic[i]) > 0)
          SWAP(&amp;dynamic[i-1], &amp;dynamic[i]);
          from := i;
          endif
          wend
          n := from;
          until (!from);


          //=============================================================
          // print the sorted array elements
          //=============================================================
          putstr("[SORTED]\n");
          for(y:=0; y<ARRAYSIZE; y++)
          putstr(dynamic[y]);
          putch('\n');
          next


          //=============================================================
          // finished with array, tear it down
          //=============================================================
          for(y:=0; y<ARRAYSIZE; y++)

          mem_Free(dynamic[y]);
          next

          print("mem finally = ", mem_Heap(),"\n");

          repeat forever
          endfunc
          Regards,
          Dave

          Comment

          Working...
          X