Announcement

Collapse
No announcement yet.

Problem with Replace-command

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

  • jcfuller
    replied
    Steve,
    duh... I was looking at SysAllocString not SysAllocStringByteLen

    James


    ------------------

    Leave a comment:


  • Steve Hutchesson
    replied
    James,

    The functions I had in mind are the standard ones that PowerBASIC
    use for dynamic string which are all BYTE size in allocation &
    deallocation.

    000041F4 0 SysAllocStringByteLen
    000041F8 0 SysFreeString
    000041FC 0 SysStringByteLen

    There is something obvious about the problem that Fred is having
    and that is that his code works correctly in 9x and win2k and on
    some installations of NT4.

    By reduction, this indicates that there is something wrong with
    either the installation of NT4 or the service pack 6 that it is
    using.

    Now Bob Zale's asm code for the function is sound, it works too
    well everywhere else to be problematic so this leaves the OLE
    string functions used to allocate, resize and deallocate the OLE
    string used.

    These normally work well on everything else so the next step is the
    OLE string pool and it is here that no-one knows what has been
    changed in the service pack 6.

    What I suggested before was to reduce any compounded memory usage
    by flushing each disk write to disk and testing if de-allocating
    at the end of each iteration of the loop slowed down or stopped
    the problem.

    Fred's report of the function stopping after a partial operation
    has the smell of memory problems so the idea was to try and work
    around the mess up which appears to be another one from Microsoft
    with the service pack 6.

    I keep getting bad reports from people who have upgraded to NT4
    Service pack 6 so I am inclined to think that the problem rests
    with it, not Fred's code.

    Regards

    [email protected]

    ------------------

    Leave a comment:


  • Fred Oxenby
    replied
    Sorry, the "sauer-kraut" forgot to extract functions needed from
    the runtime-library FOXRUN32.DLL when he published the DLL-code
    Either include this in the DLL-code or name it FoxRun32.INC

    Code:
    'code extracted from FoxRun32.DLL
    'Name the file "FOXRUN32.INC"
    'FILE WIN32API.BAS IS EQUAL TO WIN32API.INC BUT IS RENAMED TO PREVENT ACCIDENTAL
    'VERSION INCOMATIBILITIES
    '===[KONSTANTER]=================================
    %AsaVar2Pcc  = 0
    %AsaFix2Pcc  = 1
    %AsaVar2Xfp  = 2
    %AsaFix2Xfp  = 3
    '==[KONSTANTER]==================================
    %NONE   = 0
    %ASCII  = 1
    %ANSI   = 2
    %EBCDIC = 3
    '==[Översättningstabeller]=======================
    %ASC2ANS = 10
    %ASC2EBC = 11
    %ANS2ASC = 12
    %ANS2EBC = 13
    %EBC2ASC = 14
    %EBC2ANS = 15
    %ASC2ASC = 16
    %ANS2ANS = 17
    %EBC2EBC = 18
    '==[FilTyper]====================================
    %PCFIL     = 1
    %ASAFIL    = 2
    %PCCFIL    = 3
    '==[Konverteringstyper]==========================
    %PCCASC       = 30
    %PCCEBC       = 40
    %PCCASC2ASA   = 31
    %PCCASC2PCC   = 32
    %PCCASC2XFP   = 33
    %PCCEBC2ASA   = 41
    %PCCEBC2PCC   = 42
    %PCCEBC2XFP   = 43
    %PCCNOHDR     = 45
    %PCCNOHDR2PCC = 46
    %PCCNOHDR2XFP = 47
    %ASACNTVAR = 20
    %ASACNTFIX = 21
    '==[Script]=====================================
    %PcToPcc    =100
    %PcToXfp    =101
    %PcToAsa    =102
    %PcToAsaVar =1020
    %PcToAsaFix =1021
    %AsaToPcc   =200
    %AsaToXfp   =201
    %PccToPcc   =300
    %PccToXfp   =301
    %PccToAsa   =302
    %S36ToPcc   =400
    %S36ToXfp   =401
    %S36ToAsa   =402
    %VarToFix   =500
    %FixToVar   =501
    %XlateFil   =502
    %SignalFil  =503
    %MoveFil    =504
    %ZipFil     =505
    %UnZipFil   =506
    %CountPc    =510
    %CountPcc   =511
    %CountAsa   =512
    %MailFil    =600
    %MailZip    =601
    %Var2Fix    = 0
    %Fix2Var    = 1
    %XfpToXfp   = 700
    %XfpToPcc   = 701
    %XfpToAsa   = 702
    
    Function FSO_GetFileName(ByVal PathSpec$)Export As String
     Function = Mid$(PathSpec$,Instr(-1,PathSpec$,"\")+1)
    End Function
    Function FSO_AppPath()Export As String
    Local l&,Buffer$
    Buffer$=Space$(500)
        L& = GetModuleFileName(%NULL, _
                               ByVal StrPtr(Buffer$), _
                               ByVal Len(Buffer$))
        If L& = 0 Then Function = "":Exit Function
        Buffer$=Left$(Buffer$,L&)
        Function = FSO_GetParentFolderName(Buffer$)
    End Function
    Function FSO_GetParentFolderName(ByVal PathSpec$)Export As String
     If Instr(PathSpec$,"\")=0 Then Function="": Exit Function
     Function = Mid$(PathSpec$,1,Instr(-1,PathSpec$,"\"))
    End Function
    Function FSO_DeleteFile(ByVal FileSpec$)Export As Long
     Function = 1
     On Error Resume Next
     Kill FileSpec$
     If ErrClear > 0 Then Function = 0
    End Function
    You will need an ASA-file to be able to test this functions.
    This is a simple testprogram that create such a testfile
    and simulates the calling function from my Main Exe:
    Code:
    #Compile Exe
    #Include "Win32Api.inc"
    Type ErrResult
      ErrNr         As Long
      FilPos        As Quad
      BuffSize      As Long
      BuffPos       As Long
      FelRad        As String * 100
    End Type
    
    %NONE   = 0
    %ASCII  = 1
    %ANSI   = 2
    %EBCDIC = 3
    Global IsRunning&
    Declare Function ASA_CVT2XFP Lib "FOX_ASA.DLL"(ByVal InFil$,ByVal UtFil$,ByVal BlkLen%,ByVal CharSet%,ByVal Hdr$,ByVal ProgBar&) As Long   
    Declare Function ASA_ABORT Lib "FOX_ASA.DLL"()As Long
    Declare Function ASA_RETCODE Lib "FOX_ASA.DLL"(EC As ErrResult)As Long
    
    CallBack Function RunButton()
    If isRunning& <> 0 Then Exit Function
    Local ThId&
     Thread Create Test(CBHndl) To ThId&
     Thread Close ThId& To ThId&  
    End Function
    
    CallBack Function CancelButton()
      Call ASA_ABORT()
    End Function
    
    CallBack Function QuitButton()
      Dialog End CbHndl, 0
    End Function
    
    '------------------------------------------------------------------------------
    
    Function PbMain () As Long
      $Register None
    '--create the testfile 130 MB in size------------
       If Dir$("C:\ASATEST.001")="" Then
        local x%,i&,Rad$
        For i& = Asc("A") to Asc("Z")
         Rad$ = Rad$ & "0" & String$(49,i&) & $CRLF
        Next i&
        x%=Freefile
        Open "C:\ASATEST.001" for binary as x%
        For i& = 1 to 100000 
         Put$ x%,Rad$
        Next i&    
        Close x%
       End If
    '------------------------------------------------
      Local hDlg   As Long
      Local result As Long
      Dialog New 0, "FOX ASA-TEST", ,, 200, 50, 0, 0 To hDlg
      Control Add "msctls_progress32",hDlg,100,"",5,5,185,12,%WS_CHILD Or %WS_VISIBLE,%WS_EX_CLIENTEDGE
      Control Add TextBox,hDlg,200,"",5,18,185,12
      Control Add Button, hDlg, 101, "Run AsaTest", 5, 35, 50, 14 Call RunButton
      Control Add Button, hDlg, 102, "Cancel Test", 65, 35, 50, 14, 0 Call CancelButton
      Control Add Button, hDlg, 103, "Quit", 125, 35, 50, 14, 0 Call QuitButton
      Dialog Show Modal hDlg 
    
    End Function
    
    Function Test(ByVal hDlg&)As Long
    Local Tmp$,InFil$,UtFil$,BlkLen%,CharSet%,Hdr$,Rc&
    Local EC As ErrResult
      isRunning& = 1
      InFil$ = "C:\ASATEST.001"
      UtFil$ = "C:\ASATEST.PCC"
      BlkLen% = 0 'Indicate CRLF-terminated
      CharSet% = %ASCII
      Hdr$ = "TESTING|FICHTEST|3|4|5|6|7|8|TESTAPP|0123456|"
      Control Set Text hDlg&,200,"Test Started"
      rc& = ASA_CVT2XFP(InFil$,UtFil$,BlkLen%,CharSet%,Hdr$,GetDlgItem(hDlg&,100))   
      If rc& = 0 Then
       Control Set Text hDlg&,200,"Alles Ok"
      Else
       Call ASA_RETCODE(EC)
       Tmp$ = Ec.FelRad
       Replace Chr$(0) With Chr$(1) In Tmp$
       Control Set Text hDlg&,200,"Error= " & Format$(rc&) & "| " & Tmp$
      End if 
      isRunning& = 0
    End Function
    ------------------
    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se


    [This message has been edited by Fred Oxenby (edited April 13, 2000).]

    Leave a comment:


  • jcfuller
    replied
    Steve,
    I wrote a small test piece today using the Replace command and then
    decompiled it to see what it was doing and it just does not have any
    problems in the code. It uses the normal OLE string pool in the
    normal way so the code is in itself fine. This means it can ONLY be
    a buffering problem with the OLE string pool with the version of NT
    and service pack that you customer is using.
    If I'm not mistaken all the ole string functions are supposed to operate on
    unicode strings not ascii. Do you see where this might be a problem?

    James



    ------------------

    Leave a comment:


  • Lance Edmonds
    replied
    "Garbage collection" is not pertinent to this context, sorry.

    I personally believe the problem is more rudimentary, but even though Fred has posted most of his DLL code, we are unable to run the code to try to duplicate the problem because the INC files are not provided, and we would need his large data files too, plus the calling EXE code

    The earlier "Houston..." thread never eventuated to anything so it is not particularly relevent. The only common aspect is that the code in that message appears to be related to his code in this thread - Fred may be experiencing the same problems with his particular design or implementation.

    We have no idea how his code is being called from the main executable, whether something in that code is overwriting memory used by the DLL (which may not trigger a GPF because it could be manipulating memory wholy allocated to this process), or whether it is much more fundamental.

    Until we can duplicate this problem (by running the code), resolving Fred's issue is not going to be easy.




    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Peter Manders
    replied
    There used to be something called "Garbage Collect", an internal Basic function that would cleanup string space by moving strings around.
    Back then I knew how this worked, I even found and patched a bug in GfA basic (for 680x0 machines) once. I never bothered to read up on how Windows manages this.

    To the point, would it be possible that some thread in that particular version of NT4 does a garbage collect while the replace code is running?
    That would also explain why it's never consistent, it would depend on whenever there's a context switch and at the same time the string pool approaches full.
    Maybe they even "improved" garbage collect by lowering the treshhold, making it complete faster each time, but running more often.

    This is just a thought, maybe Fred can check the STRPTR value before and after the REPLACE.


    Peter Manders


    ------------------

    Leave a comment:


  • Semen Matusovski
    replied
    Fred --
    I wrote simple sub which replaces REPLACE ANY.
    To my surprise without any optimization it works 10-15 times faster than PB Replace Any.(at least, for your situation).
    I posted it in Source code' forum.


    [This message has been edited by Semen Matusovski (edited April 12, 2000).]

    Leave a comment:


  • Fred Oxenby
    replied
    Alright boys, Its time to close this discussion.
    I admit that Replace is not failing and somwhere else
    in my program, in code not yet executed glbAscii is changed,
    to the contents of glbEbcdic. and then Replace is executed
    by some code I am going to write tomorrow.
    That could explain why the last part is in Ascii,
    and the first part is in Ebcdic.



    ------------------
    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se

    Leave a comment:


  • Chris Boss
    replied
    Fred;

    For arguments sake lets say you are right. Lets assume that the problem is with the Replace command.

    Lets look at this logically !


    The following code I assume is one of the places where the translation is getting trashed because of the replace command.

    Code:
    [b]Replace Any glbAscii With glbEbcdic In SJob$[/b]
    Now lets look at this command carefully:

    There are 4 possible causes for the command to return an incorrect string.

    (1) The string glbAscii may have been changed somehow.

    (2) The string glbEbcdic may have been changed somehow.

    (3) The string SJob$ may have been changed somehow.

    (4) The assembler code for the Replace command failed to do what it is supposed to do.

    Before "assuming" it is # 4, you have to verify that it isn't #1, #2 or #3.

    Now there needs to be some verification code to test all 4 possibilities:

    Code:
    #IF %EXTRA_TEST_CODE
       DIM Test_ERROR&, Test_L1&, SJob_bak$
       if glbAscii<>glbAscii_bak then Test_ERROR&=Test_ERROR& or 1
       if glbEbcdic<>glbEbcdic_bak then Test_ERROR&=Test_ERROR& or 2
       Test_L1&=len(SJob$)
       SJob_bak$=SJob$
    #ENDIF
    Replace Any glbAscii With glbEbcdic In SJob$
    #IF %EXTRA_TEST_CODE
       if Test_L1&<>len(SJob$) then  Test_ERROR&=Test_ERROR& or 4
       if glbAscii<>glbAscii_bak then Test_ERROR&=Test_ERROR& or 8
       if glbEbcdic<>glbEbcdic_bak then Test_ERROR&=Test_ERROR& or 16
       Replace Any glbAscii With glbEbcdic In SJob_bak$
       if SJob_bak$<>SJob$ then Test_ERROR&=Test_ERROR& or 32
       if Test_ERROR& then
           ' Each error is trapped in a bit value
           msgbox "Error Found - "+str(Test_ERROR&)
       end if
    #ENDIF
    By creating backup strings for your global conversion strings, you can test to see if the strings have changed. The likely hood of the both the original and the backup string changing exactly the same would be rare.

    Now this will temporarily slow down your code, but it is necessary to test out the problem. By using conditional compiling you can remove the unneeded code easily.

    Unlesss you test this out thoroughly, there is no way to be sure what is really happening. If you can prove that the variables glbAscii and glbEbcdic have not changed somehow and that the SJob$ variable is loaded with the correct data, then it is possible the replace command is to blame.

    Remember the old programming adage, "Garbage In, Garbage Out".


    ------------------

    Leave a comment:


  • Fred Oxenby
    replied
    Some of you have asked for compile-able code.
    Lance does not like too much code, but for others here
    is the complete code in the DLL.
    Code:
    #Dim All 
    #Compile DLL "..\SLAV_DLL\FOX_ASA.DLL"
    #Include "..\COMMON\Win32Api.BAS"
    #Include "..\COMMON\FOXRUN32.INC"
    
    Type BuffTyp
     FilNr       As Long
     FilLen      As Quad
     FilPos      As Quad
     BytesToRead As Quad
     MaxBuff     As Long
     BuffSize    As Long
     BuffPos     As Long
     RadStart    As Long
     RadSlut     As Long
     RadLen      As Long
     RadLen1     As Long
     Refill      As Integer
     CharSet     As Integer
     BlkLen      As Integer
     RutinNamn   As String * 8
     FcbNamn     As String * 8
     Copies      As Integer
     OrderNr     As Long
     AsaCmd      As String * 16
     Trim        As Integer
     CvtRutin    As Integer
     xCallBack    As Dword
    End Type
    
    Type ErrResult
      ErrNr         As Long
      FilPos        As Quad
      BuffSize      As Long
      BuffPos       As Long
      FelRad        As String * 100
    End Type
    
    Global gIn       As BuffTyp
    Global gUt       As BuffTyp
    Global gErr      As ErrResult
    Global ghPBar    As Long
    Global glbAbort  As Long
    Global glbUtBuff As String
    Global glbInBuff As String
    Global gDebugFil As String
    
    %PBM_SETRANGE         =  (%WM_USER+1)
    %PBM_SETPOS           =  (%WM_USER+2)
    '%PBM_DELTAPOS         =  (%WM_USER+3)
    '%PBM_SETSTEP          =  (%WM_USER+4)
    '%PBM_STEPIT           =  (%WM_USER+5)
    %PBM_SETRANGE32       =  (%WM_USER+6)    ' lParam = high, wParam = low
    '%PBM_GETRANGE         =  (%WM_USER+7)    ' wParam = return (TRUE ? low : high). lParam = PPBRANGE or NULL
    '%PBM_GETPOS           =  (%WM_USER+8)
    '%PBM_SETBARCOLOR      =  (%WM_USER+9)	 ' lParam = bar color
    '%PBM_SETBKCOLOR       =  %CCM_SETBKCOLOR ' lParam = bkColor
    
    '===[EXPORTERAD WRAPPER CVTASA2PCC]==============
    Declare Function ASA_CVT2PCC(ByVal InFil$,ByVal UtFil$,ByVal BlkLen%,ByVal CharSet%,ByVal Hdr$,ByVal ProgBar&) As Long   
    Declare Function ASA_CVT2XFP(ByVal InFil$,ByVal UtFil$,ByVal BlkLen%,ByVal CharSet%,ByVal Hdr$,ByVal ProgBar&) As Long   
    Declare Function ASA_ABORT()As Long
    Declare Function ASA_RETCODE(EC As ErrResult)As Long
    
    '===[LOKALA FUNKTIONER]==========================
    Declare Function CVT_ASA2BARR(InFil$,UtFil$,Hdr$)As Integer
    Declare Function ASAVar_TO_XFP()As Integer
    Declare Function ASAFix_TO_XFP()As Integer
    Declare Function ASAVar_TO_PCC()As Integer
    Declare Function ASAFix_TO_PCC()As Integer
    Declare Function ProgressReport(ByVal FilPos&&,ByVal FilLen&&)As Long
    Declare Function HideProgBar()As Long
    Declare Function InitProgBar()As Long
    
    
    '===[EXPORTERAD WRAPPER CVTASA2PCC]==============
    Declare Function VBASA_CVT2PCC(ByRef InFil$,ByRef UtFil$,ByVal BlkLen%,ByVal CharSet%,ByRef Hdr$,ByVal ProgBar&) As Long   
    Declare Function VBASA_CVT2XFP(ByRef InFil$,ByRef UtFil$,ByVal BlkLen%,ByVal CharSet%,ByRef Hdr$,ByVal ProgBar&) As Long   
    Declare Function VBASA_ABORT()As Long
    Declare Function VBASA_RETCODE(ByRef RC&,ByRef FilPos&&,ByRef BuffPos&,ByRef BuffSize&,ByRef FelRad$)As Long
    '---
    Function VBASA_CVT2XFP(ByRef InFil$,ByRef UtFil$,ByVal BlkLen%,ByVal CharSet%,ByRef Hdr$,ByVal ProgBar&)Export As Long
      Function = ASA_CVT2XFP(InFil$,UtFil$,BlkLen%,CharSet%,Hdr$,ProgBar&)
    End Function   
    Function VBASA_CVT2PCC(ByRef InFil$,ByRef UtFil$,ByVal BlkLen%,ByVal CharSet%,ByRef Hdr$,ByVal ProgBar&)Export As Long   
      Function = ASA_CVT2PCC(InFil$,UtFil$,BlkLen%,CharSet%,Hdr$,ProgBar&)
    End Function
    Function VBASA_ABORT()Export As Long
     glbAbort = 1
    End Function 
    Function VBASA_RETCODE(ByRef RC&,ByRef FilPos&&,ByRef BuffPos&,ByRef BuffSize&,ByRef FelRad$)Export As Long
      RC&       =  gErr.ErrNr
      FilPos&&  =  gErr.FilPos
      BuffPos&  =  gErr.BuffPos  
      BuffSize& =  gErr.BuffSize 
      FelRad$   =  gErr.FelRad
    End Function  
    
    '===[EXPORTERAD WRAPPER CVTASA2XFP]==============
    Function ASA_ABORT()Export As Long
     glbAbort = 1
    End Function
    Function ASA_RETCODE(EC  As ErrResult)Export As Long
     EC = gErr
    End Function
    
    Function ASA_CVT2PCC(ByVal InFil$,ByVal UtFil$,ByVal BlkLen%,ByVal CharSet%,ByVal Hdr$,ByVal ProgBar&)Export As Long   
    Local ClrUDT As BuffTyp
    Local ClrErr As ErrResult
    Local rc%
        gDebugFil = FSO_AppPath() & FSO_GetFileName(InFil$)
        gErr = ClrErr
        gIn  = ClrUDT
        gUt  = ClrUDT
    '..Sätt Prog-parametrar...........................
        glbAbort      = 0
        ghPBar        = ProgBar&
        gIn.BlkLen    = BlkLen%
        Select Case CharSet%
         Case %ASCII :gIn.CharSet   = %ASC2EBC
         Case %ANSI  :gIn.CharSet   = %ANS2EBC
         Case %EBCDIC:gIn.CharSet   = %NONE
        End Select
        gIn.CvtRutin  = %AsaVar2Pcc
        If BlkLen%    > 0 Then gIn.CvtRutin  = %AsaFix2Pcc
    '..Sätt Buffer-parametrar.........................
        gIn.MaxBuff   = 15000
        gUt.MaxBuff   = 15000
    '..Anropa konverteringsrutinen....................
        Call InitProgBar()
        rc%           = CVT_ASA2Barr(InFil$,UtFil$,Hdr$)
        Call HideProgBar()
        Function      = rc%
        gErr.ErrNr    = rc%
        gErr.FilPos   = gIn.FilPos
        gErr.BuffPos  = gIn.BuffPos
        gErr.BuffSize = gIn.BuffSize
        gIn = ClrUDT
        gUt = ClrUDT
        glbUtBuff = "": glbInBuff = ""
    End Function
    
    Function ASA_CVT2XFP(ByVal InFil$,ByVal UtFil$,ByVal BlkLen%,ByVal CharSet%,ByVal Hdr$,ByVal ProgBar&)Export As Long
    Local ClrUDT As BuffTyp
    Local ClrErr As ErrResult
    Local rc%
        gDebugFil = FSO_AppPath() & FSO_GetFileName(InFil$)
        gErr = ClrErr
        gIn  = ClrUDT
        gUt  = ClrUDT
    '..Sätt Prog-parametrar...........................
        glbAbort      = 0
        ghPBar        = ProgBar&
        gIn.BlkLen    = BlkLen%
        Select Case CharSet%
         Case %ASCII :gIn.CharSet   = %ASC2EBC
         Case %ANSI  :gIn.CharSet   = %ANS2EBC
         Case %EBCDIC:gIn.CharSet   = %NONE
        End Select
        gIn.CvtRutin  = %AsaVar2Xfp
        If BlkLen%    > 0 Then gIn.CvtRutin  = %AsaFix2Xfp
        gIn.RutinNamn = Rtrim$(Parse$(Hdr$,"|",9),Any Chr$(0,32))
        gIn.OrderNr   = Val(Rtrim$(Parse$(Hdr$,"|",10),Any Chr$(0,32)))
    '..Sätt Buffer-parametrar.........................
        gIn.MaxBuff   = 15000
        gUt.MaxBuff   = 15000
    '..Anropa konverteringsrutinen....................
        Call InitProgBar()
        rc%           = CVT_ASA2Barr(InFil$,UtFil$,Hdr$)
        Call HideProgBar()
        Function      = rc%
        gErr.ErrNr    = rc%
        gErr.FilPos   = gIn.FilPos
        gErr.BuffPos  = gIn.BuffPos
        gErr.BuffSize = gIn.BuffSize
        gIn = ClrUDT
        gUt = ClrUDT
        glbUtBuff = "": glbInBuff = ""
    End Function
    '...[LOKAL KONVERTERINGSRUTIN]...................
    Function CVT_ASA2BARR(InFil$,UtFil$,Hdr$)As Integer
    '.Retur-koder....................................
    '   0 = Success
    ' 100 = Kan inte öppna InFil eller UtFil
    ' 101 = Fel i "1A"-eliminering
    ' 102 = Läsfel InFil
    ' 103 = Skrivfel UtFil
    ' 110 = Kommandofel
    ' 111 = PCC-radlängd större än 255 tecken
    ' 200 = User-Abort
    Local rc%,Tmp$,x1%,rl%
    Local SJob$,SFil$,SOrder$,SEJob$
    On Error Resume Next
    
    '..hyfsa parametrarna............................
        InFil$ = Rtrim$(InFil$,Any Chr$(0,32))
        UtFil$ = Rtrim$(UtFil$,Any Chr$(0,32))
    '..öppna InFilen.................................
        ErrClear
        gIn.FilNr = FreeFile
        Open InFil$ For Binary Access Read Write Lock Write As #gIn.FilNr
        If ErrClear > 0 Then rc% = 100:GoTo ErrExit
        gIn.FilPos      = 1
        gIn.FilLen      = Lof(gIn.FilNr)
        gIn.BytesToRead = gIn.FilLen -(gIn.FilPos - 1)
    '..öppna Ut-filen................................
        ErrClear
        gUt.FilNr = FreeFile
        Open UtFil$ For Binary As #gUt.FilNr
        If ErrClear > 0 Then rc% = 100:GoTo ErrExit
    '..lägg header i UTBuff..........................
        glbUtBuff = glbPCCHdr
    '..Uppdatera header från kommando................
        Tmp$=Parse$(Hdr$,"|", 1) :x1% = Instr(glbUtBuff, "JOBNAME=")
        If Len(Rtrim$(Tmp$)) Then Mid$(glbUtBuff,x1%+8, 8) = Tmp$
        Tmp$=Parse$(Hdr$,"|", 2) :x1% = Instr(glbUtBuff, "FORMNAME=")
        If Len(Rtrim$(Tmp$)) Then Mid$(glbUtBuff,x1%+9, 8) = Tmp$
        Tmp$=Parse$(Hdr$,"|", 3) :x1% = Instr(glbUtBuff, "FCBNAME=")
        If Len(Rtrim$(Tmp$)) Then Mid$(glbUtBuff,x1%+8, 8) = Tmp$
        Tmp$=Parse$(Hdr$,"|", 4) :x1% = Instr(glbUtBuff, "COPIES=")
        If Len(Rtrim$(Tmp$)) Then Mid$(glbUtBuff,x1%+7, 8) = Tmp$
        Tmp$=Parse$(Hdr$,"|", 5) :x1% = Instr(glbUtBuff, "STATE=")
        If Len(Rtrim$(Tmp$)) Then Mid$(glbUtBuff,x1%+6, 5) = Tmp$
        Tmp$=Parse$(Hdr$,"|", 6) :x1% = Instr(glbUtBuff, "CLASS=")
        If Len(Rtrim$(Tmp$)) Then Mid$(glbUtBuff,x1%+6, 1) = Tmp$
        Tmp$=Parse$(Hdr$,"|", 7) :x1% = Instr(glbUtBuff, "PRIORITY=")
        If Len(Rtrim$(Tmp$)) Then Mid$(glbUtBuff,x1%+9, 2) = Tmp$
    '...sätt upp XFP-kommandon.......................
        Select Case gIn.CvtRutin
         Case %AsaVar2Xfp,%AsaFix2Xfp
          SJob$   = Chr$(15) + "SJOB " + Rtrim$(Parse$(Hdr$,"|",9),Any Chr$(0,32))
          SFil$   = Chr$(15) + "INIT MPAD 132 OPER 90 '" + FSO_GetFileName(UtFil$) + "' END"
          SOrder$ = Chr$(15) + "INIT MPAD 132 OPER 105 '" + Rtrim$(Parse$(Hdr$,"|",10),Any Chr$(0,32)) + "' END"
          SEJob$  = Chr$(15) + "EJOB"
          Replace Any glbAscii With glbEbcdic In SJob$
          Replace Any glbAscii With glbEbcdic In SFil$
          Replace Any glbAscii With glbEbcdic In SOrder$
          Replace Any glbAscii With glbEbcdic In SEJob$
    '...Placera XFP-kommandon i UtBuff...............
          Rl% = 1 + Len(SJob$):If Rl% > 255 Then rc% = 111:GoTo ErrExit
          glbUtBuff = glbUtBuff + Mki$(Rl%) + Chr$(&H09) + SJob$ + Mki$(Rl%)
          Rl% = 1 + Len(SFil$):If Rl% > 255 Then rc% = 111:GoTo ErrExit
          glbUtBuff = glbUtBuff + Mki$(Rl%) + Chr$(&H09) + SFil$ + Mki$(Rl%)
          Rl% = 1 + Len(SOrder$):If Rl% > 255 Then rc% = 111:GoTo ErrExit
          glbUtBuff = glbUtBuff + Mki$(Rl%) + Chr$(&H09) + SOrder$ + Mki$(Rl%)
        End Select
    '...Commit UtBuff till disk......................
        ErrClear:Put$ gUt.FilNr,glbUtBuff
        If ErrClear > 0 Then rc% = 103:GoTo ErrExit
        glbUtBuff = ""
    '..Processa filen................................
        Select Case gIn.CvtRutin
         Case %AsaVar2Pcc: rc% = ASAVar_TO_PCC()
         Case %AsaFix2Pcc: rc% = ASAFix_TO_PCC()
         Case %AsaVar2Xfp: rc% = ASAVar_TO_XFP()
         Case %AsaFix2Xfp: rc% = ASAFix_TO_XFP()
        End Select
        If rc% > 0 Then GoTo ErrExit
    '..Töm UtBuffer till disk........................
        Select Case gIn.CvtRutin
         Case %AsaVar2Xfp,%AsaFix2Xfp
          Rl% = 1 + Len(SEJob$)
          If Rl% > 255 Then rc% = 111:GoTo ErrExit
          glbUtBuff = glbUtBuff + Mki$(Rl%) + Chr$(&H09) + SEJob$ + Mki$(Rl%)
        End Select
        ErrClear:Put$ gUt.FilNr,glbUtBuff
        If ErrClear > 0 Then rc% = 103:GoTo ErrExit
        glbUtBuff = ""
    '..stäng filerna.................................
        Close gIn.FilNr
        Close gUt.FilNr
        Function = 0
        Exit Function
    '===[ERROR-HANDLER]==============================
    ErrExit:
      Close gIn.FilNr
      Close gUt.FilNr
      Call FSO_DeleteFile(UtFil$)
      Function = rc%
    End Function
    
    'Option Explicit
    '===[LOKAL VARASA2XFP-RUTIN]=====================
    Function ASAVar_TO_XFP()As Integer
    Local Cmd$,Rad$,CmdPos%
    Local rc%,Tmp$,Rl%,z1%,z2%,z3%
    On Error Resume Next
        Tmp$ ="":glbInBuff=""
        gIn.Refill = 1
    '..loopa genom filen.............................
        ErrClear:Seek gIn.FilNr, gIn.FilPos
        If ErrClear > 0 Then Function = 120: Exit Function
        Do
         apiSleep 0
         If gIn.BytesToRead > 0 And gIn.Refill <> 0 Then
          gIn.Refill = 0
          gIn.BuffSize = Min(gIn.BytesToRead,gIn.MaxBuff)
          ErrClear
          Get$ gIn.FilNr, gIn.BuffSize, glbInBuff
          If ErrClear > 0 Then rc%=102:GoSub DebugExit:Function = 102: Exit Function
          gIn.FilPos = Seek(gIn.FilNr)
          If ErrClear > 0 Then rc%=120:GoSub DebugExit:Function = 120: Exit Function
          gIn.BytesToRead = gIn.FilLen - (gIn.FilPos - 1)
        '..Avlägsna Trailing "1A" och NULL...........
          If gIn.BytesToRead < 1  Then
           glbInBuff = Rtrim$(glbInBuff,Any Chr$(0,&H1A))
           If Right$(glbInBuff,1)<>Chr$(10) Then glbInBuff = glbInBuff + Chr$(10)
          End If
    '--Översätt Ascii Till Ebcdic--------------------
          Select Case gIn.Charset
           Case %ASC2EBC
            z1%=&HCA:z2%=&HB3:z3%=&HFA
            Replace Any glbAscii With glbEbcdic In glbInBuff
           Case %ANS2EBC
            z1%=&HDE:z2%=&HA1:z3%=&H8C
            Replace Any glbAnsi  With glbEbcdic In glbInBuff
           Case Else
            z1%=&HCA:z2%=&HFA:z3%=&HFC
          End Select
    '--Merge buffer----------------------------------
          glbInBuff = Tmp$ + glbInBuff
    '--Tabort CR och FF------------------------------
          glbInBuff = Remove$(glbInBuff$,Any Chr$(12,13))
    '--rätta till buffer-----------------------------
          gIn.BuffSize = Len(glbInBuff)
          gIn.BuffPos = 1
    '--rapportera filpos-----------------------------
          If ProgressReport(gIn.FilPos,gIn.FilLen)<> 0 Then rc%=200:GoSub DebugExit:Function = 200: Exit Function
         End If
    '--Konvertera raden------------------------------
         gIn.RadSlut = Instr(gIn.BuffPos,glbInBuff, Chr$(10))
         If gIn.RadSlut = 0 Then rc%=110:GoSub DebugExit:Function = 110: Exit Function
         Rad$ = Mid$(glbInBuff,gIn.BuffPos,gIn.RadSlut - gIn.BuffPos)
         gIn.BuffPos = gIn.RadSlut + 1
    '--Dags att fylla på buffer----------------------
         If gIn.BuffSize - gIn.BuffPos < 1024 Then
          Tmp$ = Mid$(glbInBuff,gIn.BuffPos)
          gIn.Refill = 1
         End If
    '--Validera Cmd/rad------------------------------
         Rad$=Rtrim$(Rad$,Any Chr$(0,64))
         Select Case Len(Rad$)
          Case > 1 : Cmd$ = Left$(Rad$,1):Rad$ = Mid$(Rad$,2)
          Case = 1 : Cmd$ = Rad$:Rad$ = Chr$(&H40)
          Case Else: Cmd$ = Chr$(&H40):Rad$ = Chr$(&H40)
         End Select
    '--Hantera NonAsa-kommandon----------------------
         Select Case Asc(Cmd$)
          Case &H5C :cmd$ = Chr$(&H40)
          Case &H4F,z1%,z2%,z3%:cmd$ = Chr$(&HC1): rad$ = Chr$(&H0E) + rad$
         End Select
    '--Returnera Normaliserat kommando---------------
         CmdPos% = Instr(Chr$(078,064,240,096,241,242,243,244, _
                              245,246,247,248,249,193,194,195),Cmd$)
         If CmdPos% = 0 Then
          Replace Any glbEbcdic With glbAscii In Rad$
          gErr.FelRad = "ERROR 110 CMD = " + Hex$(Asc(Cmd$)) + " RAD = " + Rad$
          rc%=110:GoSub DebugExit:Function = 110: Exit Function
         End If
    '--Skicka dem till PCC-buffer--------------------
         Cmd$ = Mid$(Chr$(001,009,017,025,137,145,153,161, _
                          169,177,185,193,201,209,217,225), CmdPos%, 1)
    '--Skapa PCC-rad---------------------------------
         Rl% = 1 + Len(Rad$)
         If Rl% > 255 Then rc%=111:GoSub DebugExit:Function = 111:Exit Function
         glbUtBuff = glbUtBuff + Mki$(Rl%) + Cmd$ + Rad$ + Mki$(Rl%)
    '--skriv ut buff---------------------------------
         If Len(glbUtBuff) > gUt.MaxBuff Then
          ErrClear:Put$ gUt.FilNr,glbUtBuff
          If ErrClear > 0 Then Function = 103:Exit Function
          glbUtBuff = ""
         End If
    '--är filen processad----------------------------
         If gIn.BytesToRead < 1 And gIn.BuffPos >= gIn.BuffSize Then Exit Do
        Loop
    '--Töm Utbuffer till disk------------------------
        If Len(glbUtBuff) > 0 Then
         ErrClear
         Put$ gUt.FilNr,glbUtBuff
         If ErrClear > 0 Then Function = 103:Exit Function
         glbUtBuff = ""
        End If
        Function = 0
        Exit Function
    DebugExit:
    Local q%,DebugString$,CSet$
    CSet$ = " NONE " & " RC= " & Format$(Rc%) 
    If gIn.CharSet= %ASC2EBC Then CSet$ =" ASC2EBC " & " RC= " & Format$(Rc%)
    If gIn.CharSet= %ANS2EBC Then CSet$ =" ANS2EBC " & " RC= " & Format$(Rc%)
    ErrClear:q% = FreeFile
    ErrClear:Open gDebugFil For Binary As #q%
    ErrClear:Put$ q%,glbInBuff
    DebugString$ = "|CharSet= " & CSet$ & "|FilPos= " & Format$(gIn.FilPos) & " |BuffPos= " & Format$(gIn.BuffPos)
    Put$ q%,DebugString$
    Close q%
    Return    
    End Function
    '===[LOKAL FIXASA2XFP-RUTIN]=====================
    Function ASAFix_TO_XFP()As Integer
    Local Cmd$,Rad$,CmdPos%
    Local rc%,Tmp$,Rl%,z1%,z2%,z3%
    On Error Resume Next
    
        Tmp$ = "":glbInBuff = ""
        gIn.Refill = 1
    '--loopa genom filen-----------------------------
        ErrClear:Seek gIn.FilNr, gIn.FilPos
        If ErrClear > 0 Then Function = 102: Exit Function
        Do
         apiSleep 0
         If gIn.BytesToRead > 0 And gIn.Refill <> 0 Then
          gIn.Refill = 0
          gIn.BuffSize = Min(gIn.BytesToRead,gIn.MaxBuff)
          ErrClear:Get$ gIn.FilNr, gIn.BuffSize, glbInBuff
          If ErrClear > 0 Then rc%=102:GoSub DebugExit:Function = 102: Exit Function
          gIn.FilPos = Seek(gIn.FilNr)
          If ErrClear > 0 Then rc%=120:GoSub DebugExit:Function = 120: Exit Function
          gIn.BytesToRead = gIn.FilLen - (gIn.FilPos - 1)
    '--Översätt Ascii Till Ebcdic--------------------
          Select Case gIn.Charset
           Case  %ASC2EBC
            Replace Any glbAscii With glbEbcdic In glbInBuff
            z1%=&HCA:z2%=&HB3:z3%=&HFA
           Case  %ANS2EBC
            Replace Any glbAnsi  With glbEbcdic In glbInBuff
            z1%=&HDE:z2%=&HA1:z3%=&H8C
           Case Else
            z1%=&HCA:z2%=&HFA:z3%=&HFC
           End Select
    '--Merge buffer----------------------------------
          glbInBuff = Tmp$ + glbInBuff
          gIn.BuffSize = Len(glbInBuff)
          gIn.BuffPos = 1                            
    '--rapportera filpos-----------------------------
          If ProgressReport(gIn.FilPos,gIn.FilLen)<> 0 Then rc%=200:GoSub DebugExit:Function = 200: Exit Function
         End If
    '--Konvertera raden------------------------------
         Cmd$ = Mid$(glbInBuff, gIn.BuffPos, 1)
         Rad$ = Mid$(glbInBuff, gIn.BuffPos + 1, gIn.BlkLen - 1)
         gIn.BuffPos = gIn.BuffPos + gIn.BlkLen
    '--Dags att fylla på buffert---------------------
         If gIn.BuffSize - gIn.BuffPos < 1024 Then
          Tmp$ = Mid$(glbInBuff,gIn.BuffPos)
          gIn.Refill = 1
         End If
    '--Trimma raden----------------------------------
         Rad$ = Rtrim$(Rad$,Any Chr$(0,64))
    '--Hantera NonAsa-kommandon----------------------
         Select Case Asc(Cmd$)
          Case &H5C :cmd$ = Chr$(&H40)
          Case &H4F,z1%,z2%,z3%:cmd$ = Chr$(&HC1): rad$ = Chr$(&H0E) + rad$
         End Select
    '--Returnera Normaliserat kommando---------------
         CmdPos% = Instr(Chr$(078,064,240,096,241,242,243,244, _
                              245,246,247,248,249,193,194,195),Cmd$)
         If CmdPos% = 0 Then
          Replace Any glbEbcdic With glbAscii In Rad$
          gErr.FelRad = "ERROR 110 CMD = " + Hex$(Asc(Cmd$)) + " RAD = " + Rad$
          rc%=110:GoSub DebugExit:Function = 110: Exit Function
         End If
    '--Skicka dem till PCC-buffer--------------------
         Cmd$ = Mid$(Chr$(001,009,017,025,137,145,153,161, _
                          169,177,185,193,201,209,217,225), CmdPos%, 1)
    '--Skapa PCC-rad---------------------------------
         Rl% = 1 + Len(Rad$)
         If Rl% > 255 Then rc%=111:GoSub DebugExit:Function = 111:Exit Function
         glbUtBuff = glbUtBuff + Mki$(Rl%) + Cmd$ + Rad$ + Mki$(Rl%)
    '--skriv ut buff---------------------------------
         If Len(glbUtBuff) > gUt.MaxBuff Then
          ErrClear:Put$ gUt.FilNr,glbUtBuff
          If ErrClear > 0 Then Function = 103:Exit Function
          glbUtBuff = ""
         End If
    '--är filen processad----------------------------
         If gIn.BytesToRead < 1 And gIn.BuffPos >= gIn.BuffSize Then Exit Do
        Loop
    '--Skicka EndOfJob och Flush PCC-Buffer----------
        If Len(glbUtBuff) > 0 Then
         ErrClear
         Put$ gUt.FilNr,glbUtBuff
         If ErrClear > 0 Then Function = 103:Exit Function
         glbUtBuff = ""
        End If
        Function = 0
        Exit Function
    DebugExit:
    Local q%,DebugString$,CSet$
    CSet$ = " NONE " & " RC= " & Format$(Rc%) 
    If gIn.CharSet= %ASC2EBC Then CSet$ =" ASC2EBC " & " RC= " & Format$(Rc%)
    If gIn.CharSet= %ANS2EBC Then CSet$ =" ANS2EBC " & " RC= " & Format$(Rc%)
    ErrClear:q% = FreeFile
    ErrClear:Open gDebugFil For Binary As #q%
    ErrClear:Put$ q%,glbInBuff
    DebugString$ = "|CharSet= " & CSet$ & "|FilPos= " & Format$(gIn.FilPos) & " |BuffPos= " & Format$(gIn.BuffPos)
    Put$ q%,DebugString$
    Close q%
    Return    
    End Function
    '===[LOKAL VARASA2PCC-RUTIN]=====================
    Function ASAVar_TO_PCC()As Integer
    Local Cmd$,Rad$,CmdPos%
    Local PrevRad$,LastCmdPos%
    Local rc%,Tmp$,Rl%,z1%,z2%,z3%
    On Error Resume Next
        Tmp$ ="":glbInBuff=""
    '--hämta första bufferten------------------------
        Seek gIn.FilNr,gIn.FilPos
        If ErrClear > 0 Then Function = 120: Exit Function
        gIn.BuffSize = Min(gIn.BytesToRead,gIn.MaxBuff)
        ErrClear:Get$ gIn.FilNr, gIn.BuffSize, glbInBuff
        If ErrClear > 0 Then rc%=102:GoSub DebugExit:Function = 102: Exit Function
        gIn.FilPos = Seek(gIn.FilNr)
        If ErrClear > 0 Then rc%=120:GoSub DebugExit:Function = 120: Exit Function
        gIn.BytesToRead = gIn.FilLen - (gIn.FilPos - 1)
    '--Avlägsna Trailing "1A" och NULL---------------
        If gIn.BytesToRead < 1  Then
         glbInBuff = Rtrim$(glbInBuff,Any Chr$(0,&H1A))
         If Right$(glbInBuff,1)<>Chr$(10) Then glbInBuff = glbInBuff + Chr$(10)
        End If
    '--Översätt Ascii Till Ebcdic--------------------
        Select Case gIn.Charset
         Case  %ASC2EBC
          Replace Any glbAscii With glbEbcdic In glbInBuff
          z1%=&HCA:z2%=&HB3:z3%=&HFA
         Case  %ANS2EBC
          Replace Any glbAnsi  With glbEbcdic In glbInBuff
          z1%=&HDE:z2%=&HA1:z3%=&H8C
         Case Else
          z1%=&HCA:z2%=&HFA:z3%=&HFC
        End Select
    '--Merge buffer----------------------------------
        glbInBuff = Tmp$ + glbInBuff
    '--Tabort CR och FF------------------------------
        glbInBuff = Remove$(glbInBuff$,Any Chr$(12,13))
    '--rätta till buffer-----------------------------
        gIn.BuffSize = Len(glbInBuff)
        gIn.BuffPos = 1
        gIn.Refill = 0
    '--Det första kommandot--------------------------
    '   Cmdpointer i LastCmdPos%
    '   PrevRad$ håller den första raden som skall
    '   kombineras med nästa Cmd$
        gIn.RadSlut    = Instr(gIn.BuffPos,glbInBuff, Chr$(10))
        If gIn.RadSlut = 0 Then rc%=110:GoSub DebugExit:Function = 110: Exit Function
        Rad$           = Mid$(glbInBuff,gIn.BuffPos,gIn.RadSlut - gIn.BuffPos)
        gIn.BuffPos    = gIn.RadSlut + 1
    '--Validera Cmd/rad------------------------------
        Rad$=Rtrim$(Rad$,Any Chr$(0,64))
        Select Case Len(Rad$)
         Case > 1 : Cmd$ = Left$(Rad$,1):Rad$ = Mid$(Rad$,2)
         Case = 1 : Cmd$ = Rad$:Rad$ = Chr$(&H40)
         Case Else: Cmd$ = Chr$(&H40):Rad$ = Chr$(&H40)
        End Select
    '--Hantera NonAsa-kommandon----------------------
        Select Case Asc(Cmd$)
         Case &H5C :cmd$ = Chr$(&H40)
         Case &HFA,z1%,z2%,z3%:rad$ = Cmd$ + rad$:cmd$ = Chr$(&H40) ',&HCA,&H9A,&H4F
        End Select
    '--Returnera Normaliserat kommando---------------
        LastCmdPos% = Instr(Chr$(078,064,240,096,241,242,243,244, _
                                 245,246,247,248,249,193,194,195),Cmd$)
        If LastCmdPos% = 0 Then
          Replace Any glbEbcdic With glbAscii In Rad$
          gErr.FelRad = "ERROR 110 CMD = " + Hex$(Asc(Cmd$)) + " RAD = " + Rad$
          rc%=110:GoSub DebugExit:Function = 110: Exit Function
        End If
    '--Spara raden till nästa kommando---------------
        PrevRad$ = Rad$
    '--loopa genom filen-----------------------------
        Do
         apiSleep 0
         If gIn.BytesToRead > 0 And gIn.Refill <> 0 Then
          gIn.Refill=0
          gIn.BuffSize = Min(gIn.BytesToRead,gIn.MaxBuff)
          ErrClear
          Get$ gIn.FilNr, gIn.BuffSize, glbInBuff
          If ErrClear > 0 Then rc%=102:GoSub DebugExit:Function = 102: Exit Function
          gIn.FilPos = Seek(gIn.FilNr)
          If ErrClear > 0 Then rc%=120:GoSub DebugExit:Function = 120: Exit Function
          gIn.BytesToRead = gIn.FilLen - (gIn.FilPos - 1)
    '--Avlägsna Trailing "1A" och NULL---------------
          If gIn.BytesToRead < 1  Then
           glbInBuff = Rtrim$(glbInBuff,Any Chr$(0,&H1A))
           If Right$(glbInBuff,1)<>Chr$(10) Then glbInBuff = glbInBuff + Chr$(10)
          End If
    '--Översätt Ascii Till Ebcdic-------------------
          Select Case gIn.Charset
           Case  %ASC2EBC
            Replace Any glbAscii With glbEbcdic In glbInBuff
            z1%=&HCA:z2%=&HB3:z3%=&HFA
           Case  %ANS2EBC
            Replace Any glbAnsi  With glbEbcdic In glbInBuff
            z1%=&HDE:z2%=&HA1:z3%=&H8C
           Case Else
            z1%=&HCA:z2%=&HFA:z3%=&HFC
          End Select
    '--Merge buffer----------------------------------
          glbInBuff = Tmp$ + glbInBuff
    '--Tabort CR och FF------------------------------
          glbInBuff = Remove$(glbInBuff$,Any Chr$(12,13))
    '--rätta till buffer-----------------------------
          gIn.BuffSize = Len(glbInBuff)
          gIn.BuffPos = 1                            
    '--rapportera filpos-----------------------------
          If ProgressReport(gIn.FilPos,gIn.FilLen)<> 0 Then rc%=200:GoSub DebugExit:Function = 200: Exit Function
         End If
    '--Konvertera raden------------------------------
         gIn.RadSlut = Instr(gIn.BuffPos,glbInBuff, Chr$(10))
         If gIn.RadSlut = 0 Then rc%=111:GoSub DebugExit:Function = 111: Exit Function
         Rad$ = Mid$(glbInBuff,gIn.BuffPos,gIn.RadSlut - gIn.BuffPos)
         gIn.BuffPos = gIn.RadSlut + 1
    '--Dags att fylla på buffer----------------------
         If gIn.BuffSize - gIn.BuffPos < 1024 Then
          Tmp$ = Mid$(glbInBuff,gIn.BuffPos)
          gIn.Refill = 1
         End If
    '--Validera Cmd/rad------------------------------
         Rad$=Rtrim$(Rad$,Any Chr$(0,64))
         Select Case Len(Rad$)
          Case > 1 :Cmd$ = Left$(Rad$,1):Rad$ = Mid$(Rad$,2)
          Case = 1 :Cmd$ = Rad$:Rad$ = Chr$(64)
          Case Else:Cmd$ = Chr$(64):Rad$ = Chr$(64)
         End Select
    '--Hantera NonAsa-kommandon----------------------
         Select Case Asc(Cmd$)
          Case &H5C :cmd$ = Chr$(&H40)
          Case &HCA,z1%,z2%,z3%:rad$ = Cmd$ + rad$:cmd$ = Chr$(&H40) ',&HCA,&H9A,&H4F
         End Select
    '--Returnera Normaliserat kommando---------------
         CmdPos% = Instr(Chr$(078,064,240,096,241,242,243,244, _
                              245,246,247,248,249,193,194,195),Cmd$)
         If CmdPos% = 0 Then
          Replace Any glbEbcdic With glbAscii In Rad$
          gErr.FelRad = "ERROR 110 CMD = " + Hex$(Asc(Cmd$)) + " RAD = " + Rad$
          rc%=110:GoSub DebugExit:Function = 110: Exit Function
         End If
    '--Skicka dem till PCC-buffer--------------------
         Cmd$ = Mid$(Chr$(001,009,017,025,137,145,153,161, _
                          169,177,185,193,201,209,217,225), CmdPos%, 1)
    '--Till detta kommando hör PrevRad$--------------
         Swap Rad$,PrevRad$
    '--Skapa PCC-rad---------------------------------
         Rl% = 1 + Len(Rad$)
         If Rl% > 255 Then rc%=111:GoSub DebugExit:Function = 111:Exit Function
         glbUtBuff = glbUtBuff + Mki$(Rl%) + Cmd$ + Rad$ + Mki$(Rl%)
    '--skriv ut buff---------------------------------
         If Len(glbUtBuff) > gUt.MaxBuff Then
          ErrClear:Put$ gUt.FilNr,glbUtBuff
          If ErrClear > 0 Then Function = 103:Exit Function
          glbUtBuff = ""
         End If
    '--är filen processad----------------------------
         If gIn.BytesToRead < 1 And gIn.BuffPos >= gIn.BuffSize Then Exit Do
        Loop
    '--Sista kommandot skall hanteras----------------
        Cmd$ = Mid$(Chr$(001,009,017,025,137,145,153,161, _
                         169,177,185,193,201,209,217,225), LastCmdPos%, 1)
        Swap Rad$,PrevRad$
    '--Skapa PCC-rad---------------------------------
        Rl% = 1 + Len(Rad$)
        If Rl% > 255 Then rc%=111:GoSub DebugExit:Function = 111:Exit Function
        glbUtBuff = glbUtBuff + Mki$(Rl%) + Cmd$ + Rad$ + Mki$(Rl%)
    '--skriv ut buff---------------------------------
        ErrClear:Put$ gUt.FilNr,glbUtBuff
        If ErrClear > 0 Then Function = 103:Exit Function
        glbUtBuff = "":glbInBuff = ""
        Function = 0
        Exit Function
    DebugExit:
    Local q%,DebugString$,CSet$
    CSet$ = " NONE " & " RC= " & Format$(Rc%) 
    If gIn.CharSet= %ASC2EBC Then CSet$ =" ASC2EBC " & " RC= " & Format$(Rc%)
    If gIn.CharSet= %ANS2EBC Then CSet$ =" ANS2EBC " & " RC= " & Format$(Rc%)
    ErrClear:q% = FreeFile
    ErrClear:Open gDebugFil For Binary As #q%
    ErrClear:Put$ q%,glbInBuff
    DebugString$ = "|CharSet= " & CSet$ & "|FilPos= " & Format$(gIn.FilPos) & " |BuffPos= " & Format$(gIn.BuffPos)
    Put$ q%,DebugString$
    Close q%
    Return    
    End Function
    '===[LOKAL FIXASA2PCC-RUTIN]=====================
    Function ASAFix_TO_PCC()As Integer
    Local Cmd$,Rad$,CmdPos%
    Local PrevRad$,LastCmdPos%
    Local rc%,Tmp$,Rl%,z1%,z2%,z3%
    On Error Resume Next
    '--Hantera första raden--------------------------
        Tmp$ = "":glbInBuff = Space$(gIn.Blklen)
        ErrClear
        Seek gIn.FilNr,gIn.FilPos
        If ErrClear > 0 Then Function = 120:Exit Function
        Get gIn.FilNr,gIn.FilPos,glbInBuff
        If ErrClear > 0 Then rc%=102:GoSub DebugExit:Function = 102: Exit Function
        Select Case gIn.Charset
         Case  %ASC2EBC
          Replace Any glbAscii With glbEbcdic In glbInBuff
          z1%=&HCA:z2%=&HB3:z3%=&HFA
         Case  %ANS2EBC
          Replace Any glbAnsi  With glbEbcdic In glbInBuff
          z1%=&HDE:z2%=&HA1:z3%=&H8C
         Case Else
          z1%=&HCA:z2%=&HFA:z3%=&HFC
        End Select
        Cmd$ = Mid$(glbInBuff, 1, 1)
        Rad$ = Mid$(glbInBuff, 2, gIn.BlkLen - 1)
        Rad$ = Rtrim$(Rad$,Chr$(64))
    '--Hantera NonAsa-kommandon----------------------
        Select Case Asc(Cmd$)
         Case &H5C :cmd$ = Chr$(&H40)
         Case &HCA,z1%,z2%,z3%:Rad$ = Cmd$ + rad$:cmd$ = Chr$(&H40) ',&HCA,&H9A,&H4F
        End Select
    '--Spara CmdPos% till sista raden----------------
        LastCmdPos% = Instr(Chr$(078,064,240,096,241,242,243,244, _
                                 245,246,247,248,249,193,194,195),Cmd$)
        If LastCmdPos% = 0 Then
          Replace Any glbEbcdic With glbAscii In Rad$
          gErr.FelRad = "ERROR 110 CMD = " + Hex$(Asc(Cmd$)) + " RAD = " + Rad$
          rc%=110:GoSub DebugExit:Function = 110: Exit Function
        End If
    '--Spara Rad$ för nästa Cmd$---------------------
        PrevRad$ = Rad$
    '--Läs resten av filen---------------------------
        gIn.FilPos = Seek(gIn.FilNr)
        gIn.BytesToRead = gIn.FilLen - (gIn.FilPos - 1)
        gIn.Refill = 1
        Do
         apiSleep 0
         If gIn.BytesToRead > 0 And gIn.Refill <> 0 Then
          gIn.Refill= 0
          gIn.BuffSize = Min(gIn.BytesToRead,gIn.MaxBuff)
          ErrClear:Get$ gIn.FilNr, gIn.BuffSize, glbInBuff
          If ErrClear > 0 Then rc%=102:GoSub DebugExit:Function = 102: Exit Function
          gIn.FilPos = Seek(gIn.FilNr)
          If ErrClear > 0 Then rc%=120:GoSub DebugExit:Function = 120: Exit Function
          gIn.BytesToRead = gIn.FilLen - (gIn.FilPos - 1)
    '--Översätt Ascii Till Ebcdic--------------------
          Select Case gIn.Charset
           Case  %ASC2EBC
            Replace Any glbAscii With glbEbcdic In glbInBuff
            z1%=&HCA:z2%=&HB3:z3%=&HFA
           Case  %ANS2EBC
            Replace Any glbAnsi  With glbEbcdic In glbInBuff
            z1%=&HDE:z2%=&HA1:z3%=&H8C
           Case Else
            z1%=&HCA:z2%=&HFA:z3%=&HFC
          End Select
    '--Merge buffer----------------------------------
          glbInBuff = Tmp$ + glbInBuff
          gIn.BuffSize = Len(glbInBuff)
          gIn.BuffPos = 1
          If ProgressReport(gIn.FilPos,gIn.FilLen)<> 0 Then rc%=200:GoSub DebugExit:Function = 200: Exit Function
         End If
    '--Konvertera raden------------------------------
         Cmd$ = Mid$(glbInBuff, gIn.BuffPos, 1)
         Rad$ = Mid$(glbInBuff, gIn.BuffPos + 1, gIn.BlkLen - 1)
         gIn.BuffPos = gIn.BuffPos + gIn.BlkLen
         Rad$ = Rtrim$(Rad$,Chr$(64))
    '--Dags att fylla på buffer----------------------
         If gIn.BuffSize - gIn.BuffPos < 1024 Then
          Tmp$ = Mid$(glbInBuff,gIn.BuffPos)
          gIn.Refill = 1
         End If
    '--Hantera NonAsa-kommandon----------------------
         Select Case Asc(Cmd$)
          Case &H5C :cmd$ = Chr$(&H40)
          Case &HCA,z1%,z2%,z3%:rad$ = Cmd$ + rad$:cmd$ = Chr$(&H40) ',&HCA,&H9A,&H4F
         End Select
    '--Returnera Normaliserat kommando---------------
         CmdPos% = Instr(Chr$(078,064,240,096,241,242,243,244, _
                              245,246,247,248,249,193,194,195),Cmd$)
         If CmdPos% = 0 Then
          Replace Any glbEbcdic With glbAscii In Rad$
          gErr.FelRad = "ERROR 110 CMD = " + Hex$(Asc(Cmd$)) + " RAD = " + Rad$
          rc%=110:GoSub DebugExit:Function = 110: Exit Function
         End If
    '--Skicka dem till PCC-buffer--------------------
         Cmd$ = Mid$(Chr$(001,009,017,025,137,145,153,161, _
                          169,177,185,193,201,209,217,225), CmdPos%, 1)
    '--PrevRad hör till detta kommando---------------
         Swap Rad$,PrevRad$
    '--Skapa PCC-rad---------------------------------
         Rl% = 1 + Len(Rad$)
         If Rl% > 255 Then rc%=111:GoSub DebugExit:Function = 111:Exit Function
         glbUtBuff = glbUtBuff + Mki$(Rl%) + Cmd$ + Rad$ + Mki$(Rl%)
    '--skriv ut buff---------------------------------
         If Len(glbUtBuff) > gUt.MaxBuff Then
          ErrClear:Put$ gUt.FilNr,glbUtBuff
          If ErrClear > 0 Then Function = 103:Exit Function
          glbUtBuff = ""
         End If
    '--är filen processad----------------------------
         If gIn.BytesToRead < 1 And gIn.BuffPos >= gIn.BuffSize Then Exit Do
        Loop
    '--Sista kommandot skall hanteras----------------
        Cmd$ = Mid$(Chr$(001,009,017,025,137,145,153,161, _
                         169,177,185,193,201,209,217,225), LastCmdPos%, 1)
        Swap Rad$,PrevRad$
    '--Skapa PCC-rad---------------------------------
        Rl% = 1 + Len(Rad$)
        If Rl% > 255 Then rc%=111:GoSub DebugExit:Function = 111:Exit Function
        glbUtBuff = glbUtBuff + Mki$(Rl%) + Cmd$ + Rad$ + Mki$(Rl%)
    '--skriv ut buff---------------------------------
        ErrClear:Put$ gUt.FilNr,glbUtBuff
        If ErrClear > 0 Then Function = 103:Exit Function
        glbUtBuff = "":glbInBuff = ""
        Function = 0
        Exit Function
    DebugExit:
    Local q%,DebugString$,CSet$
    CSet$ = " NONE " & " RC= " & Format$(Rc%) 
    If gIn.CharSet= %ASC2EBC Then CSet$ =" ASC2EBC " & " RC= " & Format$(Rc%)
    If gIn.CharSet= %ANS2EBC Then CSet$ =" ANS2EBC " & " RC= " & Format$(Rc%)
    ErrClear:q% = FreeFile
    ErrClear:Open gDebugFil For Binary As #q%
    ErrClear:Put$ q%,glbInBuff
    DebugString$ = "|CharSet= " & CSet$ & "|FilPos= " & Format$(gIn.FilPos) & " |BuffPos= " & Format$(gIn.BuffPos)
    Put$ q%,DebugString$
    Close q%
    Return    
    End Function
    
    '==[OUTPUT-FUNKTIONER]============================
    Function InitProgBar()As Long
      If ghPBar = 0 Then Function = glbAbort:Exit function
      Call SendMessage(ghPBar,%PBM_SETRANGE, 0,MakLng(0,1000))
      Call SendMessage(ghPBar,%PBM_SETPOS,0,0)
      Call ShowWindow(ghPBar,%SW_SHOW)
      Function = glbAbort
    End Function
    Function HideProgBar()As Long
      If ghPBar = 0 Then Function = glbAbort:Exit function
      Call SendMessage(ghPBar,%PBM_SETPOS,0,0)
      Call ShowWindow(ghPBar,%SW_HIDE)
      Function = glbAbort
    End Function
    Function ProgressReport(ByVal FilPos&&,ByVal FilLen&&)As Long
    Static NewPos&
      If ghPBar = 0 Then Function = glbAbort:Exit function
      NewPos& = CLng(FilPos&& / FilLen&& * 1000)
      Call SendMessage(ghPBar, %PBM_SETPOS,NewPos&,0)
      Function = glbAbort
    End Function
    
    '==[DLL-CODE]====================================
    Sub InitGlobal()
    '--ANSI teckenuppsättning---
    glbANSI =   Chr$(000,001,002,003,004,005,006,007,008,009,010,011,012,013,014,015, _
                     016,017,018,019,020,021,022,023,024,025,026,027,028,029,030,031, _
                     032,033,034,035,036,037,038,039,040,041,042,043,044,045,046,047, _
                     048,049,050,051,052,053,054,055,056,057,058,059,060,061,062,063, _
                     064,065,066,067,068,069,070,071,072,073,074,075,076,077,078,079, _
                     080,081,082,083,084,085,086,087,088,089,090,091,092,093,094,095, _
                     096,097,098,099,100,101,102,103,104,105,106,107,108,109,110,111, _
                     112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, _
                     199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197, _
                     201,230,198,244,246,242,251,249,255,214,220,248,163,216,215,128, _
                     225,237,243,250,241,209,129,130,191,174,131,189,188,161,171,187, _
                     132,133,134,135,136,193,194,192,169,137,138,139,140,162,165,141, _
                     142,143,144,145,146,147,227,195,148,149,150,151,152,153,154,155, _
                     240,208,202,203,200,170,205,206,207,157,158,159,164,166,204,176, _
                     211,223,212,210,245,213,181,254,222,218,219,217,253,156,175,180, _
                     173,177,172,190,182,167,247,184,186,168,183,185,179,178,221,160)
    '--EBCDIC teckenupsättning----
    glbEBCDIC = Chr$(000,001,002,003,055,045,046,047,022,005,010,011,012,013,014,015, _
                     016,017,018,019,060,061,050,038,024,025,063,039,028,029,030,031, _
                     064,079,127,099,103,108,080,125,077,093,092,078,107,096,075,097, _
                     240,241,242,243,244,245,246,247,248,249,122,094,076,126,110,111, _
                     236,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, _
                     215,216,217,226,227,228,229,230,231,232,233,181,113,159,095,109, _
                     081,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, _
                     151,152,153,162,163,164,165,166,167,168,169,065,187,071,220,255, _
                     104,161,121,066,192,068,208,072,082,083,084,087,086,088,123,091, _
                     224,156,158,203,106,205,219,221,223,124,252,112,177,128,191,007, _
                     069,085,206,222,073,105,154,155,171,175,186,184,183,170,138,139, _
                     043,044,009,033,040,101,098,100,180,056,049,052,051,176,178,036, _
                     034,023,041,006,032,042,070,102,026,053,008,057,054,048,058,090, _
                     140,172,114,115,116,037,117,118,119,035,021,020,004,204,120,059, _
                     238,089,235,237,207,239,160,142,174,254,251,253,141,173,188,190, _
                     202,143,027,185,182,067,225,157,144,189,179,218,250,234,062,074)
    '--ASCII teckenuppsättning----
    glbASCII =  Chr$(000,001,002,003,004,005,006,007,008,009,010,011,012,013,014,015, _
                     016,017,018,019,020,021,022,023,024,025,026,027,028,029,030,031, _
                     032,033,034,035,036,037,038,039,040,041,042,043,044,045,046,047, _
                     048,049,050,051,052,053,054,055,056,057,058,059,060,061,062,063, _
                     064,065,066,067,068,069,070,071,072,073,074,075,076,077,078,079, _
                     080,081,082,083,084,085,086,087,088,089,090,091,092,093,094,095, _
                     096,097,098,099,100,101,102,103,104,105,106,107,108,109,110,111, _
                     112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, _
                     128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, _
                     144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, _
                     160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, _
                     176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, _
                     192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, _
                     208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, _
                     224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, _
                     240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255)
    '...Header.......................................
    glbPccHdr = Chr$(118,026,255,255,206,000,255,080,082,073,078,084,069,082,032,070, _
                     079,082,077,078,065,077,069,061,032,032,032,032,032,032,032,032, _
                     032,076,080,070,061,032,032,032,032,080,076,080,070,061,032,032, _
                     032,032,076,080,073,061,032,032,067,079,078,084,082,079,076,061, _
                     032,032,032,076,079,067,078,065,077,069,061,032,032,032,032,032, _
                     032,032,032,013,010,074,079,066,078,065,077,069,061,032,032,032, _
                     032,032,032,032,032,032,067,079,080,073,069,083,061,032,032,032, _
                     032,032,032,032,032,032,080,082,073,079,082,073,084,089,061,032, _
                     032,032,083,084,065,084,069,061,032,032,032,032,032,032,067,076, _
                     065,083,083,061,032,032,032,032,032,032,032,032,032,032,032,013, _
                     010,070,067,066,078,065,077,069,061,032,032,032,032,032,032,032, _
                     032,032,085,067,083,061,032,032,032,032,032,032,032,032,032,032, _
                     032,032,032,032,032,032,032,032,032,032,032,032,049,050,051,052, _
                     053,054,055,013,206,000,068,000,198,129,001,000,000,000,000,000)
    glbPccHdr = glbPccHdr _
              + Chr$(000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000, _
                     000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000, _
                     000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000, _
                     000,000,000,000,000,000,000,000,000,000,000,016,068,000,188,000, _
                     255,064,064,064,064,064,064,064,064,064,064,064,064,064,064,064, _
                     064,064,064,064,064,064,064,064,064,064,064,064,064,064,064,064, _
                     064,064,064,064,064,064,064,064,064,064,064,064,064,064,064,064, _
                     064,064,064,064,064,064,064,064,064,064,064,064,064,064,064,064, _
                     064,064,064,064,064,064,064,064,064,064,064,064,064,064,064,064, _
                     064,064,064,064,064,064,064,064,064,064,064,064,064,064,064,064, _
                     064,064,064,064,064,064,064,064,064,064,064,064,064,064,064,064, _
                     064,064,064,064,064,064,064,064,064,064,064,064,064,064,064,064, _
                     064,064,064,064,064,064,064,064,064,064,064,064,064,064,064,064, _
                     064,064,064,064,064,064,064,064,064,064,064,064,064,064,064,064, _
                     064,064,064,064,064,064,064,064,064,064,064,064,064,064,064,064, _
                     064,064,064,064,064,064,064,064,064,064,064,064,188,000)
    End Sub
    
    Function LibMain(ByVal hInstance   As Long, _
                     ByVal fwdReason   As Long, _
                     ByVal lpvReserved As Long) Export As Long
    
      Select Case fwdReason
        Case %DLL_PROCESS_ATTACH
           InitGlobal
           LibMain = 1   'success!
           'LibMain = 0   'failure!
          Exit Function
        Case %DLL_PROCESS_DETACH
           LibMain = 1   'success!
           'LibMain = 0   'failure!
          Exit Function
        Case %DLL_THREAD_ATTACH
           LibMain = 1   'success!
           'LibMain = 0   'failure!
          Exit Function
        Case %DLL_THREAD_DETACH
           LibMain = 1   'success!
           'LibMain = 0   'failure!
          Exit Function
      End Select
    End Function
    ------------------
    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se

    Leave a comment:


  • Fred Oxenby
    replied
    Well, guys, as my problem is not solved but worked around, I can make yokes about it.
    I have no hard feelings visavi powerbasic.I know that if my code is failing that is my problem.
    I also know that here is a single instruction failing in the code
    Follow my code and you will se that 15000 bytes are replaced
    in one single instruction.
    Follow my code and you will also find one of those stupid programmers that
    reset all errorflags before he makes an potential dangerous call
    Code:
          ErrClear:Get$ gIn.FilNr, gIn.BuffSize, glbInBuff
          If ErrClear > 0 Then rc%=102:GoSub DebugExit:Function = 102: Exit Function
    Just to be sure that errors comes from the executed instruction.
    Next, relevant sequence of instructions
    Code:
          ErrClear:Get$ gIn.FilNr, gIn.BuffSize, glbInBuff
          If ErrClear > 0 Then rc%=102:GoSub DebugExit:Function = 102: Exit Function
          Replace Any glbAscii With glbEbcdic In glbInBuff
          glbInBuff = Tmp$ + glbInBuff
    I don't use ErrClear here or checking Err or ErrApi. Why?
    because I have never been able to get anything but zero on this
    instruction. Even abusing Replace Any with diffrent size of
    fromChar$ and ToChar$ return Zero in the ErrApi and Err-variable
    If it is not Replace Any that produces a partial faulty buffer,
    could it be the merge-instruction:
    glbInbuff = Tmp$ + glbInBuff
    Perhaps, but then this merge has to take glbInBuff and translate
    part of it back to ascii before merging the two strings. I don't think this is very likely to happen.
    How do I find out that the buffer is not correctly translated?
    Because pos 1 in every subpart of the string ended with char 0A is a known value,
    (You can also describe it as the first char after char 0A)
    And I check this value.
    During this check of the glbInbuff, it is not altered, tampered with or anything like that.
    '--------
    Fred, the ball is in your court. I hope we can resolve this RSN.
    If you are not part of the sulotion, you are a part of the problem.
    Sure, but it would be nice, given the fact that this really happens,
    if someone from the backroom of powerbasic R&D (have I said this before..?)
    stepped forward and told me that if there is a problem when
    using Replace Any, ErrApi will hold a reference to whatever
    caused the problem and the Err variable will be non-zero.
    Finally, I have appreciated every single advice I have been given here on this board,
    No question about it, Many of them will be followed promptly,
    including backing down NT4 to SP4 and make sure IE 4.01 is installed. Then I will run full scale test on this machine, making sure that 'live data' is not involved in the testing.

    ------------------
    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se



    [This message has been edited by Fred Oxenby (edited April 12, 2000).]

    Leave a comment:


  • Fred Oxenby
    replied
    According to my logs, we have never received even a single report of problems or
    evan a query regarding REPLACE or REPLACE ANY (with the exception of a couple of enquiries
    that turned out to be mismatched string lengths with the ANY clause).
    Lance, remember "Houston... we might have a problem" from
    march 1999 (a year ago).
    As I said earlier, at that time I had not enough hard proof to persuit the matter. It was not crystal clear what happened.
    I was not even really sure it was the Replace-instruction.
    At that time the problem was solved by using Stamina-routine
    instead of Replace.
    I even sent support the complete program
    Supports reply then were "if there are a bug in PB you can prove
    this with code less than 10 lines, otherwise there are no bug"
    (freele translated while trying to pull the knife out of my heart)



    ------------------
    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se

    Leave a comment:


  • Chris Boss
    replied
    Fred;

    I mentioned this earlier and I think Hutch has "zeroed" in the likelyhood of the problem being in the Windows OLE engine.

    While a PB app may be dependent upon a single OS DLL, that OS DLL (OLE in this case) may have dependencies of its own.

    The problem occurs when a particular OS may have "mismatched" DLLs. There are more than one OLE DLLs in the OS and it is possible that one or all of them have been overwritten by an incorrect version. Some applications don't install corectly and may overwrite an "NEW" OS DLL with an "OLDER" version, which can create an OS DLL nightmare.

    While I can't be sure this is the cause, it is definitely worth investigating the OS OLE DLLs to see if incorrect ones are in use.

    Another area of concern is the affect of "other" apps running at the same time as yours. A good example is MS Interent Explorer. Running an app after IExplorer has been run can reak havoc for some apps, likely bacause of some bugs in Microsofts own apps. As a rule, I never run my PowerBasic compiler after running IExplorer. I always reboot and then start working on PB apps. I just don;t trust IExplorer.

    The main point here, is that your code may be failing "because of external reasons" not because of your code or the PB compiler.

    Lance, is right. If the Replace function was that unreliable, then they would be inundated with reports of a bug in the compiler. The replace function is used a great deal by PB programmers and a bug in it would have been apparent very quickly.



    ------------------

    Leave a comment:


  • Lance Edmonds
    replied
    Ok, time to make a comment or two here...

    1. Fred, you said that REPLACE ANY with a 15000 bytes string fails, right? I tried this code:

    #COMPILE EXE
    FUNCTION PBMAIN
    A$ = STRING$(15000,"A")
    B$ = "A"
    C$ = "B"
    REPLACE ANY B$ WITH C$ IN A$
    MSGBOX "zero for success... we get " & FORMAT$(INSTR(A$, B$))
    END FUNCTION

    This code runs fine for me... the result is zero every time. I tried it under Windows 2000 (NT5) as I don;t have NT4 here. However, others with NT4 are encouraged to execute this code too.

    2. Your code apparently fails within a DLL not an EXE, but as we have not seen compilable code, nor it seems has anyone else encountered this error... we can only mark this one as an "unconfirmed report".

    According to my logs, we have never received even a single report of problems or evan a query regarding REPLACE or REPLACE ANY (with the exception of a couple of enquiries that turned out to be mismatched string lengths with the ANY clause).

    3. Try the code I posted above... Try it yourself under as many NT4 machines you can get your hands on, and also make a DLL out of it to double check this against your complaint. Lets get to the bottom if this once and for all.

    In summary, continuing with the "guesswork" in this thread is just wasting everyones time until someone can come up with a definitive conclusion as to the cause of the problem or, at the very least, a snippet of compilable code that shows the problem up.

    Fred, the ball is in your court. I hope we can resolve this RSN.

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Steve Hutchesson
    replied
    Fred,

    I wrote a small test piece today using the Replace command and then
    decompiled it to see what it was doing and it just does not have any
    problems in the code. It uses the normal OLE string pool in the
    normal way so the code is in itself fine. This means it can ONLY be
    a buffering problem with the OLE string pool with the version of NT
    and service pack that you customer is using.

    Now in the short term, you are looking for a workaround to stop the
    crashes, even though your own code is fine. It is not uncommon to
    have to do workarounds on OS code as badly written as some of this
    late Microsoft stuff is.

    OLE string is a pre-allocated pool of memory which is why its faster
    than GlobalAlloc and it sems that the later operating system versions
    are making more use of it so it only takes one messup from Microsoft
    to cause a problem.

    Now basically your options are to try and take the load off the OLE
    string pool and you have a few options you can test out quickly to
    see if it will help.

    1. De-allocate the basic string each time it is used which means
    once per loop. a$ = ""

    2. Try flushing each block of output to disk after each disk write.

    It is not good code design and it will slow the code up but it may
    help to stop the crashes.

    Good Luck with it.

    [email protected]

    ------------------

    Leave a comment:


  • Eric Pearson
    replied
    Fred --

    > You have not seen the word "B?G" anywhere in my posting.

    Among other things you said "I don't believe the compiler is responsible for the failing Replace-instruction I know that. But let's not argue semantics, let's try to fix your problem...

    > I will never be able to dictate what operating system my
    > customer will use in the future

    I can't tell my customers "you must use version X of Windows" either, but I can -- and do -- tell them things like "Windows NT4 Service Pack X contains a serious bug that is known to cause intermittent problems in our programs". If they argue with me, and they insist that all of their other programs are working fine, I say something like "Why do you think Service Pack 2 exists? Because Service Pack 1 was not perfect. And neither is the most current Service Pack, and the next one won't be perfect either."

    I just re-read this entire thread looking for clues, and you said this...

    > This code does not work in NT4 SP6a

    Service Pack 6 has a reputation of "creating more problems that it solved" so I'd be very suspicious. And SP6 is recent enough that most people have not installed it yet. I have not, have you? How about the customers where your program is working properly. To lurkers: Is there anybody out there who has installed SP6a that would volunteer to run a test program for Fred?

    I am particularly suspicious of Windows because of what you said about the apparent correlation between external programs and your program's problems.

    Finally, I would like to modify your "one page of translated text" analogy. It seems to me that 15000 bytes is more like a stack of ten pages. So I would say "I gave Hans a stack of ten pages to translate. When he is done, he gives them to Gretta (the code between the REPLACE and the error-detection code) and she gives them to me. Once in a while the last page is not translated."

    So who do you mistrust: Hans (the compiler) or Gretta (the other source code)?

    Or maybe it's that mischief-maker from Redmond, Bill. He seems to enjoy appearing unexpectedly and scrambing other people's work!

    -- Eric



    ------------------
    Perfect Sync: Perfect Sync Development Tools
    Email: mailto:[email protected][email protected]</A>

    Leave a comment:


  • Guest
    Guest replied
    Hello Fred, is the problem arising with ANY specific service pack on NT4?

    There have been bugs before with the OLE dll's. I don't do service packs unless
    I absolutely need them.



    [This message has been edited by Ron Pierce (edited April 12, 2000).]

    Leave a comment:


  • Fred Oxenby
    replied
    Eric,
    You have not seen the word "B?G" anywhere in my posting.

    And Yes, unfortunately I have made up my mind about Replace-command
    But I am not rejecting #Register None, ErrApi etc.
    I answered the question if I used them. And I told the truth.I did not use them.
    I have tried ErrApi. It returns zero, which I interpret as 'no problem detected'
    or 'not applicable in this situation.'
    My initial question was this:
    I need a very quick sulotion to this problem.
    Can someone help?
    Can I prevent context-switching around the replace-command?
    I think we have to draw a very sharp line in the discussion.
    Above the line the Question is:Is Replace producing false result
    Below the line we can always discuss:What triggers Replace to produce false result
    ABOVE THE LINE:
    If you have one page of text in German language.
    You ask a trusted person (Hans) to translate it into English.
    When you get the page back from Hans,
    You take another page,that already is in English language,
    and put that page in front of Hans page.
    Later when you read it, on page two (witch Hans has translated),
    you find the last paragraph still to be in German language
    What Question do You ask yourself ?
    1)Yee, I have known Hans for very long, and he has (well almost) never failed me,
    Perhaps if I put the fist side upside down, the last paragraph will be in English too?
    2)Yee, something disturbed Hans, perhaps I should lock the doors around him while
    he is working?
    BELOW THE LINE
    1) I think it was the new girl in the neighborhood that passed by Hans window.
    I will ask her to move somewhere else, so she is not disturbing Hans
    2) etc...
    '--
    In my humble opinion there are no question about it:
    Running my program on WinNt4:
    Replace is sporadic producing false result.

    Running same program on same machine with Win98SE installed:
    Replace is doing its work correctly.
    '--
    I will never be able to dictate what operating system my customer will use in the future,
    and if I have to abandon the 'Replace-instruction' and replace it with something else,
    this rewrite of code will be of such magnitude, that my decision to use 'Powerbasic' will be
    loudly questioned.
    If I have to verify every Replace-instruction the impact on speed would put me out of
    buissnes in no time at all.
    '--
    In my humble opinion, no external program, no network congestion, may never interfere
    with a single instruction like Replace, and cause it to silently produce false result.
    '--


    ------------------
    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se

    Leave a comment:


  • Eric Pearson
    replied
    Fred --

    I appreciate the way you feel -- I've been there many times -- and I am absolutely not saying "there is no bug in REPLACE ANY", but please consider the following, and accept it in the spirit in which it is offered. I really am trying to help.

    > you don't have to do any testing, to see if
    > the instruction failed to do its job.

    Please correct me if I'm wrong, but it appears that, at least in the code that you posted, you are not testing the glbInBuff string immediately after the REPLACE ANY which you believe is failing. Right after the REPLACE ANY you have this line...

    glbInBuff = Tmp$ + glbInBuff

    ...which, at least in theory, could produce a "mixed result" string of the type that you are describing. For example, if something (like a memory corruption) was going wrong and the gIn.Charset did not have the value that you expect, and as a result the REPLACE ANY did not even execute, you could see a glbInBuff string that was partially converted (Tmp$) and partially not (the glbInBuff string that did not get REPLACEd as expected). Without seeing more code I can't be certain, but it looks that way to me.

    Fred, clearly something is going wrong with your program. When you run the exact same program twice with exactly the same data and get different results, something is obviously not right. But based on my own experience with problems like this I'm not convinced (as you seem to be) that REPLACE ANY is at fault. It is a truism that "if you think you know the answer ahead of time, that is the answer that you will find", and I'd like to encourage you to perform additional tests.

    Any number of different memory-corruption mechanisms could, at least in theory, cause the type of behavior you are describing. Maybe the string is being REPLACEd correctly but is being corrupted later. Maybe a numeric variable like gIn.Charset is being corrupted. Maybe... who knows?

    Please don't get upset with me for saying this, but you seem to dismiss ideas like ERR/ERRAPI/GetlastError, writing your own REPLACE function, and #REGISTER NONE as "not worth trying", and that can be frustrating for those of us that try to offer help on this BBS. And please don't get upset with us for not simply agreeing with you that is a bug in the compiler.

    Also, it would really help if you could post a complete example that fails, and let a variety of people test it on a variety of NT4 systems. Maybe that one customer site is running a certain NT Service Pack, or has a network-wide problem of some kind, or...?

    I doubt that you'll find anybody on this BBS who is 100% sure that any given PowerBASIC function is bug free. But you will find many, many, many people who have been convinced that they'd found a compiler bug, only to slap their forehead later. That being said, once in a while people DO find new compiler bugs, and most of us are open to that possibility, but we tend to "play the odds" and place our bets on the more common cause of problem, code bugs.

    -- Eric


    ------------------
    Perfect Sync: Perfect Sync Development Tools
    Email: mailto:[email protected][email protected]</A>

    Leave a comment:


  • Fred Oxenby
    replied
    Chris, I don't believe the compiler is responsible for the failing
    Replace-instruction I know that.
    If you do a simple test like this:
    Code:
    C$=String$(15000,"A")
    A$="A":B$="B"
    Replace Any A$ with B$ in C$
    and your C$-string show you 9500 "B" followed by 5500 "A"
    you don't have to do any testing, to see if the instruction failed to do its job.
    Just looking at the resulting C$-string proves it did not.
    --
    My published function shows that there is a validity-check of the output
    from Replace-instruction.
    Whenever this validity-check fails, and before doing anything else,
    the failing buffer (glbInBuff) is saved to a local file,
    File Position,Buffer Size and Buffer position is saved in the same file
    After that the function bails out and returns a failure code.
    This gives me the hard data I need to examine the reason of failure
    You probably realize that this behavior is not intended for checking
    the replace-instruction. It is there to assist my customers to find and correct
    problems in their data files.


    ------------------
    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se

    Leave a comment:

Working...
X