Announcement

Collapse
No announcement yet.

Where am I?

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

  • Where am I?

    It appears that you cannot compile this

    Code:
     IF FUNCNAME$="PBMAIN" THEN
                EXIT FUNCTION
            ELSE
                EXIT SUB
                END IF
    If I am in PBMAIN the compiler says I am not in a SUB
    If I am in a SUB, the compiler says I am not in a FUNCTION

    and it will not compile

    I know I am one or the other!

    This code is me trying to write generic code for exiting out of a program when I have found an ERR and have reported on it. I might find the ERR in PBMAIN, or in a SUB or in a SUB called by a SUB or so on.

    I know I can code my way around this - by having two error routines, one for PBMAIN and one for subroutines.

    Is there a better way?

    [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
    Kerry Farmer

  • #2
    Something like this of use to you?

    Code:
    Function PBMain() As Long
       If FuncName$ = "PBMain" Then Exit Function Else GoTo EndOfProcedure
    EndofProcedure:
    End Function

    Comment


    • #3
      One way is to not use SUBS

      FWIW, I never use SUBS. I write everything as a FUNCTION, even if I don't use the return value.

      And I don't really see the point of your routine if the purpose is to "exit out of a program". Exit SUB will just take you back to the calling SUB or FUNCTION.
      --
      [URL="http://www.camcopng.com"]CAMCo - Applications Development & ICT Consultancy[/URL][URL="http://www.hostingpng.com"]
      PNG Domain Hosting[/URL]

      Comment


      • #4
        Gary - If I am in a subroutine, that does not work as it will not accept an 'EXIT FUNCTION'

        Stuart - if I have a nice common error routine then I can check after exiting any sub which checks errors if ERR <> 0 and then I can exit sub or function as appropriate then.

        The real point is that the compiler is making the error at compile stage when I think it should be checking at compiled stage.

        I can easily program around it and have done. But I wondered if I asked the question - what would a good programmer do?

        BTW PBCC and Windows 10 if that is relevant.
        [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
        Kerry Farmer

        Comment


        • #5
          Can't get all upper case to post?
          Code:
          function pbmain
           if funcname$ = "PBMAIN" then 0
          0
          end function

          Comment


          • #6
            Gary had the right idea using GOTO (without EXIT)

            Code:
            FUNCTION PBMAIN
             If FUNCNAME$ = "PBMAIN" THEN 0
             IF FUNCNAME$ = "PBMAIN" THEN GOTO 0
             IF FUNCNAME$ = "PBMAIN" THEN GOTO EndOfProcedure
             IF FUNCNAME$ = "PBMAIN" THEN EndOfProcedure
            EXIT FUNCTION 'optional normal exit
            0
            EndOfProcedure:
            END FUNCTION
            Last edited by Mike Doty; 2 Jun 2018, 08:52 AM.

            Comment


            • #7
              How about a watchdog Timer or Threaded Function that monitors, the value of a global (gStatus) or an Event, and reacts accordingly.

              Working Functions or Subs could set the value of gStatus on exit or as required?


              Rgds, Dave

              Comment


              • #8
                To me this is a good case for judicious use of GOTO. I usually use something like this:

                Code:
                FUNCTION MyFunction() as long
                
                  (some code here)
                
                  IF (SomeConditionThatMeansBailOut) then goto ExitFunc
                
                ExitFunc:
                
                 (clean up code here, if needed
                
                END FUNCTION

                Real programmers use a magnetized needle and a steady hand

                Comment


                • #9
                  This code is me trying to write generic code for exiting out of a program when I have found an ERR and have reported on it. I might find the ERR in PBMAIN, or in a SUB or in a SUB called by a SUB or so on.
                  Sounds like ON ERROR GOTO ErrorRtn

                  or something like this which also logs each goto

                  Code:
                  GLOBAL gs AS STRING
                  $format = "&: &"+$CR
                  
                  FUNCTION PBMAIN AS LONG
                   MySub
                   MyFunc ""
                   ? gs,%MB_SYSTEMMODAL,"EXIT by GOTO"
                  END FUNCTION
                  '---------------------------------------------
                  SUB MySub
                   IF FUNCNAME$ = "MYSUB" THEN GOTO ExitFunc
                  EXIT SUB
                  ExitFunc:
                   Logit FUNCNAME$
                  END SUB
                  '---------------------------------------------
                  FUNCTION MyFunc(s AS STRING) AS LONG
                   IF FUNCNAME$ = "MYFUNC" THEN GOTO ExitFunc
                  EXIT FUNCTION
                  ExitFunc:
                   Logit FUNCNAME$
                  END FUNCTION
                  '---------------------------------------------
                  SUB Logit(sFuncname AS STRING) THREADSAFE
                   gs+=USING$($format,TIME$,sFuncName)
                  END SUB




                  Comment


                  • #10
                    ? in functions named other than PBMAIN ?

                    "EXIT [,EXIT...] ' The nearest enclosing block structure"
                    instead of EXIT FUNCTION or EXIT SUB? As long as you're not "inside" a command (IF, SELECT, DO, etc) in the function or sub. Put another way, if the sub or function is the "nearest block", then do not specify SUB or FUNCTION after the EXIT.
                    Dale

                    Comment


                    • #11
                      Dale,
                      Not sure what you are saying since EXIT only works in LOOPS.
                      Examples, that will not compile
                      Code:
                      FUNCTION PBMAIN () AS LONG
                       IF FUNCNAME$="PBMAIN" THEN
                        EXIT FUNCTION
                       ELSE
                         EXIT
                       END IF
                      END FUNCTION
                      Code:
                      FUNCTION PBMAIN () AS LONG
                       IF FUNCNAME$="PBMAIN" THEN EXIT 'DO loop expected
                      END FUNCTION

                      Comment


                      • #12
                        Good catch.

                        "Using EXIT by itself will leave the most recently executed structure, but not an outer block." bold added.

                        So a FUNCTION/END FUNCTION or SUB/END SUB is an outer block. This one on me.
                        Dale

                        Comment


                        • #13
                          All good ideas people - thanks

                          [Dave I am not that good as a programmer!]

                          What I really want is an 'EXIT PROGRAM'

                          My 'goto' level solution is to have two error routines, one for functions (ie PBMAIN) and one for subroutines. Then I have another check for ERR <> 0 after exiting any SUB and exiting again. This second exit function also has to have two versions - Function (ie PBMAIN) and SUB

                          In my case the error routines are MACROS.

                          Many of my programs are #CONSOLE OFF and I want to display the error so I have to go into what I call a Popup program.

                          So my error routine is:

                          Code:
                          GLOBAL event_data AS STRING
                          MACRO error_check_no_console (nameoferror)
                          IF ERR <> 0 THEN                                              'error check
                                  event_data =  EXE.PATH$ + " "+FUNCNAME$  + " "+ nameoferror + " "+ FORMAT$(ERR,"###") + " "+ ERROR$(ERR)
                                  SHELL  "popups.exe 2" + event_data,1
                                  'in here I will add EXIT FUNCTION or EXIT SUB
                                  END IF
                          END MACRO
                          I often add more info into the name of error
                          The '2' tells the POPUP that this is the error routine. I also go to popups for reasons other than errors such as quick reports on progress or totals etc.

                          [Interesting - I just realised that FUNCNAME$ works in a FUNCTION or a SUB and EXIT FUNCTION does not. Is that a slight inconsistency?]

                          Thanks again guys - what a great forum!
                          [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
                          Kerry Farmer

                          Comment


                          • #14
                            Originally posted by Kerry Farmer View Post
                            All good ideas people - thanks

                            [Dave I am not that good as a programmer!]

                            What I really want is an 'EXIT PROGRAM'

                            My 'goto' level solution is to have two error routines, one for functions (ie PBMAIN) and one for subroutines.

                            Just to avoid confusion:
                            What you have is one error routine for functions and one for procedures. Subroutines would use one of these, which one would be dependent on whether it was part of a function or a procedure. A subroutine is a branch within a function or procedure.

                            Strictly speaking, there is no such thing as a SUB

                            "SUB and END SUB define a subroutine-like block of statements called a procedure (or subprogram),"



                            This confusion of terms is one reason I make everything a function


                            --
                            [URL="http://www.camcopng.com"]CAMCo - Applications Development & ICT Consultancy[/URL][URL="http://www.hostingpng.com"]
                            PNG Domain Hosting[/URL]

                            Comment


                            • #15
                              Program can be ended in PBMAIN, PopUp or after PopUp
                              Programs should end in PBMAIN, in my opinion and not use just the END statement.


                              PopUp any amount of data to display in sMsg$ (used MACRO in this example) using default program for .TXT files.
                              Extra features, thread safe, no waiting for PopUp, optional sound on error, error file in same path as executable

                              Could change "error.txt" to "error.htm" and use html error messages
                              Could replace shell with GRAPHIC WINDOW

                              Code:
                              #INCLUDE "win32api.inc"
                              MACRO ShowError = USING$("& & &",TIME$,FUNCNAME$,ERROR$(ERR))
                              $errorfile = "error.txt"
                              %beeponerror =1
                              
                              FUNCTION PBMAIN AS LONG
                               ERR = 61 'simulate disk full
                               IF ERR THEN PopUp ShowError
                               Test1
                              END FUNCTION
                              
                              SUB Test1
                               ERR = 53 'simulate file not found
                               IF ERR THEN PopUp ShowError
                              END SUB
                              
                              SUB PopUp(sMsg AS STRING) THREADSAFE
                               IF %beeponerror THEN BEEP
                               LOCAL hFile AS LONG
                               hFile = FREEFILE
                               DO
                                ERRCLEAR
                                OPEN EXE.PATH$ + $errorfile FOR OUTPUT AS hFile
                                IF ERR THEN SLEEP 50
                               LOOP UNTIL ERR = 0
                               PRINT #hFile, sMsg
                               CLOSE #hFile
                               ShellExecute (%NULL, "OPEN", $errorfile, BYVAL %NULL, CURDIR$, %SW_SHOWNORMAL)
                               SLEEP 250 'avoid multiple shells at the same time
                              END SUB

                              Comment


                              • #16
                                What I really want is an 'EXIT PROGRAM'
                                END statement
                                Purpose Terminate program immediately.
                                Syntax END [nErrorLevel&]
                                Remarks Normally, PowerBASIC programs are terminated when you exit the PBMAIN or WINMAIN() function. It should always be your goal to end programs in this fashion, so that the compiler and the operating system can do everything possible to leave things in an orderly state.

                                The END statement is an alternative termination method which should only be used in limited circumstances. It may be helpful in emergency situations, such as a fatal error like "out of memory". It's also useful (temporarily) in the conversion of DOS programs, just for the sake of compatibility. However, once conversion is complete, you should eliminate it as soon as possible.

                                The optional nErrorLevel& value has an effective range of 0 to 255. Batch files may act on the result through the IF [NOT] ERRORLEVEL batch command.
                                Restrictions END may not be used in a DLL. END is intended only for temporary use in converting DOS programs to Windows. You should convert it to the standard EXIT FUNCTION method as soon as possible. It should be avoided while any COM objects are active.
                                See also EXIT, PBMAIN, WINMAIN

                                Comment


                                • #17
                                  One advantage of using functions in lieu of subs is that you can use the return value as an error flag which can cascade up through nested levels.

                                  Code:
                                  Function PBMain() as long
                                  ...
                                  If not SaveIt() then exit function
                                  ...
                                  End Function
                                  
                                  Function SaveIt() as long
                                  If Not Validate() then Exit Function
                                  ......
                                  Function = %OK
                                  End Function
                                  
                                  Function Validate() as long
                                  ...
                                  if x <> y then
                                  msgbox "Error....."
                                  exit fuction
                                  end if
                                  .....
                                  function = %OK
                                  End Function
                                  A failure in Validate cascades up through SaveIt and causes PBMain to exit.
                                  --
                                  [URL="http://www.camcopng.com"]CAMCo - Applications Development & ICT Consultancy[/URL][URL="http://www.hostingpng.com"]
                                  PNG Domain Hosting[/URL]

                                  Comment


                                  • #18
                                    Code:
                                    VOID ExitProcess(
                                        UINT uExitCode     // exit code for all threads  
                                       );
                                    I agree with the view that you should exit a PB executable in the PBMAIN but if you really have to write sloppy code, ExitProcess() is the safe way to exit any executable.
                                    hutch at movsd dot com
                                    The MASM Forum

                                    www.masm32.com

                                    Comment

                                    Working...
                                    X