STARTing procedures by address

In the SV newsgroups James Hrubes asked a question about whether it's possible to START a procedure via the procedure's name rather than its label. The short answer is no. Say you have a procedure called BrowseStudents. BrowseStudents is a label, and 'BrowseStudents' is a string, and the Clarion runtime library doesn't provide a way of translating a string to a procedure label.

In response to James' question, Maarten Veenstra posted this little gem from an unknown author. This program illustrates another approach, which is to store the ADDRESS of a procedure and then START the address instead of the label.

But there's a trick. Take a close look at the DynaStart prototype in the MAP:

   Program
include('builtins.clw')
Procs  LONG,DIM(16)

 MAP
  Main
  BrowseStudents
  BrowseTeachers
  BrowseSchools
  BrowseClassRooms
  MODULE('Clarion')
    DynaStart(LONG,LONG),LONG,PROC,NAME('Cla$START')
  END
 END

 CODE

 Procs[1] = address(BrowseStudents)
 Procs[2] = address(BrowseTeachers)
 Procs[3] = address(BrowseSchools)
 Procs[4] = address(BrowseClassRooms)
 MAIN

Main  PROCEDURE
Window WINDOW('Select Procedure'),AT(,,219,69),|
         FONT('MS Sans Serif',8,,FONT:regular,CHARSET:ANSI),|
         CENTER, GRAY
       LIST,AT(93,18,103,10),USE(?List1),VSCROLL,DROP(4),|
         FROM('BrowseStudents|BrowseTeachers|BrowseSchools|BrowseClassRooms')
       PROMPT('Select Procedure:'),AT(23,18),USE(?Prompt1)
       BUTTON('Start Selected Procedure'),AT(60,44,99,14),USE(?StartButton)
     END
     CODE
     OPEN(Window)
     SELECT(?List1,1)
     ACCEPT
     CASE FIELD()
      OF ?StartButton
       CASE EVENT()
       OF EVENT:Accepted
        DynaStart(Procs[CHOICE(?List1)],25000)

       END
     END
     END
 
BrowseStudents PROCEDURE
    CODE
     MESSAGE('Students')

BrowseTeachers PROCEDURE
   CODE
   MESSAGE('Teachers')

BrowseSchools     PROCEDURE
   CODE
   MESSAGE('Schools')


BrowseClassRooms  PROCEDURE
   CODE
   MESSAGE('ClassRooms')

You might think you could use START directly, but you can't. The libsrc\builtins.clw contains the following prototype:

 START(_PROC,UNSIGNED=0),SIGNED,PROC,NAME('Cla$START')  

And _PROC is a procedure prototype:

_PROC(),TYPE

The compiler complains if you attempt to pass an address instead of an actual procedure.

As the unknown author of that example deduced, internally START simply takes the address of a procedure. So the redeclaration of START uses LONG parameters instead, and now you can pass the address of any parameterless procedure. Presumably you could take the same approach with the other two forms of START.

It's a nifty bit of code. So who wrote it?

Posted: September 1 2009

Clarion Roadmap

Try the roadmap (beta)

Search ClarionMag

 

Advanced search

From the archives

A Callback Technique for Capesoft's FileManager2

12/21/2006 12:00:00 AM

CapeSoft's FileManager2, and its more recent incarnation FileManager3, are amazing products: they completely automate the process of upgrading client databases, whether local or across a network, and make it easy to do file maintenance. Randy Rogers shows how to add a callback procedure to FM2 to provide user feedback during startup.