Advanced Topics&Reference Guide
Advanced Topics&Reference Guide
Advanced Topics & Reference Guide COPYRIGHT 1994-2003 SoftVelocity Incorporated. All rights reserved.
This publication is protected by copyright and all rights are reserved by SoftVelocity Incorporated. It may not, in whole or part, be copied, photocopied, reproduced, translated, or reduced to any electronic medium or machine-readable form without prior consent, in writing, from SoftVelocity Incorporated.
This publication supports Clarion. It is possible that it may contain technical or typographical errors. SoftVelocity Incorporated provides this publication as is, without warranty of any kind, either expressed or implied.
SoftVelocity Incorporated 2769 East Atlantic Blvd. Pompano Beach, Florida 33062 (954) 785-4555 www.softvelocity.com
Trademark Acknowledgements: SoftVelocity is a trademark of SoftVelocity Incorporated. Clarion is a trademark of SoftVelocity Incorporated. Btrieve is a registered trademark of Pervasive Software. Microsoft, Windows, and Visual Basic are registered trademarks of Microsoft Corporation. All other products and company names are trademarks of their respective owners.
Contents:
Introduction Advanced Topics: 5 7
Clarion 6 Migration Tips.......................................................................................................7 DLL Initialization............................................................................................................7 Change of EVALUATE Error Codes .............................................................................7 Embedding code when closing a Process procedure...................................................8 General Rules regarding your data and the new Thread Model...................................9 Heap Overflow Error when migrating applications........................................................9 ISAM File Access Performance ....................................................................................9 Migrating Large Dictionaries and Data Paths .............................................................10 Migration of hand coded project files ..........................................................................10 POINTER(File) and POSITION(File) ..........................................................................11 Remove MDI attribute from dockable toolbar windows ..............................................11 TXA Comparison Technique.......................................................................................11 Use of Error Managers during DLL Initialization .........................................................12 Dictionary Class.................................................................................................................13 The New Thread Model of Clarion 6 .................................................................................14 Launching a thread - behind the scenes ...........................................................................15
17
Clarion Language Utilities .................................................................................................17 BeginUnique (Set Application to Run in a Single Process) ........................................18 BLOBTOFILE (Copy Data from BLOB Field to File)...................................................19 BYTETOHEX (convert a BYTE to Hexadecimal)........................................................20 CreateDirectory (Create a directory)...........................................................................21 EndUnique (Close an application's event handle) ......................................................22 FileExists (Confirm file existence)...............................................................................23 FILETOBLOB (Copy data from a file to a BLOB field)................................................24 FullDrag (Query/Change Window Drag Setting).........................................................25 GetFileDate (Get the file date) ....................................................................................26 GetFileTime (Get the file time)....................................................................................27 GETREG(get Windows registry entry) ........................................................................28 GetTempFileName (Generate a temporary file) .........................................................29 GetTempPath (Return TMP or TEMP environment path) ..........................................30 GetUserName (Return Network User Name) .............................................................31 IsTermServer (Verify Terminal Server Usage) ...........................................................32 LONGTOHEX (convert an unsigned LONG to Hexadecimal) ....................................33 PROP:WindowsVersion ..............................................................................................34 PUTREG (write value to Windows registry)................................................................35 RemoveDirectory (Remove a directory) .....................................................................37 ResizeImage (Resize an image to fit a control) ..........................................................38 SHORTTOHEX (convert an unsigned SHORT to Hexadecimal) ...............................39
Advanced Topics & Reference Guide ValidateOLE (Validate OLE Control Creation)............................................................40 WindowExists (Validate Window Existence)...............................................................41 Commonly Used Equates..................................................................................................42 Template Equates (TPLEQU.CLW)............................................................................55
59
Introduction .................................................................................................................59 Project System Macros ...............................................................................................61 Basic Compiling and Linking.......................................................................................66 Conditional Processing and Flow Control...................................................................71 SoftVelocity #pragmas ................................................................................................79 Predefined Compiler Flags .......................................................................................114 Project System Examples .........................................................................................115 Module Definition Files (.EXP Files) .........................................................................127 Special Considerations for One-Piece (Single) Executables....................................135 Version Information Resource Files..........................................................................137
139
Overview ...................................................................................................................139 Compiler Integration..................................................................................................140 Resolving Data Types...............................................................................................142 Prototyping 3GL Functions in Clarion .......................................................................153 Parameter Data Types..............................................................................................154 Return Data Types ....................................................................................................156 Passing Parameters..................................................................................................157 Resolving Calling Conventions .................................................................................159 Resolving Naming Conventions................................................................................161 Programming Considerations ...................................................................................164
169
Prototypes and Declarations.....................................................................................169 Accessing Clarion's Runtime Library from C/C++ or Modula-2 Code ......................172 Standard C Functions in Clarion's Runtime Library..................................................187
Index:
201
Introduction
Welcome to the Advanced Topics and Reference Guide! This document contains many diverse topics that are targeted for the more experienced Clarion programmer, although all users will find some parts informative and useful.
Topics include: A reference for commonly used EQUATES found in generated applications and hand coded examples. A brief overview of the new Dictionary Class used in all generated applications (that use a dictionary). Several topics regarding the new Thread Model of Clarion 6 Migration Tips An invaluable source when moving applications and projects from earlier versions to Clarion 6 A reference describing the Clarion Language Utilities, extensions of the language to help ease your programming tasks An in depth reference of the Clarion Project System Multi-langauge programming in Clarion Using external API calls with your Clarion Code
Advanced Topics
DLL Initialization
Enforcement of threaded variables in multi-DLL applications is critical in Clarion 6. In older versions, if your file definitions are set to "open in current thread" in the dictionary (the THREAD attribute is set in the FILE definition), your file definitions in your DLLs must match that definition. To ensure this, examine each applications global file control section, and make sure that all of your files are set to 'ALL THREADED' in the Threaded drop list. You CANNOT mix thread and non-threaded attributes on files in a multi-dll application. Although this programming style was permitted in earlier versions of Clarion, the initialization of preemptive threads will not allow this in Clarion 6. You can use either setting, thread or non-threaded, as long as its consistent across all DLLs and your executable.
Advanced Topics
General Rules regarding your data and the new Thread Model
1. Use the THREAD attribute on global Data (file, class, group, queue or simple types). 2. Use the THREAD attribute on module Data (file, class, group, queue or simple types). 3. Avoid the use of static variables. 4. Don't pass the address of anything within a START command - this was a common trick used by people to communicate between threads. If you do any of the above you must make them thread safe. Refer to the Multi Threaded Programming PDF for detailed information on this process. Local data (including classes that are normally instantiated locally) is automatically threaded (unless you put the STATIC attribute on it).
10
Advanced Topics
11
12
Advanced Topics
13
Dictionary Class
The new Clarion threading model dictates that the existing File and Relation Managers use threaded objects (i.e. a new instance on every thread). One of the effects of this is that the traditional ABC code that initializes both File and Relation Managers (contained in the DctInit generated procedure) now has to be executed whenever a new thread is started. Likewise, the Managers kill code (traditionally contained in DctKill) must be called whenever a thread is terminated. To facilitate this, a small globally defined class called Dictionary will be generated into every ABC template based application that does not have its global data defined external to the application. (i.e. the File and Relation managers compiled locally). The Dictionary object contains only construct and destruct methods but, more important, it is a threaded object. Example:
This means that the Construct method will be called whenever a new thread comes into existence and the Destruct method will be called whenever a thread is terminated. The constructor calls DctInit and the destructor calls DctKill. Therefore, DctInit is called whenever a thread is started and DctKill is now called whenever a thread is terminated; thus ensuring that threaded File and Relation managers are created and destroyed correctly.
14
It is much easier to access COM objects You can have threads running independently of other threads. Programs are more stable. The new thread model also makes the OLE layer much easier to work with because the object will run on the Clarion thread whereas currently it is run on its own separate thread. For more detailed information, see the Multi-Threaded Programming PDF
Advanced Topics
15
16
Reference
17
18
BeginUnique Sets an application to run as a single process applicationname A string constant or variable that specifies the full path and name of your application. Example: C:\INVOICE\INVOICE.EXE BeginUnique returns FALSE if the program specified in applicationname is already running (active). If not running, BeginUnique returns an event number specified by Windows. This event number can be used by the EndUnique statement to terminate the single process mode.
Return Data Type: Example: IF NOT BeginUnique(GLO:ApplicationName) MESSAGE(CLIP(GLO:ApplicationName) & already running. ELSE RUN(GLO:ApplicationName) END See Also:
LONG
EndUnique
Reference
19
BLOBTOFILE Copy the contents of a BLOB field to an external file. bloblabel filename The fully qualified label of the BLOB field. (Example: Customer.BlobImage) A string constant or variable that names the output file to copy the BLOB to.
BLOBTOFILE is used to copy the contents of a BLOB to an external file. If the copy fails for any reason, BLOBTOFILE returns the ERRORCODE posted. BLOBTOFILE (and FILETOBLOB) are simply binary-to-binary operations. If you need to save images to a BLOB, and later restore them to an output file, the type of image should also be saved in the database (JPG, GIF, BMP, etc.). Using BLOBTOFILE to save to a different extension can produce unpredictable results.
SIGNED
IF BLOBTOFILE(CUS:ImageBlob,'imagename.jpg')!returns an ERRORCODE if copy fails MESSAGE('BLOB did not copy due to the following ERRORCODE: ' & ERRORCODE()) END See Also:
FILETOBLOB BLOB
20
Convert a BYTE value to its Hexadecimal equivalent. A BYTE variable or constant A BYTE used to designate a lower or upper case HEX symbol (A,B,C,D,E)
BYTETOHEX is used to convert a number to its Hexadecimal equivalent. If the flag variable is non-zero, any non-numeric Hexadecimal symbols are returned in lowercase. If zero (default), the non-numeric digits are returned in uppercase.
Return Data Type: Example: BYTETOHEX(255,0) BYTETOHEX(255,1) !returns FF !returns ff
STRING
See Also:
SHORTTOHEX LONGTOHEX
Reference
21
CREATEDIRECTORY Create a new directory directoryname A string constant or variable that stores the directory name
CREATEDIRECTORY creates a new directory with the name passed in the directoryname parameter. CREATEDIRECTORY returns zero (0) if successful, and non-zero if not. You can query the ERRNO built-in function to trap for the following error codes: 3 Path not found (One of the higher path components in directoryname) 5 Access Denied (Directory may already exist)
On some Windows versions, any attempt to create multiple levels of directories (For example. C:\dir1\dir2\dir3) will fail, but the error code will not be returned correctly. CREATEDIRECTORY will still post a non-zero value, which you can use to trap and post a generic "Directory Not Created" error.
Return Data Type: Example: MODULE('') errno(),*SIGNED,NAME('__errno__') END IF CREATEDIRECTORY(GLO:NewDirectoryName) CASE Errno() OF 3 MESSAGE(Path Not Found) OF 5 MESSAGE(Access Denied) END END See Also: !proptotype built-in error flag
BYTE
RemoveDirectory
22
EndUnique eventnumber
Closes an applications event number A numeric constant or variable that uniquely identifies an application event.
EndUnique is used to invalidate the specified application event handle. This is useful where a function using BeginUnique was no longer valid, and you need to override the single event process when subsequent applications are started.
Example: EndUnique(GLO:AppEventNumber) See Also:
BeginUnique
Reference
23
FILEEXISTS filename
Confirm the existence of a file A string constant or variable containing the name of the file (and path, if applicable)
FILEEXISTS confirms the existence of a file. If FILEEXISTS returns TRUE (1), the file exists. If FILEEXISTS returns FALSE (0), the file specified in the filename parameter does not exist.
Return Data Type: Example: IF NOT FILEEXISTS(GLO:NewFile) DO CreateFile END IF NOT FILEEXISTS(C:\INVOICE\Config.dat) InitConfig END !If the file does not exist !Call the ROUTINE to create it
BYTE
24
FILETOBLOB Copy the contents of a file to a BLOB field. filename bloblabel A string constant or variable that names the input file to copy to a BLOB field. The fully qualified label of the BLOB field. (Example: Customer.BlobImage)
FILETOBLOB is used to copy the contents of a file to a BLOB field. If the copy was unsuccessful, FILETOBLOB returns the ERRORCODE posted.
Return Data Type: Example: IF FILETOBLOB(GLO:ImageFilename, CUS:ImageBlob) !returns an ERRORCODE if copy fails MESSAGE(CLIP(GLO:ImageFilename) & ' was not copied - ERRORCODE: ' & ERRORCODE()) END See Also:
SIGNED
BLOBTOFILE BLOB
Reference
25
FULLDRAG setdragflag
Query and/or change the full window drag settings A BYTE variable or constant. TRUE (1) or FALSE (0)
FULLDRAG returns the current window drag setting. If the optional setdragflag is set to TRUE (1), full window dragging is enabled. If the optional setdragflag is set to FALSE (0), full window dragging is disabled and only the window frame will appear when dragging a window.
Return Data Type: Example: IF NOT FULLDRAG() FULLDRAG(1) END !If full window dragging is OFF !Enable it
LONG
26
GETFILEDATE filename
Return the date stamp of a file A string constant or variable containing the name of the file (and path, if applicable)
GETFILEDATE returns the date stamp of the file specified by the filename parameter. The date is returned as a LONG that is deformatted and returned in an @D2 picture format. If the file is invalid or does not exist, GETFILEDATE returns a zero (0).
Return Data Type: Example: Filedate = GETFILEDATE(LOC:Filename)
LONG
Reference
27
GETFILETIME filename
Returns the time stamp of a file A string constant or variable containing the name of the file (and path, if applicable)
GETFILETIME returns the time stamp of the file specified by the filename parameter. The time is returned as a LONG that is deformatted and returned in an @T4 picture format. If the file is invalid or does not exist, GETFILETIME returns a zero (0).
Return Data Type: Example: Filetime = GETFILETIME(LOC:Filename)
LONG
28
GETREG root
Gets the value of a specific key and/or value from the system registry. The root section of the registry from which to obtain the value. Valid values for this are defined in equates.clw and are as follows: REG_CLASSES_ROOT REG_CURRENT_USER REG_LOCAL_MACHINE REG_USERS REG_PERFORMANCE_DATA REG_CURRENT_CONFIG REG_DYN_DATA The key name of the key whose value is to be queried. This may contain a path separated by backslash \ characters. The name of the value to be queried, if omitted, the value associated directly with the key is returned. The GETREG function returns the value of named entry in the system registry as a Clarion string. If the requested entry does not exist, an empty string is returned.
keyname valuename
STRING
PROGRAM MAP. INCLUDE('EQUATES') CurrentPath CSTRING(100) ColorScheme CSTRING(100) CODE CurrentPath =| GETREG(REG_LOCAL_MACHINE,'SOFTWARE\SoftVelocity\Clarion6','root') !Returns root directory of Clarion 6 install ColorScheme =| GETREG(REG_CURRENT_USER,'Control Panel\Current','Color Schemes') !get the current user's color scheme See Also:
PUTREG, DELETEREG
Reference
29
GETTEMPFILENAME Returns the name of a temporary file prefix pathname A string constant or variable naming the prefix (first three letters) of the temporary file. If blank, the default prefix used is $$$ A string constant or variable naming the location of the temporary file. If omitted, the system TEMP or TMP directory path is used.
GETTEMPFILENAME is used to generate a temporary file. If the pathname specified is invalid, GETTEMPFILENAME returns an empty string.
Make sure to remove your temporary files that you create after use. The Windows system will not automatically remove these files.
Return Data Type: Example: !Note ## represents a random number assigned to the temporary file name message(GETTEMPFILENAME('bob','d:\help')) !created 'bob##.tmp' in D:\help message(GETTEMPFILENAME('')) !created '$$$##.tmp' in !C:\WINNT\TEMP (my TEMP path)
STRING
30
GETTEMPPATH
Returns the name of the path specified by the Windows Environment variables
GETTEMPPATH is used to return the full path designated by the TMP or TEMP Windows Environment settings.GETTEMPPATH returns the first Environment setting it finds.
Return Data Type: Example: GLO:TempPath = GETTEMPPATH( ) !return environment path
STRING
Reference
31
GETUSERNAME
GETUSERNAME is used to retrieve the current default user name, or the user name used to establish a network connection. GETUSERNAME returns a blank string if an error is encountered.
STRING
GLO:LoginName = GETUSERNAME()
32
ISTERMSERVER
It is a good practice for applications to detect whether they are running in a Terminal Services Client session in order to optimize performance. For example, when an application is running on a remote session, it should eliminate unnecessary graphic effects. If a user is running the application directly on the terminal, it is not necessary for the application to optimize its behavior. ISTERMSERVER is used to detect Terminal Server usage by returning the status of the System Metrics SM_REMOTESESSION flag. ISTERMSERVER returns TRUE if an application is running in a Terminal Services Client session, and FALSE if the application is running on the console. This function is only valid for Windows 2000 or later.
Return Data Type: Example: GLO:RemoteSessionActive = ISTERMSERVER() !is a remote session active?
BYTE
Reference
33
LONGTOHEX Convert a ULONG value to its Hexadecimal equivalent. number flag A ULONG variable or constant A BYTE used to designate a lower or upper case HEX symbol (A,B,C,D,E)
LONGTOHEX is used to convert a number to its Hexadecimal equivalent. If the flag variable is non-zero, any non-numeric Hexadecimal symbols are returned in lowercase. If zero (default), the non-numeric digits are returned in uppercase.
Return Data Type: Example: LONGTOHEX(32000000,0) LONGTOHEX(32000000,1) See Also: !returns 1E84800 !returns 1e84800
STRING
BYTETOHEX SHORTTOHEX
34
PROP:WindowsVersion
Returns the string that describes Windows version running the program.
Reference
35
PUTREG root
The root section of the registry to which to write the value. Valid values for this are defined in equates.clw and are as follows: REG_CLASSES_ROOT REG_CURRENT_USER REG_LOCAL_MACHINE REG_USERS REG_PERFORMANCE_DATA REG_CURRENT_CONFIG REG_DYN_DATA
The key name of the key whose value is to be written. This may contain a path separated by backslash \ characters. The name of the value to be written. The value to be written to the registry in the position given. If omitted, an empty string is written to the registry.
The PUTREG procedure places the value into a valuename that exists in the Windows registry.
36
Example: PROGRAM MAP. INCLUDE('EQUATES') CurrentPath CSTRING(100) ColorScheme CSTRING(100)
CODE CurrentPath = C:\Clarion6 PUTREG(REG_LOCAL_MACHINE,'SOFTWARE\SoftVelocity\Clarion6','root',CurrentPath !Sets the root directory of Clarion 6 install ColorScheme = Windows Standard PUTREG(REG_CURRENT_USER,'Control Panel\Current','Color Schemes',ColorScheme) !writes the current user's color scheme to the registry
See Also:
GETREG, DELETEREG
Reference
37
REMOVEDIRECTORY Remove an existing directory directoryname A string constant or variable that stores the directory name
REMOVEDIRECTORY removes an existing directory with the name passed in the directoryname parameter. REMOVEDIRECTORY returns zero (0) if successful, and non-zero if not. You can query the ERRNO built-in library function to trap for the following error codes: 3 Path not found (One of the higher path components in directoryname) 5 Access Denied (Path may refer to a file, root directory, or current directory)
BYTE
MODULE('') errno(),*SIGNED,NAME('__errno__') END IF REMOVEDIRECTORY(GLO:NewDirectoryName) CASE Errno() OF 3 MESSAGE(Path Not Found) OF 5 MESSAGE(Access Denied) END END See Also:
CreateDirectory
38
Resize a valid graphic file to fit inside a target IMAGE control The Field Equate Label of the target IMAGE control. A SHORT constant or variable identifying the height of the target IMAGE control in dialog units. A SHORT constant or variable identifying the height of the target IMAGE control in dialog units. A SHORT constant or variable identifying the height of the target IMAGE control in dialog units. A SHORT constant or variable identifying the height of the target IMAGE control in dialog units. A valid label of a REPORT structure. Indicates that the control to store the resized image is contained in a REPORT target instead of a WINDOW
RESIZEIMAGE is used to resize the image to fit the original control size. If an image is larger than the target control, the image will be reduced to fit the target controls position parameters. If an image is smaller than the target control, the image will be expanded to fit the target controls position parameters.
Example: CASE ACCEPTED() OF ?LookupFile ThisWindow.Update LOC:Filename = FileLookup9.Ask(0) DISPLAY IF LOC:Filename ?Image1{PROP:TEXT} = LOC:Filename !Move filename to image field ResizeImage(?Image1,114,132,90,64) !Resize it END OF ?OK ThisWindow.Update IF SELF.Request = ViewRecord AND NOT SELF.BatchProcessing THEN POST(EVENT:CloseWindow) END END
Reference
39
SHORTTOHEX Convert a USHORT value to its Hexadecimal equivalent. number flag A USHORT variable or constant A BYTE used to designate a lower or upper case HEX symbol (A,B,C,D,E)
SHORTTOHEX is used to convert a number to its Hexadecimal equivalent. If the flag variable is non-zero, any non-numeric Hexadecimal symbols are returned in lowercase. If zero (default), the non-numeric digits are returned in uppercase.
Return Data Type: Example: SHORTTOHEX(64000,0) SHORTTOHEX(64000,1) See Also: !returns FA00 !returns fa00
STRING
BYTETOHEX
LONGTOHEX
40
Validate that an OLE control has been successfully created A field number or field equate label of the OLE control. (under construction) (under construction)
VALIDATEOLE is used to verify that an OLE control has been created successfully. VALIDATEOLE returns TRUE if the OLE control has been successfully created. If not successful, VALIDATEOLE can optionally display a message box that describes why the OLE control could not be created, provided that the OLEFilename parameter is passed, and then returns FALSE. Otherwise, VALIDATEOLE just returns FALSE if only the OLEControl is designated.
BYTE
LOC:OLEActive = VALIDATEOLE( )
Reference
41
WINDOWEXISTS windowtitle
Verify that a WINDOW structure is active A string constant or variable that specifies the window name (the window's title).
WINDOWEXISTS is used to retrieve a window handle of the top-level window whose window name matches the window title. If WINDOWEXISTS succeeds, the return value is a handle to the window that has the specified window name.
BYTE
42
Reference
! Field-independent events (FIELD() returns 0) EVENT:CloseWindow EVENT:CloseDown EVENT:OpenWindow EVENT:OpenFailed EVENT:LoseFocus EVENT:GainFocus EVENT:Suspend EVENT:Resume EVENT:Notify EVENT:Timer EVENT:DDErequest EVENT:DDEadvise EVENT:DDEdata EVENT:DDEcommand EVENT:DDEexecute EVENT:DDEpoke EVENT:DDEclosed EVENT:Move EVENT:Size EVENT:Restore EVENT:Maximize EVENT:Iconize EVENT:Completed EVENT:Moved EVENT:Sized EVENT:Restored EVENT:Maximized EVENT:Iconized EVENT:Docked EVENT:Undocked EVENT:BuildFile EVENT:BuildKey EVENT:BuildDone EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE (201H) (202H) (203H) (204H) (205H) (206H)
43
EQUATE (208H) EQUATE (209H) EQUATE (20AH) EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE (20BH) (20CH) (20DH) (20EH) (20FH) (20FH) (210H) (211H) (220H) (221H) (222H) (223H) (224H) (225H) (230H) (231H) (232H) (233H) (234H) (235H) (236H)
! same as DDEexecute
44
! Windows standard functions STD:WindowList EQUATE (1) STD:TileWindow EQUATE (2) STD:CascadeWindow EQUATE (3) STD:ArrangeIcons EQUATE (4) STD:HelpIndex EQUATE (5) STD:HelpOnHelp EQUATE (6) STD:HelpSearch EQUATE (7) STD:Help EQUATE (8) STD:Cut EQUATE (10) STD:Copy EQUATE (11) STD:Paste EQUATE (12) STD:Clear EQUATE (13) STD:Undo EQUATE (14) STD:Close EQUATE (15) STD:PrintSetup EQUATE (16) STD:TileHorizontal EQUATE (17) STD:TileVertical EQUATE (18) !CURSOR Equates CURSOR:None CURSOR:Arrow CURSOR:IBeam CURSOR:Wait CURSOR:Cross CURSOR:UpArrow CURSOR:Size CURSOR:Icon CURSOR:SizeNWSE CURSOR:SizeNESW CURSOR:SizeWE CURSOR:SizeNS CURSOR:DragWE CURSOR:Drop CURSOR:NoDrop CURSOR:Zoom !ICON Equates ICON:None ICON:Application ICON:Hand ICON:Question ICON:Exclamation ICON:Asterisk ICON:Pick ICON:Save ICON:Print ICON:Paste ICON:Open ICON:New ICON:Help EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE
('<0FFH,01H,00H,00H>') ('<0FFH,01H,01H,7FH>') ('<0FFH,01H,02H,7FH>') ('<0FFH,01H,03H,7FH>') ('<0FFH,01H,04H,7FH>') ('<0FFH,01H,05H,7FH>') ('<0FFH,01H,81H,7FH>') ('<0FFH,01H,82H,7FH>') ('<0FFH,01H,83H,7FH>') ('<0FFH,01H,84H,7FH>') ('<0FFH,01H,85H,7FH>') ('<0FFH,01H,86H,7FH>') ('<0FFH,02H,01H,7FH>') ('<0FFH,02H,02H,7FH>') ('<0FFH,02H,03H,7FH>') ('<0FFH,02H,04H,7FH>')
('<0FFH,01H,00H,00H>') ('<0FFH,01H,01H,7FH>') ('<0FFH,01H,02H,7FH>') ('<0FFH,01H,03H,7FH>') ('<0FFH,01H,04H,7FH>') ('<0FFH,01H,05H,7FH>') ('<0FFH,02H,01H,7FH>') ('<0FFH,02H,02H,7FH>') ('<0FFH,02H,03H,7FH>') ('<0FFH,02H,04H,7FH>') ('<0FFH,02H,05H,7FH>') ('<0FFH,02H,06H,7FH>') ('<0FFH,02H,07H,7FH>')
Reference
ICON:Cut ICON:Copy ICON:Child ICON:Frame ICON:Clarion ICON:NoPrint ICON:Zoom ICON:NextPage ICON:PrevPage ICON:JumpPage ICON:Thumbnail ICON:Tick ICON:Cross ICON:Connect ICON:Print1 ICON:Ellipsis EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE ('<0FFH,02H,08H,7FH>') ('<0FFH,02H,09H,7FH>') ('<0FFH,02H,0AH,7FH>') ('<0FFH,02H,0BH,7FH>') ('<0FFH,02H,0CH,7FH>') ('<0FFH,02H,0DH,7FH>') ('<0FFH,02H,0EH,7FH>') ('<0FFH,02H,0FH,7FH>') ('<0FFH,02H,10H,7FH>') ('<0FFH,02H,11H,7FH>') ('<0FFH,02H,12H,7FH>') ('<0FFH,02H,13H,7FH>') ('<0FFH,02H,14H,7FH>') ('<0FFH,02H,15H,7FH>') ('<0FFH,02H,16H,7FH>') ('<0FFH,02H,17H,7FH>') ('<0FFH,02H,81H,7FH>') ('<0FFH,02H,82H,7FH>') ('<0FFH,02H,83H,7FH>') ('<0FFH,02H,84H,7FH>') ('<0FFH,02H,85H,7FH>') ('<0FFH,02H,86H,7FH>') ('<0FFH,02H,87H,7FH>')
45
BEEP:SystemDefault BEEP:SystemHand BEEP:SystemQuestion BEEP:SystemExclamation BEEP:SystemAsterisk !Range Equates REJECT:RangeHigh REJECT:RangeLow REJECT:Range REJECT:Invalid !Color Equates COLOR:NONE COLOR:SCROLLBAR COLOR:BACKGROUND COLOR:ACTIVECAPTION COLOR:INACTIVECAPTION COLOR:MENU COLOR:WINDOW COLOR:WINDOWFRAME COLOR:MENUTEXT COLOR:WINDOWTEXT COLOR:CAPTIONTEXT
! ! ! !
Above top range on SPIN below bottom range ditto Other range error Invalid input
EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE
(-1) (80000000H) (80000001H) (80000002H) (80000003H) (80000004H) (80000005H) (80000006H) (80000007H) (80000008H) (80000009H)
46
COLOR:ACTIVEBORDER EQUATE (8000000AH) COLOR:INACTIVEBORDER EQUATE (8000000BH) COLOR:APPWORKSPACE EQUATE (8000000CH) COLOR:HIGHLIGHT EQUATE (8000000DH) COLOR:HIGHLIGHTTEXT EQUATE (8000000EH) COLOR:BTNFACE EQUATE (8000000FH) COLOR:BTNSHADOW EQUATE (80000010H) COLOR:GRAYTEXT EQUATE (80000011H) COLOR:BTNTEXT EQUATE (80000012H) COLOR:INACTIVECAPTIONTEXT EQUATE (80000013H) COLOR:BTNHIGHLIGHT EQUATE (80000014H) COLOR:Black COLOR:Maroon COLOR:Green COLOR:Olive COLOR:Navy COLOR:Purple COLOR:Teal COLOR:Gray COLOR:Silver COLOR:Red COLOR:Lime COLOR:Yellow COLOR:Blue COLOR:Fuschia COLOR:Aqua COLOR:White EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE (0000000H) (0000080H) (0008000H) (0008080H) (0800000H) (0800080H) (0808000H) (0808080H) (0C0C0C0H) (00000FFH) (000FF00H) (000FFFFH) (0FF0000H) (0FF00FFH) (0FFFF00H) (0FFFFFFH)
! Parameter to CREATE / Return value from PROP:type CREATE:sstring CREATE:string CREATE:image CREATE:region CREATE:line CREATE:box CREATE:ellipse CREATE:entry CREATE:button CREATE:prompt CREATE:option CREATE:check CREATE:group CREATE:list CREATE:combo CREATE:spin CREATE:text CREATE:custom CREATE:menu CREATE:item CREATE:radio CREATE:menubar EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22)
Reference
CREATE:application CREATE:window CREATE:report CREATE:header CREATE:footer CREATE:break CREATE:form CREATE:detail CREATE:ole CREATE:droplist CREATE:dropcombo CREATE:progress CREATE:sheet CREATE:tab CREATE:panel CREATE:rtf CREATE:sublist CREATE:toolbar FONT:thin FONT:regular FONT:bold FONT:weight FONT:fixed FONT:italic FONT:underline FONT:strikeout FONT:Screen FONT:Printer FONT:Both FONT:TrueTypeOnly FONT:FixedPitchOnly CHARSET:ANSI CHARSET:DEFAULT CHARSET:SYMBOL CHARSET:MAC CHARSET:SHIFTJIS CHARSET:HANGEUL CHARSET:JOHAB CHARSET:GB2312 CHARSET:CHINESEBIG5 CHARSET:GREEK CHARSET:TURKISH CHARSET:HEBREW CHARSET:ARABIC CHARSET:BALTIC CHARSET:CYRILLIC CHARSET:THAI EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE (24) (25) (26) (27) (28) (29) (30) (31) (32) (33) (34) (35) (37) (38) (39) (40) ! return value only ! return value only ! return value only
47
EQUATE (CREATE:list + 0100H) EQUATE (128) EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE (100) (400) (700) (07FFH) (0800H) (01000H) (02000H) (04000H)
EQUATE(0) EQUATE(1) EQUATE(2) EQUATE(4) EQUATE(8) EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE ( 0) ( 1) ( 2) ( 77) (128) (129) (130) (134) (136) (161) (162) (177) (178) (186) (204) (222)
48
CHARSET:EASTEUROPE CHARSET:OEM PEN:solid PEN:dash PEN:dot PEN:dashdot PEN:dashdotdot PEN:null PEN:insideframe BRUSH:SOLID BRUSH:NULL BRUSH:HOLLOW BRUSH:HATCHED BRUSH:PATTERN BRUSH:INDEXED BRUSH:DIBPATTERN FALSE TRUE LISTZONE:field LISTZONE:right LISTZONE:header LISTZONE:expandbox LISTZONE:tree LISTZONE:icon LISTZONE:nowhere VBXEVENT:Click VBXEVENT:DblClick VBXEVENT:GotFocus VBXEVENT:KeyDown VBXEVENT:KeyPress VBXEVENT:KeyUp VBXEVENT:LostFocus VBXEVENT:MouseDown VBXEVENT:MouseMove VBXEVENT:MouseUp BUTTON:OK BUTTON:YES BUTTON:NO BUTTON:ABORT BUTTON:RETRY BUTTON:IGNORE BUTTON:CANCEL BUTTON:HELP MSGMODE:SYSMODAL MSGMODE:CANCOPY EQUATE (238) EQUATE (255) EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE (0) (1) (2) (3) (4) (5) (6) (0) (1) (BRUSH:NULL) (2) (3) (4) (5)
EQUATE (0) EQUATE (1) EQUATE(0) EQUATE(1) EQUATE(2) EQUATE(3) EQUATE(4) EQUATE(5) EQUATE(6) EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE (0) (1) (4) (5) (6) (7) (8) (9) (10) (11) (01H) (02H) (04H) (08H) (10H) (20H) (40H) (80H)
Reference
WINDOW:OK WINDOW:NotOpened WINDOW:BadWindow WINDOW:ClosePending WINDOW:InDestroy TEXT:Field TEXT:File !DDE link types DDE:auto DDE:manual DDE:remove EQUATE (0) EQUATE (-1) EQUATE (-2) EQUATE EQUATE EQUATE EQUATE EQUATE (0) (1) (2) (3) (4)
49
! Types OMIT('***',_WIDTH32_) SIGNED EQUATE(SHORT) UNSIGNED EQUATE(USHORT) _nopos EQUATE(08000H) *** COMPILE('***',_WIDTH32_) SIGNED EQUATE(LONG) UNSIGNED EQUATE(LONG) _nopos EQUATE(080000000H) *** BOOL EQUATE(SIGNED) !DIRECTORY equates & TYPEs !Old 8.3 filename support ff_:NORMAL ff_:READONLY ff_:HIDDEN ff_:SYSTEM ff_:DIRECTORY ff_:ARCHIVE ff_:LFN EQUATE(0) EQUATE(1) EQUATE(2) EQUATE(4) EQUATE(10H) EQUATE(20H) EQUATE(80H)
50
FILE:Queue Name ShortName Date Time Size Attrib QUEUE,PRE(FILE),TYPE STRING(FILE:MaxFileName) STRING(13) LONG LONG LONG BYTE END
!FileDialog equates FILE:Save FILE:KeepDir FILE:NoError FILE:Multi FILE:LongName FILE:Directory OCX:default OCX:16bit OCX:32bit OCX:1632bit DOCK:Left DOCK:Top DOCK:Right DOCK:Bottom DOCK:Float DOCK:All EQUATE(1) EQUATE(2) EQUATE(4) EQUATE(8) EQUATE(10H) EQUATE(20H) EQUATE(0) EQUATE(1) EQUATE(2) EQUATE(3) EQUATE(1) EQUATE(2) EQUATE(4) EQUATE(8) EQUATE(16) EQUATE(31)
Reference
51
PAPER:LETTER PAPER:LETTERSMALL PAPER:TABLOID PAPER:LEDGER PAPER:LEGAL PAPER:STATEMENT PAPER:EXECUTIVE PAPER:A3 PAPER:A4 PAPER:A4SMALL PAPER:A5 PAPER:B4 PAPER:B5 PAPER:FOLIO PAPER:QUARTO PAPER:10X14 PAPER:11X17 PAPER:NOTE PAPER:ENV_9 PAPER:ENV_10 PAPER:ENV_11 PAPER:ENV_12 PAPER:ENV_14 PAPER:CSHEET PAPER:DSHEET PAPER:ESHEET PAPER:ENV_DL PAPER:ENV_C5 PAPER:ENV_C3 PAPER:ENV_C4 PAPER:ENV_C6 PAPER:ENV_C65 PAPER:ENV_B4 PAPER:ENV_B5 PAPER:ENV_B6 PAPER:ENV_ITALY PAPER:ENV_MONARCH PAPER:ENV_PERSONAL PAPER:FANFOLD_US PAPER:FANFOLD_STD_GERMAN PAPER:FANFOLD_LGL_GERMAN in PAPER:LAST PAPER:USER
EQUATE(1) EQUATE(2) EQUATE(3) EQUATE(4) EQUATE(5) EQUATE(6) EQUATE(7) EQUATE(8) EQUATE(9) EQUATE(10) EQUATE(11) EQUATE(12) EQUATE(13) EQUATE(14) EQUATE(15) EQUATE(16) EQUATE(17) EQUATE(18) EQUATE(19) EQUATE(20) EQUATE(21) EQUATE(22) EQUATE(23) EQUATE(24) EQUATE(25) EQUATE(26) EQUATE(27) EQUATE(28) EQUATE(29) EQUATE(30) EQUATE(31) EQUATE(32) EQUATE(33) EQUATE(34) EQUATE(35) EQUATE(36) EQUATE(37) EQUATE(38) EQUATE(39) EQUATE(40) EQUATE(41) EQUATE(41) EQUATE(256)
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
Letter 8 1/2 x 11 in Letter Small 8 1/2 x 11 in Tabloid 11 x 17 in Ledger 17 x 11 in Legal 8 1/2 x 14 in Statement 5 1/2 x 8 1/2 in Executive 7 1/4 x 10 1/2 in A3 297 x 420 mm A4 210 x 297 mm A4 Small 210 x 297 mm A5 148 x 210 mm B4 250 x 354 B5 182 x 257 mm Folio 8 1/2 x 13 in Quarto 215 x 275 mm 10x14 in 11x17 in Note 8 1/2 x 11 in Envelope #9 3 7/8 x 8 7/8 Envelope #10 4 1/8 x 9 1/2 Envelope #11 4 1/2 x 10 3/8 Envelope #12 4 \276 x 11 Envelope #14 5 x 11 1/2 C size sheet D size sheet E size sheet Envelope DL 110 x 220mm Envelope C5 162 x 229 mm Envelope C3 324 x 458 mm Envelope C4 229 x 324 mm Envelope C6 114 x 162 mm Envelope C65 114 x 229 mm Envelope B4 250 x 353 mm Envelope B5 176 x 250 mm Envelope B6 176 x 125 mm Envelope 110 x 230 mm Envelope Monarch 3.875 x 7.5 in 6 3/4 Envelope 3 5/8 x 6 1/2 in US Std Fanfold 14 7/8 x 11 in German Std Fanfold 8 1/2 x 12 in German Legal Fanfold 8 1/2 x 13
52
! File Driver Function equates for use with file{PROP:SupportsOp,DriverOp:n} ITEMIZE(1),PRE(DriverOp) ADD EQUATE BOF EQUATE BUILDfile EQUATE APPEND EQUATE BUILDdyn EQUATE BUILDkey EQUATE CLOSE EQUATE COMMIT EQUATE COPY EQUATE CREATE EQUATE DELETE EQUATE DUPLICATE EQUATE EMPTY EQUATE EOF EQUATE GETfilekey EQUATE GETfileptr EQUATE GETkeyptr EQUATE HOLD EQUATE LOCK EQUATE(20) LOGOUT EQUATE(22) NAME EQUATE NEXT EQUATE OPEN EQUATE PACK EQUATE POINTERfile EQUATE POINTERkey EQUATE FLUSH EQUATE PUT EQUATE PREVIOUS EQUATE RECORDSfile EQUATE RECORDSkey EQUATE BUILDdynfilter EQUATE STARTTRAN EQUATE RELEASE EQUATE REMOVE EQUATE RENAME EQUATE ENDTRAN EQUATE ROLLBACK EQUATE SETfile EQUATE SETfilekey EQUATE SETfileptr EQUATE SETkey EQUATE SETkeykey EQUATE SETkeyptr EQUATE SETkeykeyptr EQUATE SHARE EQUATE SKIP EQUATE UNLOCK EQUATE ADDlen EQUATE BYTES EQUATE
Reference
GETfileptrlen PUTfileptr PUTfileptrlen STREAM DUPLICATEkey WATCH APPENDlen SEND POSITIONfile POSITIONkey RESETfile RESETkey NOMEMO REGETfile REGETkey NULL SETNULL SETNONNULL SETproperty GETproperty GETblobdata PUTblobdata BLOBSIZE SETblobproperty GETblobproperty BUFFER SETviewfields CLEARfile RESETviewfile BUILDevent SETkeyproperty GETkeyproperty DOproperty DOkeyproperty DOblobproperty VIEWSTART VIEWSTOP GETNULLS SETNULLS GETSTATE RESTORESTATE CALLBACK FREESTATE DESTROY END EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE(75) EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE EQUATE(88) EQUATE EQUATE EQUATE(92) EQUATE EQUATE(96) EQUATE EQUATE EQUATE EQUATE EQUATE(102) EQUATE(104)
53
54
! Data Type Equates for use with file{PROP:SupportsType, DataType:n} ITEMIZE(1),PRE(DataType) BYTE EQUATE SHORT EQUATE USHORT EQUATE DATE EQUATE TIME EQUATE LONG EQUATE ULONG EQUATE SREAL EQUATE REAL EQUATE DECIMAL EQUATE PDECIMAL EQUATE BFLOAT4 EQUATE(13) BFLOAT8 EQUATE STRING EQUATE(18) CSTRING EQUATE PSTRING EQUATE MEMO EQUATE BLOB EQUATE(27) END ! These equates are to be used as the first parameter to the DELETEREG, ! GETREG and PUTREG statements REG_CLASSES_ROOT REG_CURRENT_USER REG_LOCAL_MACHINE REG_USERS REG_PERFORMANCE_DATA REG_CURRENT_CONFIG REG_DYN_DATA REG_NONE REG_SZ REG_EXPAND_SZ EQUATE(80000000h) EQUATE(80000001h) EQUATE(80000002h) EQUATE(80000003h) EQUATE(80000004h) EQUATE(80000005h) EQUATE(80000006h) EQUATE(0) EQUATE(1) EQUATE(2) ! ! ! ! No value type Unicode nul terminated string Unicode nul terminated string (with environment variable
references) REG_BINARY EQUATE(3) ! Free form binary REG_DWORD EQUATE(4) ! 32-bit number REG_DWORD_LITTLE_ENDIAN EQUATE(4) ! 32-bit number (same as REG_DWORD) REG_DWORD_BIG_ENDIAN EQUATE(5) ! 32-bit number REG_LINK EQUATE(6) ! Symbolic Link (unicode) REG_MULTI_SZ EQUATE(7) ! Multiple Unicode strings REG_RESOURCE_LIST EQUATE(8) ! Resource list in the resource map REG_FULL_RESOURCE_DESCRIPTOR EQUATE(9) ! Resource list in the hardware description REG_RESOURCE_REQUIREMENTS_LIST EQUATE(10) REG_QWORD EQUATE(11) ! 64-bit number REG_QWORD_LITTLE_ENDIAN EQUATE(11) ! 64-bit number (same as REG_QWORD)
Reference
55
56
ScrollSort:Alpha
ScrollSort:Name
SortRequest:SelectSort EQUATE(1) SortRequest:Reset EQUATE(2) SortRequest:LocateRecord EQUATE(3) SortResult:Changed SortResult:OK LocateOnPosition LocateOnValue LocateOnEdit EQUATE(1) EQUATE(2) EQUATE(1) EQUATE(2) EQUATE(3)
RefreshOnPosition EQUATE(1) RefreshOnQueue EQUATE(2) RefreshOnTop EQUATE(3) RefreshOnBottom EQUATE(4) RefreshOnCurrent EQUATE(5) EVENT:Preview:Print EQUATE EVENT:Preview:Cancel EQUATE EVENT:Preview:Zoom EQUATE EVENT:Preview:NextPage EQUATE EVENT:Preview:PrevPage EQUATE EVENT:Preview:Jump EQUATE EVENT:Preview:ChangeDisplay EQUATE EVENT:Preview:DisableNext EQUATE EVENT:Preview:EnableNext EQUATE EVENT:Preview:DisablePrev EQUATE EVENT:Preview:EnablePrev EQUATE EVENT:Preview:DirectZoom EQUATE EVENT:Preview:DirectUnzoom EQUATE
(401H) (402H) (403H) (404H) (405H) (406h) (407H) (450h) (451h) (452h) (453h) (454h) (455h)
Reference
Preview:OutOfPagesText Preview:OutOfPagesHead Preview:DisplayText Preview:DisplayIcons Preview:DisplayAll EQUATE ('There are no more pages to display') EQUATE ('End of Report') EQUATE (1) EQUATE (2) EQUATE (3)
57
58
59
60
Language Components
Keywords start with a pound sign ( # ). In the example, each keyword begins on a new line for readability. This is not required. Comments start with a double hyphen ( -- ) and are terminated by a Carriage Return or Line Feed. Macros are surrounded by percent signs ( % ). You may want to think of macros as variablesa value is substituted whenever the project system encounters a macro name surrounded by percent signs ( % ). See Project System Macros. Keyword Parameters are everything else you see in the example. Parameters and their syntax are discussed with each keyword. The Project System recognizes the following keywords:
#abort #and #autocompile #compile #declare_compiler #dolink #else #elsif #endif #error #exemod #exists #expand #file #if #ignore #implib #include #link #message #model #noedit #not #older #or #pragma #prompt #run #rundll #set #split #system #then #to
#noedit
The #noedit command can be placed at the top of a project file to prevent menu-editing from the SoftVelocity environment. It has no effect in the Clarion environment.
61
--Hello associated with mymac --#message %mymac substituted for -- and Hello substituted for %mymac
--World associated with mymac --#message %mymac substituted for -- and World substituted for %mymac
If a single % had been specified in the first #set command, the macro %mymac would have been expanded (to the empty string) before defining the replacement text for the macro %echo. The double % results in the project system executing:
#message Hello #message World
62
#expand <file-name>
The filename is subjected to redirection analysis, and the following macros are defined: %cpath %opath %ext %tail %cdir %odir Is set to the fully expanded filename where the file would be created. Is set to the fully expanded filename where the file would be opened. Is set to the extension of the filename. Is set to the filename, less extension, drive and path. Is set to the directory where the file would be created. Is set to the directory where the file would be opened for read (if the file does not exist %opath is set the same as %cpath).
Project System Reference For example, suppose the redirection file has the line,
*.def : . ; c:\ts\include
63
and the file c:\ts\include\io.def exists, and the current directory is d:\test then,
#expand io.def
is equivalent to,
#set opath = d:\test\io.def #set cpath = c:\ts\include\io.def #set ext #set tail #set odir #set cdir = .def = io = d:\test\ = c:\ts\include\
#split <filename>
The filename is split into its base and extension. The following macros are defined: %ext %name1 For example:
#split d:\name.exe
Is set to the extension of the filename. Is set to the filename, less extension.
is equivalent to,
#set ext #set name = exe = d:\name
64
%compile_src In compile mode, this is set to the name of the file to be compiled, with path and extension where available. Otherwise, it is set to the empty string. %cpath %devsys %editfile %editwin %errors %ext %filetype %jpicall %L %link %link_arg %main Set by the #expand command. Set by the Clarion environment to win. Set to the name of the file being edited in the topmost window. If no window is open, or in batch mode, it is set to the empty string. Set to the window number (0-9) of the topmost window. If no window is open, or in batch mode, it is set to the empty string. Count of errors produced by preceding compile or #file adderrors command. Set by the #split and #expand commands. Set by the #system command to its second argument, and examined by the #link command. Set by the #model command to its second argument, and examined by the #link command. Set by the #model command to either (standalone) L (local) or ! (own). The #link command uses this to derive the name of any required library files. Set to the current link list. Set to its argument by the #link command. Set to the assumed name of the main source file. In make or link mode when not using UNNAMED.PR, this is derived from the project filename, with path and extension removed. Otherwise, it is the supplied source filename complete with path and extension if specified. Set to on or off by the #compile, #link and #dolink commands, to indicate whether the target file was up to date.
%make
%manual_export Set this macro on to indicate that the #link command should not construct a .LIB file when a DLL is linked. If this macro is not specified, a .LIB file is created automatically from the corresponding .EXP file if found (see Module Definition File below), or from the object files in the link list. %model %name Set by the #model command to its first argument, and examined by the #link command. Set by the #split command.
Project System Reference %obj %odir %opath Set to the object filename in a #compile command. Set by the #expand command. Set by the #expand command.
65
%pragmastring Will always expand to the current state of the #pragma settings - this is useful for debugging. %prjname Set to the assumed name of the project - this is usually derived from the project filename, but with the path and extension removed. Where UNNAMED.PR is being used, it is derived from main source filename without source and extension. Used within declare_compiler macros to determine whether source/object dependencies require a remake.
%remake
%remake_jpi Used within declare_compiler macros to determine whether source/object dependencies require a remake. %remake_jpi should be used for object files created by SoftVelocity compilers, which contain additional information. %reply %S Set by the #prompt command. Set by the #system command to 32 indicating the instruction set being used to build the project. The #link command uses this to derive the name of any required library files. Set to the source filename in a #compile command. Set by the #system command to its first argument, and examined by the #model and #link commands. Set by the #expand command. Set to on if a C or C++ source file is compiled. Set to on if a C++ source file is compiled. Set to on if a Modula-2 source file is compiled. Set to on if a Pascal source file is compiled.
The above macros are examined by the #link command to determine which libraries to include, and then set to off. %warnings Count of warnings produced by preceding compile or #file adderrors command.
66
#system
#system operating_system [ target_type ] The #system command is used to specify the target operating system and file type. The macros %system and %filetype are set to the first and second arguments. See Special Project System Macros below. The first argument specifies the target operating system, and may be win or win32. The second argument indicates the target file type, and may be exe, lib, or dll. If omitted, exe is assumed. The #system command affects the behavior of subsequent #model and #link commands. Therefore a #system command must be specified before either of these. If more than one #system command occurs in a project, each must be followed by a #model command in order to take effect.
#model
#model memory_model [ linking_convention ] The #model command is used to specify the memory model to be used for subsequent compiles and links. This memory model will continue to be used until modified by explicit #pragmas, or by another #model command. The #model command sets the macros %model and %jpicall to its first and second parameters respectively. For example,
#model clarion dll
is equivalent to
#set %model = clarion #set %jpicall = dll
The first argument specifies the memory model, which is always clarion for Clarion projects. The second indicates the linking convention, which may be dll, lib, or owndll. If omitted, dll is assumed.
Project System Reference Setting the second argument to dll indicates that you will be creating an exe or dll that calls the standard Clarion dlls. Setting the second parameter to lib indicates that you will be creating an exe, lib or dll that includes all the components of the Standard Clarion libraries (and file drivers) in the exe, lib or dll. Using owndll indicates that you are linking to a dll that was previously created with the lib link convention, so the standard Clarion dlls are not linked. The #system command must be specified before the first #model command.
67
#pragma
#pragma <#pragma> { , <#pragma> } The #pragma command modifies the state of the #pragma options which affect the behavior of the SoftVelocity compilers or linker. The syntax and meaning of all #pragmas are discussed under the SoftVelocity #pragmas section below. The special macro %pragmastring expands to the current state of all #pragma options which are not in their default state - this can be useful for determining exactly which options are being used for a given compile. For example:
#message %pragmastring
68
#compile
#compile<source> [ #to <object> ] [ / <#pragma> { , <#pragma> } ] { , <source> [ #to <object> ] [ / <#pragma> { , <#pragma> } ] } The #compile command causes each nominated source file to be compiled (if necessary). The name of the object file may be specified using #to. If this is omitted, the name is derived from the source filename, with the extension .obj. Any #pragmas specified in a #compile command apply only to the single source filename that precedes the / character. The macro %make is set to on if a compile is necessary, off otherwise. The macros %src and %obj are set to the names of the source and object filenames. Each object file is added to the link list, i.e. there is an implicit:
#pragma link( %obj )
For example:
#compile fred.c #to fred.obj #compile george.cpp /debug(vid=>full)
It is possible to reconfigure the behavior of the Project System when compiling source files of a given extension using the #declare_compiler command. This may also be used to declare actions to perform for different file extensions - for example, to support third-party compilers or preprocessors. See Other Commands below.
#link
#link <target_filename> The #link command links together (if necessary) all the files in the link list to the nominated executable or library file. The file type is determined by the extension of the nominated target file, or, if there is no extension, by the file type specified in the most recent #system command. If neither are specified, the default is to produce an executable file. The effect of #link is to set the macro %link_arg to the specified filename. The Project System maintains a list of those files that are to be used as input to the linker the next time an executable or library file is created. This list is known as the link list. A filename may be added to the link list using the #pragma link command.
69
However, it is seldom necessary to use #pragma link explicitly, as all the SoftVelocity compilers add the resulting object file to the link list whenever a source file is compiled using #compile. In addition, when the #link command is encountered, all required standard library files, and other object files which are imported by those already on the link list are also added to the list. The link list is cleared after each link. The #link command differs from the similar #dolink command in that (so far as the Project System can determine), any additional object files required are automatically added to the link list before linking. This includes any SoftVelocity library files, and also (with an implicit #autocompile command) all modules imported with IMPORT clauses in SoftVelocity Modula-2 or with #pragma link statements in SoftVelocity C or SoftVelocity C++ source files. In addition, #link will determine from the target file type any additional processing that needs to be applied to the output file. For certain specialized requirements, the use of #link may be inappropriatefor example, if a specialized startup file is required, or when building library files, where explicit control of exactly which files are included may be preferred. In such cases, the #dolink command should be used. #dolink <target_filename> The #dolink command takes the object files which have previously been added to the link list, and combines them into an executable or library file (depending on the extension of the nominated target file), if required to keep the target file up to date. No additional files are added to the link list, so all required files must have been specified previously, by means of #pragma link, #pragma linkfirst, #compile, and #autocompile. For simple projects, the use of #link is preferable because the link list is dynamically maintained by the project system, freeing the developer from this responsibility. When finished, the #dolink command clears the link list. See also: #pragma link_options (link)
#autocompile
The #autocompile command examines the object files which are currently in the link list, to see which objects they need to be linked with. This would include objects specified using a #pragma link in a SoftVelocity C or C++ source file, or in the case of module based languages such as SoftVelocity Modula-2 imported modules. Each resulting object file, which is not already in the link list, is then compiled (if necessary) and added to the link list. If there is more than one possible source for a given object file, an error is reported. This process is repeated until the link list stops changing. It is not necessary to use #autocompile for simple projects where #link is used rather than #dolink, as #link performs an implicit #autocompile.
70
#ignore
#ignore <filename> #ignore #pragmastring There are two forms of the #ignore command. The first, where a filename is specified, tells the Project System to ignore the date of the nominated file when deciding whether or not to compile. This is useful when a safe change is made to a widely used header file, to prevent mass recompile. The special form #ignore #pragmastring directs the Project System to ignore the #pragma settings when deciding whether or not to compile a file. This may be useful, for example, when a new compile-time macro has been defined, but there is no need to recompile everything.
#implib
#implib <libfilename> The #implib command is used to create (if necessary) a dynamic link library file. There are two forms of this command, which operate in slightly different ways. If a single filename is specified, this names an import library file, which is created (if not up-to-date) from the object files in the link list. The object files are scanned and each public procedure or variable is exported. For example:
#pragma link( fred.obj, joe.obj ) #implib mylib.lib
In the second form of the #implib command, an import library filename and a module definition file (.expsee Module Definition File below) are both specified, and the library file is created (if not up-to-date) from the symbols named in the definition file. This form of the command is equivalent to using the tsimplib utility that comes with SoftVelocity C, C++, and Modula-2. #implib <expfilename> <libfilename> Using #implib in the second form requires you to create and maintain the list of exports by hand, whereas the first form exports all public names automatically. The use of a module definition file is an advantage if you need to maintain compatibility with previous versions of an interface, and it also allows you to export only the procedures which need to be exported. When #implib is used with a module definition file, the link list is cleared.
71
#if
The syntax of the #if command is as follows :
#if <boolean-expression> #then commands #elsif <boolean-expression> #then commands #else commands #endif
The #elsif part may be omitted, or may be repeated any number of times. The #else part may be omitted. The expressions are evaluated in order, until one of them yields true, then the following command sequence is executed. If none of the expressions yield true, and the #else part is present, then the commands following #else are executed. All other commands are ignored. The syntax and semantics of boolean expressions are described under Boolean Expressions below.
#error
#error <string> This command terminates the current project. Under the Clarion environment, the Text Editor is opened at the position of the #error command, and displays the supplied string as the error message. For example:
#if "%name"="" #then #error "name not set up" #endif
72
#abort
#abort [ on | off ] This command is used to control whether a failed #compile or #run command will terminate a project. If abort mode is on, a project will be aborted as soon as a #compile fails, or a #run command produces a non-zero return-code. If abort mode is off, a project will only be aborted if an internal command fails, including a #link, #implib or #exemod command. #abort on will set abort mode to on, while #abort off will turn it off. #abort without one of the above arguments will abort the current project immediately. The default abort mode is on when running under the Clarion environment.
73
User Interface
The following commands allow you to collect information and provide feedback during the make process.
#message
#message <string> This command displays the specified string in the make display window. This can be used to indicate progress through the project file, or to display status messages. For example:
#message "finished making %prjname"
#prompt
#prompt <promptstring> [ <defaultstring> ] This command prompts you to enter a string, by displaying the <promptstring> and waiting for a keyboard entry. The string you enter is returned as the value of the macro %reply. If <defaultstring> is specified, and no keyboard entry is made, the <defaultstring> will be used as the value returned to %reply. For example:
#prompt "Command line: " %cline #set cline = %reply
Boolean Expressions
Boolean expressions used in #if and #elsif commands are made up from the following boolean operators (listed in order of precedence):
#or #and #not = #exists #older ( )
#or
boolean-expression = <factor> { #or <factor> } A boolean expression containing one or more #or operators yields true if the evaluation of any of the factors yields true.
74
#and
<factor> = <term> { #and <term> } A factor containing one or more #and operators yields false if the evaluation of any of the terms yields false.
#not
<term> = #not <term> A term proceeded by the #not operator yields true if the evaluation of the term yields false, and vice versa.
= (comparison)
<term> = string = string A term containing a comparison operator yields true if the strings are identical, otherwise false. == may be used instead of =. The = operator and second string may be omitted, in which case the first string is compared against the string "on". That is,
DemoSwitch =
is equivalent to
DemoSwitch = "on"
The first string may be replaced by an expression of the form name1(name2), where name2 names a #pragma of class name1. In this case, the expression is replaced by the current setting of the specified #pragma, before the comparison is made.
#exists
<term> = #exists <file-name> A term containing the #exists operator yields true if the file exists (after applying redirection to the filename), otherwise false.
#older
<term> = <file-name> #older <file-name> { , <file-name> } A term containing the #older operator yields true if the first file specified is older than at least one of the other files specified, otherwise false. Redirection is applied to all filenames (See The Redirection File below). This operator is often useful to determine whether a post/preprocessing action needs to be performed. For example:
#if mydll.lib #older mydll.exp #then ...
75
#file Commands
The following file system commands are available:
#file adderrors #file append #file copy #file delete #file move #file redirect #file touch
76
To capture errors from a program with a different error format, a filter program can be used to translate them. For example:
#run masm %f; > %f.err #file adderrors %f.err #run myprog %f; | myfilter > %f.err #file adderrors %f.err
If any errors are detected, and abort mode is on, the project will terminate and the errors will be reported in the make status window. The macros %errors and %warnings are set to the number of errors and warnings detected.
77
Filenames within the command string (with the exception of the executable filename itself) are not automatically subject to redirection - #expand may be used before using #run if this is required.
#include <file-name>
A copy of the contents of the nominated file is inserted in the input stream. <filename> should specify a fully qualified filename, or an unqualified filename, in which case redirection analysis is applied (see The Redirection File above). The current values of the link list, #pragma settings, and macros are fully available to the #include statements. In other words, the #include statements are handled as though they resided within the including .prj file.
#call <file-name>
A copy of the contents of the nominated file is inserted in the input stream. <filename> should specify a fully qualified filename, or an unqualified filename, in which case redirection analysis is applied (see The Redirection File above). The current values of the link list, #pragma settings, and macros are not available to the #call statements, and the #call statements cannot modify these values in the calling environment. In other words, #call statements are handled as a process that is completely separate from the calling process.
78
#declare_compiler asm= #set make=%%remake #if %%make #then #edit save %%src #expand %%src #set _masmsrc=%%opath #expand %%obj #set _masmobj=%%cpath
#run "masm %%_masmsrc,%%_masmobj/MX/e; >masmtmp.$$$" #file adderrors masmtmp.$$$ #file delete masmtmp.$$$ #endif #pragma link(%%obj)
#exemod
#exemod <file-name> <file-name> <file-name> This command is the equivalent of using the tsexemod utility that comes with SoftVelocity C, C++, and Modula-2. #exemod is required to make advanced overlay model programs, Windows programs and DOS DLLs. However, it is not necessary to use this command explicitly when making Windows programs. TSEXEMOD is used to modify the header and segment information in a new format executable file (.EXE or .DLL), using the information in a module definition (.EXP) file. For example:
TSEXEMOD binfile.* expfile.exp mapfile.map
79
SoftVelocity #pragmas
All SoftVelocity languages, and the Project System, use a common set of compiler options known as #pragmas. In general, pragmas may appear in the source code or in a project file, and the effect will be the same. A pragma can be used in the Project language, C++ code, or Modula-2 code. Some only work in certain places. A P to the right of the pragma indicates it can be used in the Project language, a C indicates it can be used in C++ code and a M indicates it can be used in Modula-2 code.
$B (Ctrl-Break handler). This is no longer supported. Use Lib.EnableBreakCheck instead. $D (data segment name). This is supported, but adds the suffix _BSS (for uninitialized data) or _DATA (for initialized data) to the name instead of the D_ prefix. $J (use IRET instead of RET). This is not supported. Instead, you should use the pragma:
(*# call( interrupt => on ) *)
However, you may find that you have to make other changes as well as the effect of the pragma is different from the $J directive: $K (C calling convention). This is not supported. Instead, you should use the pragma:
(*# call( c_conv => on ) *)
$M (code segment name). This is supported but adds the suffix _TEXT to the name instead of the C_ prefix. $P (external names for local procedures). This is no longer supported. It is no longer applicable.
80
Advanced Topics & Reference Guide $Q (procedure tracing). This is no longer supported. Instead, you should use the pragma:
(*# debug( proc_trace => on ) *)
This enables a different method of tracing procedures. Refer to the proc_trace pragma for further details. $X (80x87 stack spilling). This is no longer supported (and is no longer necessary). $Z (NIL pointer checks). This still does NIL pointer checks but no longer clears memory. $@ (preserve DS). This is no longer supported.
The support for these directives has been included with later systems so that your old programs and modules will recompile with minimum changes. However, you should avoid using the old directives with new programs, and use pragmas instead.
Pragmas in the Project System may also be specified in the #compile command, to apply to a single compilation. For example:
#compile mandel.mod /debug(vid=>on)
Pragma Classes
A #pragma takes the form #pragma class(name=>value). The #pragma classes are as follows:
Call #pragmas Check #pragmas Data #pragmas Debug #pragmas Define #pragmas Expr #pragmas Link and Linkfirst #pragmas Link_option #pragmas Module #pragmas Name #pragmas Optimize #pragmas Option #pragmas
81
Call #pragmas
#pragmas with the class name call affect all aspects of calling conventions, code segments, and code pointers. The current settings of the call #pragmas at the point at which a procedures definition is encountered, determines the calling convention that is used to call the procedure. SoftVelocity compilers detect if an inconsistent calling convention is used when a procedure is called. The type-safe linker reports an error if the calling conventions attributed to a given procedure do not match in every object file. The following call #pragmas are available:
#pragma call(c_conv => on | off) #pragma call(ds_entry => identifier) #pragma call(ds_eq_ss => on | off) #pragma call(inline => on | off) #pragma call(inline_max => Number) #pragma call(near_call => on | off) #pragma call(o_a_copy => on | off) #pragma call(o_a_size => on | off) #pragma call(opt_var_arg => on | off) #pragma call(reg_param => RegList) #pragma call(reg_return => RegList) #pragma call(reg_saved => RegList) #pragma call(result_optional => on | off) #pragma call(same_ds => on | off) #pragma call(seg_name => identifier) #pragma call(set_jmp => on | off) #pragma call(standard_conv => on | off) #pragma call(var_arg => on | off)
cpm
Specifies whether procedure calls are near or far. When on, the compiler calls procedures with near calls. The compiler can only use near calls if the calling and called procedures are in the same segment. The compiler checks that this is the case. The default value is off. This example forces near calls:
#pragma call(near_call=>on)
82
cpm
Specifies whether to load the data segment (DS) register on entry to a procedure. When on, DS will not be loaded as part of the procedure prolog. This will only be correct when the DS setting of the calling procedure matches that of the called procedure. The compiler checks that this is the case. This option is off by default. For example:
#pragma call(same_ds => on)
cpm
When on, this option enables the Microsoft C calling convention. In this convention, the compiler pushes procedure parameters in right to left order on the stack and the caller pops these parameters off the stack. This is not the default, so you should only use this #pragma when interfacing to Microsoft C code. For example:
#pragma call(c_conv=>on)
You can also use the cdecl keyword in C and C++ to achieve the same effect. See also the standard_conv #pragma, which has the same effect for C and C++, but is ignored for Modula-2. The standard_conv #pragma is set off by default.
cm
If this #pragma is set on before a procedure definition, the compiler makes a copy of the procedure in the code rather than using a call instruction. The default value is off. You can use this convention for any procedure, but this #pragma is mainly used together with the reg_param #pragma for simple machine-code procedures. For example:
#pragma save #pragma call(inline => on, reg_param => (dx,ax)) static void outp(int port, unsigned char byt)= { 0xEE, /* out dx,al */ }; #pragma restore
makes outp an inline procedure, so a call to it appears as a single 80x86 machine instruction: out dx,al.
cpm
Project System Reference Specifies the code segment name. call(seg_name => nnn) means that the compiler places the code for the procedure in segment nnn_TEXT. The default value depends on the memory model. In the small and compact models, the default is null; in the other models it is the name of the source file. For example, a code segment named _TEXT would be specified as:
#pragma call(seg_name => null)
83
The default setting is language dependant, and is not defined by the Project System.
cpm
This #pragma indicates a segment name which the DS register will point to throughout the execution of a procedure. If the identifier is null, the compiler names the segment _DATA. If the identifier is none, the compiler does not assume a fixed DS during procedure execution and uses DS as a general purpose segment register like ES.
#pragma call(ds_entry => MYDATA)
This example indicates that on entry to the procedure, DS will point to the segment named MYDATA_DGROUP.
cm
SoftVelocity languages pass procedure parameters in machine registers rather than using the stack. This generates smaller and faster code. This #pragma allows you to fine-tune individual procedure calls for maximum speed. Other vendors languages use a less efficient calling convention; you must, therefore, disable this calling convention when interfacing to precompiled objects written for these compilers (see the Advanced Programmers Guide that comes with SoftVelocity C, C++, and Modula-2, Chapter 5: Multi-language Programming). This #pragma has no effect on structure parameters, which are always passed on the stack. The argument for reg_param is a register list, specifying which registers should be used. Registers for parameters are allocated left to right from the list. The table shows how the compiler allocates registers dependent on parameter types:
1 byte 2 bytes 4 bytes floating point ax, bx, cx, dx ax, bx, cx, dx, si, di ax, bx, cx, dx, si, di for low word. ax, bx, cx, dx, si, di, es, ds for high word. st0, st1, st2, st3, st4, st5, st6
Note that the es and ds registers will only be used for the high word of a 4-byte parameter where that parameter is of pointer type. If either the low or high word cannot be allocated, then the whole parameter is passed on the stack. When the compiler exhausts the list of registers, it passes the parameter on the stack. If you specify an empty list, the compiler uses the stack for all parameters.
84
cm
This #pragma specifies which registers a procedure preserves. The argument RegList is a list that specifies the set of registers. The default set for the SoftVelocity calling convention is:
ccall(reg_saved=>(ax,bx,cx,dx,si,di,ds,st1,st2))
When on, this option passes the size of open array parameters on the stack: This #pragma has no effect for value parameter open arrays, unless the o_a_copy #pragma is set off. The default setting is on.
When on, open array parameters are copied onto the stack as part of the procedure prolog. If off, only a reference to the array is passed. Note that the open array parameters size must be passed in order for a copy to be made - see #pragma call(o_a_size). The default setting is on.
It controls whether VAR parameters use 16- or 32-bit pointers. The default setting is on for small and medium models, otherwise off.
85
When on, it implies that the following procedures take a variable number of arguments. This effectively disables the "too many arguments" error that the compiler would normally detect. The consequence however, is that the compiler cannot carry out any type checking on the arguments. This #pragma should be used when calling C procedures (such as printf) where the number of arguments varies:
(*# call(var_arg => on, reg_param=>(), c_conv=>on ) *)
cm
This #pragma is used to specify the registers to be used for return values of integer, pointer and floating point types. For example:
#pragma call(reg_return => (bx,cx))
It can be used to call a procedure as a proper procedure without generating a compiler error. For example:
(*# save *) (*# module( result_optional => on ) *) PROCEDURE FuncProc(x: CHAR): CARDINAL; (*# restore *)
This is only useful when the called procedure has a side effect that is more important than the result. It is particularly useful when calling SoftVelocity C library procedures. The default setting is off.
86
cm
This #pragma should only be used for the library routines which implement non-local jumps. The effect is to inform the compiler of the non-standard register saving properties of these routines.
cpm
This #pragma controls the largest procedure which is inlined. The default setting is 12, which corresponds to the minimum code size for most programs. A larger value increases the code size and may accelerate code execution. The #pragma takes effect for each call, so a procedure may be called in different ways at different places.
Procedures are not inlined if the body has not been compiled before the call.
The effect on C and C++ programs is the same as the call(c_conv) #pragma. For Modula-2 there is no effect. The default is off.
cp
This #pragma controls whether optimized entry sequences are generated for procedures with variable parameter lists. The default is on.
Data #pragmas
#pragmas with the class name data affect data segmentation, data pointers and all aspects of data layout. The current settings of the data #pragmas at the point of a variables declaration will affect the way in which it is accessed. The following data #pragmas are available:
#pragma data(c_far_ext => on | off) #pragma data(class_hierarchy => on | off ) #pragma data(compatible_class => on | off) #pragma data(const_assign => on | off ) #pragma data(const_in_code => on | off) #pragma data(cpp_compatible_class => on | off )
87
cpm
The #pragma data(seg_3name=>xxx) specifies that the compiler should place global initialized data objects in a segment named xxx_DATA, and global uninitialized data objects in a segment named xxx_BSS. These both have group name xxx and are in the FAR_DATA class. If the size of a data object is larger than the global data threshold, the compiler places the object in a separate segment. The following example makes the names of the default segments: MYDATA_DATA and MYDATA_BSS. These segments are in group MYDATA and have class FAR_DATA:
#pragma data(seg_name => MYDATA)
You can also specify null, to indicate the names _BSS and _DATA. The default value is null in all models except for extra large and multi-thread. For example:
#pragma data(seg_name => null)
cp
When on, the code generator does not assume that external variables are in the segment specified by the segment #pragma. The #pragma defaults to on. For example:
#pragma(seg_name=>MYDATA, far_ext=>off)
makes the name of the default segments MYDATA_DATA and MYDATA_BSS in group MYDATA. The compiler assumes external data objects to be in the same segment.
88
pm
When on, the code generator does not assume that external variables are in the segment specified by the seg_name #pragma. The #pragma defaults to off in all memory models. For example:
(*# data(seg_name => MYDATA, c_far_ext => off ) *)
makes the name of the default segments MYDATA_DATA and MYDATA_BSS in group MYDATA. This #pragma is not particularly useful in Modula-2 except for interfacing to C.
cm
Specifies whether data pointers are near or far. This #pragma also affects pointers generated by the & operator and by implicit array to pointer conversions in C and C++. For example:
#pragma data(near_ptr => on)
Variables declared when this #pragma is set to on are considered to be volatile, and will always be kept in memory, rather than being kept in registers across statements. The default setting is off. This #pragma is not allowed in a project file, and is not available for C and C++, where the volatile keyword should be used.
The effect is as for #pragma data(volatile), but applies to variables of variant record types only. The default setting is off.
pm
Normally SoftVelocity does not allow two fields in different alternatives of a variant record to have the same name. Using this #pragma:
(*# data( ext_record => on) *)
will allow you to use the same name in different alternatives, if the fields are located at the same offset in the variant record and they have the same data type. The default setting is off.
89
pm
Enumeration constants with less than 256 alternative values are normally stored in one byte. Switching this option off:
(*# data( var_enum_size => off) *)
will force the compiler to store them as two-byte quantities. This is particularly useful for interfacing to third-party libraries and operating system calls that expect a word value. Without this #pragma the enumeration would be byte rather than word size. The default setting is on.
cm
Specifies the size of the stack. You must place this #pragma in the file containing the main procedure (the main module in Modula-2). If the stack size cannot be set to the specified size, the compiler uses the largest possible size. The default size is 16K bytes. For example:
#pragma data(stack_size => 0x6000) main() { /* statements */ }
pm
This #pragma controls whether record fields are packed at bit level. The default setting is off.
This #pragma controls whether constants are put in to a code or data segment. The default setting is on.
pm
This #pragma controls whether information about class hierarchies is included in the class descriptor (method table). The information is used by the IS operator and TypeGuards with check on. The default setting is on.
pm
This #pragma controls whether the compiler includes extra information in class descriptors to provide compatibility with C. The default setting is off.
90
cp
This #pragma controls whether the compiler includes the correct information in class descriptors to provide compatibility with Modula-2. The default setting is off.
cpm
This #pragma sets the global data threshold. This determines at what size a data object is placed in a segment of its own. The default setting is 10000 bytes.
pm
This #pragma controls whether it is possible to assign to a structured constant. The default setting is off.
Check #pragmas
#pragmas with the class name check control run-time error checking. These can help you to locate erroneous program logic, but at the expense of slower execution. All these #pragmas default to off. When a run-time check detects an error, the default action is to terminate the process and create the file CWLOG.TXT. The following check #pragmas are available:
#pragma check(guard => on | off) #pragma check(index => on | off) #pragma check(nil_ptr => on | off) #pragma check(overflow => on | off) #pragma check(range => on | off) #pragma check(stack => on | off)
cpm
When on, the run-time system checks that your program does not run out of stack space. You can increase the size of the stack using the data(stack_size) #pragma.
91
cpm
When on, the run-time system checks for any dereference of NULL or NIL pointers.
pm
When on, a range check is performed whenever a value is assigned to a variable of subrange or enumerated type. In addition, compile-time values are checked to ensure that they are in the range of their type.
pm
When on, the run-time system checks that numeric values do not go out of range.
cpm
When on, the run-time system checks for the use of an array index larger than the array size.
pm
This #pragma controls whether checks are performed on the checked-guard operator.
92
Name #pragmas
#pragmas with the class name control aspects of linkage naming. However, the C programmer should also be familiar with C name mangling and extern declarations. The following name #pragmas are available:
#pragma name(prefix => (none | modula | c | os2_lib | windows)) #pragma name(prefix => string) #pragma name(upper_case => on | off)
cp
This #pragma is available in C and C++ Only. It specifies whether public names should be converted to upper case. You would use this when interfacing to Pascal, or to third party C libraries. The default setting is off.
#pragma name(prefix)
There are two forms of this #pragma: In Modula-2: In C and C++:
cpm
mp
This #pragma is available under Modula-2 (under C and C++ the syntax is slightly different see #pragma name(prefix => string). The name(prefix) #pragma specifies the prefix and case of the public names that the compiler uses. The public names are names for non-static procedures and external data objects. By default, SoftVelocity Modula-2 prefixes all external names with the name of the module followed by an @ for data and a $ for procedures. You will need to use this #pragma to interface to SoftVelocity C. The prefix #pragma specifies which prefix scheme to use: Modula Use the SoftVelocity Modula-2 naming convention of prefixing all external names with the name of the module and an @ or a $. Puts no prefix on external names. Use the C naming convention (adds an underbar, _ to all external names). Use the OS/2 library standard (prefix all external names with the module name). Use the Microsoft Windows external naming convention.
93
cp
This #pragma is available under C and C++ Only. Under Modula-2 the syntax is slightly different - see #pragma name(prefix => (none | modula | c | os2_lib | windows)). The value is a string specifying the prefix to all public names. An empty string specifies no prefix. The default prefix is an underbar. If you wish to interface to SoftVelocity Modula-2, you can use this #pragma to specify the module prefix with a dollar ($) suffix. For example, to use the WrStr procedure from module IO:
#pragma name(prefix => "IO$") void WrCard(unsigned);
In C, a Pascal or Modula2 linkage specification can specify a module name within the linkage specification, in which case the use of this #pragma is not necessary. The default setting is language-dependent. The Project System does not set a default value for this macro.
94
Optimize #pragmas
#pragmas with the class name optimize control optimizations performed by the SoftVelocity code generator. By default, all optimizations are enabled. Turning off an optimization will result in poorer code quality, and is unlikely to have a significant impact on compile times. The following optimize #pragmas are available:
#pragma optimize(alias => on | off) #pragma optimize(const => on | off) #pragma optimize(cpu => 86 | 286 | 386 | 486) #pragma optimize(cse => on | off) #pragma optimize(jump => on | off) #pragma optimize(loop => on | off) #pragma optimize(peep_hole => on | off) #pragma optimize(regass => on | off) #pragma optimize(speed => on | off) #pragma optimize(stk_frame => on | off)
cpm
When on, the compiler minimizes evaluation of complete expressions by keeping partial results in a temporary register. The default setting is on.
cpm
When on, the compiler will hold frequently used constants in registers to produce faster code. The default setting is on.
cpm
When on, SoftVelocity tries to make the code run as fast as possible without regard for the code size. When off, SoftVelocity tries to make the code as small as possible. A good example of the difference between optimizing for speed and optimizing for space is the use of a for loop. When optimizing for speed, the compiler might use nop instructions to place jump labels inside the for loop on even boundaries. The 80x86 architecture makes this much quicker than odd boundaries, but each nop adds another byte to the code size. This means that when optimizing for space, the compiler eliminates the extra nop instructions. The default setting is on.
95
cpm
When on, the compiler will only make stack frames where required, thus eliminating the need to set up the BP register. This optimization can only be made when all parameters and local variables for a procedure can be held in machine registers. When off, the compiler always sets up the BP register, thus allowing a complete activation stack listing while debugging. The default setting is on.
cpm
When on, the compiler spends time finding the best allocation of registers for variables. This results in fast and tight code but slower compile. The default setting is on.
cpm
When on, the compiler performs a variety of machine-code translations, generating smaller and faster code. The default setting is on.
cpm
When on, the compiler will rearrange loops to eliminate as many jumps as possible, thus generating faster code. The default setting is on.
cpm
When on, the compiler uses the loop depth when eliminating common sub-expressions and performing jump optimizations. The result of this optimization is faster, but potentially larger, code. The default is on.
cpm
When on, this allows the compiler to assume that variables in a procedure will not also be used indirectly with a pointer in the same procedure. This assumption is not strictly allowed in ANSI C but is correct for all meaningful programs. The default setting is on.
cpm
This controls the instructions used by the code generator, by declaring the processor to be used. The default is cpu=>286. This is normally set on the Project Systems Optimize tab.
96
Debug #pragmas
#pragmas with the class name debug control the amount of additional information produced by the code-generator to assist debugging programs. The following debug #pragmas are available.
#pragma debug(line_num => on | off) #pragma debug(proc_trace => on | off) #pragma debug(public => on | off) #pragma debug(vid => off | min | full)
cpm
When full, the compiler places information for the SoftVelocity Visual Interactive Debugger (VID) into a .DBD file. Use this option when debugging your program with the SoftVelocity debugger.
This #pragma disables the register usage and stack frame optimizations, allowing full access to variables within the debugger. All local variables are treated as volatile, to ensure that their values are not held in registers across statements, thus ensuring that the debugger can access their values at all times. When min, the compiler performs the optimizations described above, and does not treat local variables as volatile. The debugger can still be used, but cannot reference local variables and some stack frames. When off, the compiler generates no debugger information, thus speeding compile, generating the best possible code, and saving disk space. The default setting is off.
pm
When this #pragma is on, the compiler generates instructions to call the procedures EnterProc and ExitProc on, respectively, entering and exiting every procedure. These procedures can then perform any procedure tracing you may require.
You should ensure that this #pragma is off for the EnterProc and ExitProc procedures themselves, otherwise infinite recursion will occur and your program will undoubtedly crash. The two procedures must be visible to the module in which proc_trace is set on. This means that the module itself must define the procedures ExitProc and EnterProc or the module must specifically import them using an unqualified import. The default setting is off.
97
cpm
This #pragma causes the compiler to generate line number information for debuggers such as symdeb. This information is stored in object files and printed in the map file. The default setting is off.
cpm
This causes private objects to be made public to facilitate the use of debuggers such as symdeb. It may cause duplicated public warnings at link-time in languages such as C and C++ which do not have a modular structure. These warnings may be safely ignored, although it is recommended that such procedures should be renamed to avoid possible confusion. The default setting is off.
98
Module #pragmas
#pragmas with the class name module control options that apply to an entire source file or module. These #pragmas should be specified at the top of any source files to which they apply, or in the project file. The following module #pragmas are available:
#pragma module(implementation => on | off ) #pragma module(init_code => on | off ) #pragma module(init_prio => Number) #pragma module(smart_link => on | off)
pm
When on, it implies that the module contains initialization code to be run when the program is loaded and before the main module is executed. Switching the option off is useful for modules written in other languages, as it will stop the linker warning of undefined symbols:
(*# module( init_code => off ) *)
If an implementation module sets this #pragma off, then there is a knock-on effect, i.e., all imported modules must also have init_code set to off. The default setting is on.
pm
This #pragma specifies whether or not a definition file (.DEF or .ITF) has a corresponding object file. It should be turned off if the definition file defines interfaces to routines in a different language, to prevent the Project System from attempting to remake the corresponding object file. The default is on. This #pragma can also be used in the implementation part of a module, before any module source code. In this case it overrides the default naming of the associated object file. Normally the name of the .OBJ file corresponding to a module is taken from the module name. When this #pragma is set off, the object filename will be taken from the filename, not the module name.
99
cpm
Setting this #pragma to off disables the smart linking feature, to the extent that either all or none of the objects in each segment from a compile will be included in a link. This may result in quicker linking, and also may allow other linkers (such as Microsoft) to be used. (There are many potential problems with trying to use a non-SoftVelocity linker, and it is definitely not recommended). The default setting is on.
cp
This #pragma is available under C only. It defines a priority for the initialization code for static objects. Normally the initialization order is undefined between files, but this #pragma allows you to control the initialization order in that files with higher priority are initialized before modules with lower priority. The number must be a value between 0 and 32. The default value is 16, and the C library uses values between 25 and 32 (it is therefore not recommended to use values in this range, otherwise part of the library may not have initialized before user code is executed).
100
Option #pragmas
#pragmas with the class name option control language-dependent options, such as SoftVelocity extensions. The following option #pragmas are available:
#pragma option(ansi => on | off) #pragma option(bit_opr => on | off) #pragma option(incl_cmt => on | off) #pragma option(lang_ext => on | off) #pragma option(min_line => on | off) #pragma option(nest_cmt => on | off) #pragma option(pre_proc => on | off) #pragma option(uns_char => on | off)
cp
This #pragma is available under C and C++ Only. If it is set to on, ANSI keywords only are allowed. The default setting is off.
cp
This #pragma is available under C and C++ Only. The following constructs are not valid under ANSI C, but are included in SoftVelocity C and C++ when this #pragma is not set on: A type cast yields an lvalue if the operand is an lvalue. Procedures can be initialized with binary machine code. The relational operators (>,>=,<=,<) allow the operators to be a mixture of integer and pointer operands. Bitfields in C can have type char and unsigned char. Relative pointers.
101
cp
This #pragma is available under C and C++ Only. When on, you can nest comments without causing an error message. For example:
/* This is a test comment /* This is a nested comment */ */
When off, nested comments cause an error message. The default is off, allowing the compiler to trap unterminated comments more easily and make it conform with ANSI C.
cp
This #pragma is available under C and C++ Only. When on, types declared as char lie between 0 and 255. When off, values declared as char lie between -127 and 128. The default setting is off.
cp
This #pragma is available under C and C++ Only. When on, the compiler produces preprocessor output in a file with the same name but with extension .i. This output file makes it easy to debug the result of macro expansions. The default setting is off.
cp
This #pragma is available under C and C++ Only. When on, comments are preserved in preprocessor output. The default setting is off. This #pragma has no effect unless #pragma pre_proc is on.
cp
This #pragma is available under C and C++ Only. When on, the preprocessor minimizes the number of blank lines in output. The default setting is on. This #pragma has no effect unless #pragma pre_proc is on.
pm
This #pragma is available under Modula-2 only. It allows bitwise operations on cardinals: The default setting is off.
102
Warn #pragmas
#pragmas with the class name warn control the generation of compiler warnings. These #pragmas are only available under C and C++. The warnings given by SoftVelocity C and C++ help you to check, as far as possible, common coding mistakes. Since no compiler can determine your intentions, you may get warnings even if your code is correct. Your code may generate some warnings more than others, so SoftVelocity allows you to customize which warning checks are performed. You can set each of the warning options to on, off, or err. When on, SoftVelocity checks the code for that warning and reports the problem, but the problem does not stop the compile or linking. When off, SoftVelocity ignores the warning. When err, SoftVelocity checks the code for the warning, reports the problem, and does not allow linking until you have fixed the problem.
SoftVelocity C and C++ check the code and produce a warning for a good reason. Indeed, to use your non-ANSI C code, SoftVelocity C uses a minimal set of warning messages by default. You should, therefore, think twice before turning off any of the default warning messages. We advise that you keep all the warnings either on or err. The following warn #pragmas are available:
#pragma warn(wacc => on | off | err) #pragma warn(wait => on | off | err) #pragma warn(wall => on | off | err) #pragma warn(watr => on | off | err) #pragma warn(wcic => on | off | err) #pragma warn(wcld => on | off | err) #pragma warn(wclt => on | off | err) #pragma warn(wcne => on | off | err) #pragma warn(wcor => on | off | err) #pragma warn(wcrt => on | off | err) #pragma warn(wdel => on | off | err) #pragma warn(wdne => on | off | err) #pragma warn(wdnu => on | off | err) #pragma warn(wetb => on | off | err) #pragma warn(wfnd => on | off | err) #pragma warn(wftn => on | off | err) #pragma warn(wnid => on | off | err) #pragma warn(wnre => on | off | err) #pragma warn(wnrv => on | off | err)
103
cp
This #pragma affects the settings of all the warnings. If set to on or err, all warnings will be enabled.
cp
Pointer conversion. When on or err, the compiler checks for a conversion between two incompatible pointer types, or between a pointer and an integral type. The default setting is on.
cp
Declaration has no effect. When on or err, the compiler checks for a declaration that has no meaning, for example, long int;. A declaration should contain a variable declarator, a structure or union tag, or members of an enumeration. The default setting is on.
cp
Storage class redeclared. When on or err, the compiler checks that you have not declared the same variable differently within your program. For example:
int x; /* External linkage */ /* Internal linkage */ static int x;
The static storage class always takes preference. The default setting is on.
104
cp
Unexpected text in preprocessor command. When on or err, the compiler checks for a new line character terminating a preprocessor command. The default setting is on.
cp
Unknown #pragma. When on or err, the compiler checks for foreign #pragmas or mistakes in SoftVelocity C #pragmas. If you are only creating code using SoftVelocity C or C++ #pragmas, you should switch this warning to either on or err. The default setting is on.
cp
Function not declared. When on or err, the compiler checks for functions that have been called but not declared. If these functions occur, SoftVelocity C assumes that the function is an extern function returning an int. The default setting is off.
cp
Function prototype not declared. When on or err, the compiler checks whether a function has a prototype associated with it. Prototypes are important to SoftVelocity, since it can not do much type checking without them. You should, therefore, declare prototypes for all functions. It is best to keep this warning on or err. The default setting is off.
cp
No expression in return statement. When on or err, the compiler checks for a return value in a non-void function. You should keep this warning off if you are compiling some old style C code without prototypes. The default setting is off.
cp
No return value in function. When on or err, the compiler checks for a return statement in a non-void function. The default setting is off.
cp
Different const attributes. When on or err, the compiler checks whether a function that expects a pointer to a variable gets a pointer to a constant. The default setting is on.
105
cp
Far to near pointer conversion. When on or err, the compiler checks for conversion of a 32bit far pointer to a 16-bit near pointer. The default setting is on.
cp
Near to far pointer conversion. When on or err, the compiler checks for conversion of a 16bit near pointer to a 32-bit far pointer. The default setting is on.
cp
Possible use of variable before assignment. When on or err, the compiler checks that you have used a local variable before you have given it a value. SoftVelocity checks this warning with a simple scan through the function, which can cause gotos and the like to generate false warnings.
cp
Parameter never used in function. When on or err, the compiler checks for a parameter that the code never uses, so declaration of dummy parameters generates warnings. The default setting is off.
cp
Variable declared but never used. When on or err, the compiler checks whether a local variable has been declared but never used in the function. The default setting is on.
cp
Code has no effect. When on or err, the compiler checks statements and the left operand in a comma expression to see if they have no effect. The default setting is on. For example:
x y; /* expression has no effect */ f, x; /* left operand has no effect */
cp
Conversion may lose significant digits. When on or err, the compiler checks for a conversion from long or unsigned long to int or unsigned int. The default setting is on.
106
cp
Assignment in test expression. When on or err, the compiler checks for a possible mistyping of the C equality (==) operator. The equality operator contains two =. For example:
if (x=y) printf("X equals Y"); /* is a mistake */
cp
Value of escape sequence is too large. When on or err, the compiler checks that an escape sequence is in the range 0 to 255. The default setting is on.
cp
Value of constant is out of range. When on or err, the compiler checks whether an integer constant is in the range of an unsigned long, or a floating point constant is in the range of a long double. The default setting is on.
cp
Constant is long. When on or err, the compiler checks for an integral constant that has type long because of its value but does not have an L suffix. The default setting is off.
cp
Returns address of local variable. When on or err, checks for a return statement that returns the address of a local variable. This causes a problem because C reclaims the variable storage on completion of the function. The pointer, therefore, points at undefined data. The default setting is on.
107
cp
Default type promotion on parameter. When on or err, the compiler compares the declaration of a parameter in an old-style function definition with the prototype for incompatible argument promotions. For example:
int func(char); /* parameter declared as char */
This is a violation of the ANSI C standard regarding compatible function declarations.The default setting is on.
cp
Parameter list inconsistent with previous call. This warning is issued if a parameter declaration is incompatible with the corresponding parameter in a previous function declaration. The default setting is on.
cp
Address for local variable not in DGROUP. When on or err, the compiler checks that a local variable does not have its address taken in small model, when using #pragma data(ss_in_dgroup => off). The default setting is on.
cp
Function redeclared with fixed parameters. When on or err, the compiler checks for a prototype with a variable number of arguments, but the corresponding function definition specifies a fixed number of arguments. This will work in SoftVelocity C, but it is a violation of the ANSI C rules for compatible function declarations, and therefore, not portable. The default setting is on.
108
cp
Local variable never used. When on or err, the compiler checks whether you declare a local variable and assign it a value but never use it. The default setting is on.
cp
Overflow in constant expression. This warning is issued when a constant integer expression overflows. The default setting is on.
cp
Default access specifier used for base class. This warning is issued if a base class specification does not have an access specifier and the default access is used (i.e. public for a struct and private for a class). The default setting is on.
cp
Expression in delete[] is obsolete. This warning is issued if an expression is specified in the square brackets of a delete expression. The expression is ignored. This is obsolete C usage. The default setting is on.
cp
Keyword overload is not required. This warning is issued if the keyword overload is specified in C. The use of this keyword is obsolete C usage. The default setting is on.
cp
Constant in code segment requires initialization. This warning is issued if a constant placed in the code segment requires run-time initialization, as may be the case for an object declared const in C, whose initializer is an expression, when the const_in_code #pragma is set on. This situation will lead to a protection violation in OS/2 and Window 3 protected mode applications, so const_in_code should be set off if this warning is encountered. The default setting is on.
cp
This warning is issued if a class is defined in a function return type specification. Such a construct is legal, but unusual, and frequently results from omitting a semicolon between a class definition and the following function declaration. The default setting is on.
109
Project #pragmas
A #pragma with the class name project is used to pass information from a compile to the Project System. The value of the #pragma should be a string, which is then stored in the object file for use by the Project System. Whenever an object file is added to the link list, the text specified using this #pragma is executed as a Project System command. For example, if a header file includes the line:
#pragma project("#set myflag=on")
then whenever a source file that includes this header file is included in a project, the Project System macro myflag will be set. This might be used for processing later in the project file. This #pragma may only appear in source files, not in a project file.
Save/Restore #pragmas
The save #pragma saves the entire #pragma state, so you can later restore it with a restore #pragma. The save and restore #pragmas work in a stack-like manner, thus allowing you to nest them. For example:
/*save the #pragma state and enable the interruptconvention*/ #pragma save #pragma call(interrupt => on) /* interrupt functions are specified here */ #pragma restore
There is no limit on the number of saves, except the amount of memory available. These #pragmas may be used in source files or in a project file.
Link #pragmas
#pragma link( <filename> {,<filename> } ) #pragma linkfirst( <filename> ) These #pragmas may be specified in a project file, in which case the nominated files are added immediately to the link list. In addition, the link #pragma may be specified in a C or C++ source file, in which case the nominated files will be added to the link list when an autocompile command is executed in the Project System, if any files already on the link list had this #pragma specified. For example:
#pragma link( file1.obj, file2.obj, file3.lib ) #pragma linkfirst (initexe.obj)
110
If no extension is given .obj is assumed. Files specified using #pragma link are added to the end of the link list (unless already present). A file specified using #pragma linkfirst is linked before the link list. Only one file may be specified for each link using #pragma linkfirst.
Link_Option #pragmas
#pragmas with the class name link_option are used to specify linker options. These #pragmas may only occur in project files. The following link_option #pragmas are available:
#pragma link_option(case => on | off ) #pragma link_option(decode => on | off ) #pragma link_option(link=> <string>) #pragma link_option(map => on | off) #pragma link_option(overlay => on | off ) #pragma link_option(pack => on | off ) #pragma link_option(shift => num) #pragma link_option(share_const => on | off) #pragma link_option(icon => iconname)
Controls whether a map file is generated with information about segment sizes and publics etc. The default is to create a map file.
This #pragma controls whether the linker treats upper/lower case as significant when linking. The default is case=>off.
This #pragma controls whether segments are packed together. The default is pack=>on.
This indicates whether the linker should produce decded names in the MAP file, as well as their public symbols. The option is set to on if any C source files are included in a project, otherwise off.
111
This specifies the segment alignment shift count for new-format executables. The default is 4, indicating that segments are aligned on 16-byte boundaries.
This pragma controls whether the 16-bit linker commons-up identical constants. The default is on, making the exe file smaller, but C programmers may want to turn it off if they are relying on constants having different addresses.
This pragma specifies the name of the application icon file (icon => MyIcon.ico).
Define #pragmas
A #pragma whose class name is define is used to define a conditional compile symbol for subsequent compiles. The symbol is available for interrogation by the OMIT and COMPILE compiler directives. See the Language Reference for more information. This #pragma may only be used in project files. A define #pragma takes the form:
#pragma define(ident=>value)
where ident names the symbol and value specifies the value it is given. For Modula-2, the given identifier is defined as a boolean constant with value TRUE if the value on was specified, otherwise FALSE. For C and C++, the given identifier is defined as a macro. If the value on is specified, the macro is defined to the value 1. If the value off is specified, the macro is not defined. Any other value will cause the identifier to be defined as a macro expanding to the given value. Only a single C or C++ token may be specified, or the compiler will report an error. To define a macro where the value is a string literal, use a command of the form #pragma define (name => "fred").
Enables (onthe default) or disables (off) generation of initialization code. Turn maincode off when compiling generic modules or LIB modules.
112
Specifies divide by zero behavior. When on, division by zero returns zero. When off (the default), division by zero returns an exception.
Specifies rounding behavior when truncating a REAL to a LONG. When on, the result is rounded up if the REAL value is "close to" the next larger integer. When off (default), no rounding occurs.
Specifies the size (in bytes) of the threshold at which any data structure larger than the specified size (default is 16384) is assigned heap memory instead of stack memory.
Specifies use of Binary Coded Decimal (BCD) arithmetic when on (default) and forces use of Floating Point arithmetic when off.
Specifies use of Binary Coded Decimal (BCD) arithmetic for ULONG variables when on (default) and forces use of Floating Point when off.
Enables or diables use of DECIMAL and PDECIMAL variables greater than fifteen (15) digits. The default is on (enabled).
Specifies number of procedures per segment. By default (n = 0) all procedures ina single module go into a single code segment. Setting the value of n for a specific module "breaks up" the module containing a large number of procedures which "breaks" the 64K code segment limit.
113
Specifies the compiler will invoke a procedure call at the beginning and end of compiling each procedure. This allows you to implement your own profiler. The prototypes for these procedures must be:
EnterProc(UNSIGNED Line,*CSTRING Proc,*CSTRING, File),NAME(Profile:EnterProc) LeaveProc(),NAME(Profile:LeaveProc)
The EnterProc is called at the beginning of each procedure and LeaveProc at the end.
Specifies a number (n) that is compatible with the C++module priority schema. Default is 5.
114
115
ALLDRV.PR
#system win dll #model clarion #set drvdebug #set kitdebug = full = full
#set release = off #set fromclw = on #set incbuildno = off #set demo = off #if "%release"="on" #then #pragma define(_RELEASE=>on) #set incbuildno = on #set kitdebug #set drvdebug #endif #pragma define(DEMO_VERSION=>%demo) = off = off
116
#set dowin32=off #set dolib=on #call %%prjfile #set dowin32=off #set dolib=off #abort off #set dowin32=on #set dolib=off #call %%prjfile #set dowin32=on #set dolib=on #call %%prjfile #abort on #if #exists btrieve.pr #if #exists odbc.pr #if #exists cla21.pr #if #exists tps.pr #if #exists dos.pr #if #exists ascii.pr #if #exists basic.pr #set domodels= #set dowin32=off #set dolib=off #call %%prjfile #set dowin32=off #set dolib=on #call %%prjfile #set dowin32=off #set dolib=off
#then #set prjfile=btrieve.pr %domodels #then #set prjfile=odbc.pr %domodels #then #set prjfile=cla21.pr %domodels #then #set prjfile=tps.pr %domodels #then #set prjfile=dos.pr %domodels #then #set prjfile=ascii.pr %domodels #then #set prjfile=basic.pr %domodels
#file redirect ts.red #if #exists sql400.pr #if #exists oracle.pr #then #set prjfile=sql400.pr %domodels #then #set prjfile=oracle.pr %domodels #endif #endif
117
ORACLE.PR:
#noedit -------------------------------------------------------------------------------------------------------------------------------------ORACLE.PR Oracle Driver project file ------------------------------------------------------------------------------------------------------------------------------------#system win dll #model clarion ---target OS is windows, dll executable --memory model is clarion
Set default macro values. These "switches" will control the make process = ORA = off = off = full = full = off = on --set %cpath to path where file is created --%opath to path where file is opened --%ext to CPP --%tail to ORACLEIN --%cdir to directory where file is created --%odir to directory where file is opened
#set drv #set trace #set heapchk #set drvdebug #set sqldebug #set kitdebug --#set release
#expand ORACLEIN.CPP
-- Define a conditional compile symbol for subsequent compiles. -- The symbol is DRVSPEC, and its value is "oraclesp.h" -- DRVSPEC is available for interrogation by the OMIT and COMPILE -- statementssee the Language Reference for more information. #pragma define(DRVSPEC=>'"oraclesp.h"') --Compile the sql modules with appropriate levels of debug code. #include SQLFILES.PR --Execute statements from SQLFILES.PR here.
118
#compile ORACLEIN.CPP
--compile the oracle c++ source. --both are added to the link list.
#compile ORAIMPOR.CLW /define (maincode=>off)--and the clarion source. #pragma link(ORAIMPOR.RSC) #pragma link (ORA7WIN.LIB) #pragma link (%lnkpfx%asc.LIB) --add ORAIMPOR.RSC to the link list. --add ORA7WIN.LIB to the link list. --add C60ASC.LIB to the link list. --%lnkpfx% resolves to C60, ---Execute the series of statements assigned to drv_Link at the very end of the DRVKIT.PI file. These statements are designed to link and patch the File Driver.
%drv_Link
SQLFILES.PR:
-- Release version: Disable all debugging and tracing #if "%release"="on" #then #set drvdebug #set kitdebug #set sqldebug #set trace #set heapchk #endif -- make sure the sql_type switch is explicitly set (no default) #if '%sql_type' = '' #then #error "sql_type must be set" #endif -- Default is compact code. Set the DRIVER_COMPACT symbol based on -- the value of the %compact macro #if "%compact"="" #then #set compact=on #endif #if '%compact'='off' #or '%heapchk'='on' #then #pragma define(DRIVER_COMPACT=>off) #else #pragma define(DRIVER_COMPACT=>on) = off = off = off = off = off
119
#include DRVKIT.PI
--Execute statements from DRVKIT.PI here. --All macros, pragmas, and link list are fully --available to the #included statements.
#pragma save
--Save the current #pragma settings so they --can be restored later with #pragma restore.
-- Debugging: Debugger info and Run-time checks #if "%sqldebug"="" #then #set sqldebug=off #endif #pragma debug(vid=>%sqldebug) #if "%sqldebug"="full" #then #pragma debug(line_num=>on) #endif #pragma warn(wall=>on) #set srcfile = SAFESTR.CPP #set dstfile = %sql_type%SAFE.CPP -----enable all warning msgs --set %srcfile to SAFESTR.CPP --set %dstfile to OSAFE.CPP --for full debugging, enable --and line numbering #pragma check(index=>on,range=>on,overflow=>on) --runtime error checks --default is off
Execute the series of statements assigned to makesrc in the middle of the DRVKIT.PI file. These statements are designed to get the C++ constructor entry point to have a different name for each driver.
%makesrc #set srcfile = SQLOPEN.CPP #set dstfile = %sql_type%SQLOPE.CPP %makesrc #set srcfile = SQLUPDAT.CPP #set dstfile = %sql_type%SQLUPD.CPP %makesrc #set srcfile = SQLRETRI.CPP #set dstfile = %sql_type%SQLRET.CPP %makesrc -- ditto -- ditto -- ditto
120
#set srcfile = SQLGLOB.CPP #set dstfile = %sql_type%SQLGLO.CPP %makesrc #if %system=win #then #set srcfile = SQLVIEW.CPP #set dstfile = %sql_type%SQLVIEW.CPP %makesrc #endif #pragma restore #pragma warn(wall=>on)
-- ditto
-- conditionally -- ditto
--restore the #pragma settings saved earlier --enable all warning messages
DRVKIT.PI:
#noedit ---------------------------------------------------------------------------------------------------------------------------------------------DRVKIT.PI Driver Kit project include file ---------------------------------------------------------------------------------------------------------------------------------------------- DrvKit.Pi contains project statements common to all Driver Kit based -- File Drivers. -- drvkit.pi: -----------#set trace #set heapchk #set common = on = on = on -- Enable tracing -- Enable Heap Checker -- Merge common code Optional: Any other defines that affect the Driver Specification #set drv = A 3 or 4 letter driver id (e.g C21) -- or appropriate file #pragma define(DRVSPEC='"c21specs.h") The following settings must be set before including
121
122
#if "%pfx"="" #then #set pfx #endif #else #set dolib=off #if %model=extendll #then #pragma define(_XTDDLL=>on) #endif #set pfx = %M%%drv% = %drv%
#if '%RWMODE%' = 'on' #then #set lnkpfx=drw #else #set lnkpfx=%clapfx% #endif #set S = "" #endif --set suffix to null
#set drvname
= %lnkpfx%%drv%%S%
#message "Making %drvname% File Driver" --Display status message #if #not "%inbrowser" #then #if #exists %drvname%.ver #then #compile %drvname%.ver #endif #endif --Conditionally... -compile the driver
-- Heap Checker: Compile and enable Heap Checker (No Debugging) #if "%heapchk"="on" #or "%heapdbg"="on" #then #set heapchk = on #pragma define(HEAPCHK=>on) #if "%heapdll"="on" #then #pragma link(%clapfx%hchk.lib) #else #pragma save #if "%heapdbg"="on" #then #pragma debug(vid=>full) --Save current pragma settings. --Conditionally... -- enable debug code. --Set compiler directive switch. --If dll, then --add heapchk lib to link list.
123
-- Debugging: Debugger info and Run-time checks #if "%drvdebug"="" #then #set drvdebug=full #endif--default is "full" #pragma debug(vid=>%drvdebug) #if "%drvdebug"="full" #then #pragma check(index=>on,range=>on,overflow=>on) #pragma debug(line_num=>on) #endif --enable runtimes --enable line nos.
-- Common Code: Some Driver Kit code is merged when linking multiple -- File Driver Libraries #if "%common"="on" #then #pragma define(COMMON_CODE=>on) #endif #if '%drvdir' = '' #then #error "drvdir must be set to build lib versions of the drivers" #endif -- To get the C++ constructor entry point to have a different -- name for each of the drivers it is necessary to compile -- different C++ source modules: #set makesrc = ' #if (#not #exists %%drvdir%%%%dstfile) #or (%%drvdir%%%%dstfile #older %%srcfile ) #or (%%srcfile #older %%drvdir%%%%dstfile ) #then #expand %%srcfile #run "copy %%opath %%drvdir%%%%dstfile > NUL " #endif #compile %%dstfile %%defns --Conditionally... -- define compiler switch
124
' -- Driver Kit: Compile Driver Kit sources #pragma save settings #if #not "%kitdebug"="" #then #pragma debug(vid=>%kitdebug) #else #pragma debug(vid=>off) #endif #set srcfile = DRVL1.C #set dstfile = %pfx%L1.C prefix %makesrc #if #not "%nocommon" ="on" #then #set srcfile = DRVSTATE.C #set dstfile = %pfx%STAT.C %makesrc #if #not (%system=dos) #then #set srcfile = DRVVIEW.CPP #set dstfile = %pfx%VIEW.CPP %makesrc #if #not (%filetype=dll) #then #pragma define(DRV_HAS_LIBMAIN=>on) #endif #set srcfile = DRVW.C #set dstfile = %pfx%W%dolib%.C #set defns = '/define(_LIB_TARGET=>%dolib%)' %makesrc #set defns = '' #set srcfile = DRVWUTIL.C #set dstfile = %pfx%WUTI.C %makesrc
--Set srcfile name --set dstfile name w correct --Execute stmts defined above. --if common code --make DRVSTATE
--make DRVWUTIL
125
#if #not %dolib% #then #set srcfile = DRVDIAL.CLW #set dstfile = %pfx%DIAL.CLW #set defns = '/define(maincode=>off)' %makesrc #set defns = '' #pragma link(%pfx%dial.rsc) #endif #endif #endif #if "%trace"="on" #then #pragma save, define(TRACE=>on) #set srcfile = DRVTRACE.C #set dstfile = %pfx%TRAC.C %makesrc #endif #set srcfile = DRVPIPE.C #set dstfile = %pfx%P%dolib%.C #set defns = '/define(_LIB_TARGET=>%dolib%)' %makesrc #set defns = '' #if "%trace"="on" #then #pragma restore #endif #pragma restore
--make DRVPIPE
-- Build Macro drv_Link to be used later in this process -- to link and patch the File Driver: #set drv_Link = ' #pragma link_option(share_const=>on) #if #not (%%system=dos) #then #if "%%dolib"="on" #then #dolink %%drvname%%.lib
126
#else #implib %%drvname%%.lib %%drvname%%.exp #if define(_CW15)=on #then #pragma linkfirst(idll%%S%%w.obj) #else #pragma linkfirst(icwdll.obj) #endif #pragma link(win%%S%%.lib) #pragma link(cwrun%%S%%.lib) #pragma link_option(decode=>off) #dolink %%drvname%%.dll #endif #if "%%make" #and #not "%%dolib"="on" #then
#exemod %%drvname%%.dll %%drvname%%.exp %%drvname%%.map #endif #else #if %%filetype=dll #then #implib %%drvname%%.lib %%drvname%%.exp #endif #set tscla #set tscpp = on = off
#link %%drvname%% #if "%%make" #and (%%filetype=dll) #then #expand %%drvname%%.dll #run "mkdriver %%cpath > NUL" #endif #endif '
127
Statement
Attribute
NAME LIBRARY HEAP_COMMIT HEAP_RESERVE STACK_COMMIT STACK_RESERVE IMAGE_BASE DEBUG LINENUMBERS SECTION_ALIGNMENT FILE_ALIGNMENT EXPORTS
Names the application Names the dynamic-link library Amount of heap committed Amount of heap reserved Amount of stack committed Amount of stack reserved Module base memory location Include debug information Include line number information Multiples of 4096 only Multiples of 512 only Defines exported functions
Advanced Topics & Reference Guide Values of n and m set the image major and minor version fields in PE optional header respectively. n and m must be decimal numbers. Default values for these fields are zero (0).
If you use either a NAME or a LIBRARY statement, it must precede all other statements in the module definition file. You can include source-level comments in the module definition file, by beginning a line with a semicolon(;). The utilities ignore each such comment line. Module definition keywords (such as NAME, LIBRARY, and EXPORTS) must be entered in uppercase letters. The EXPORTS statement must appear last.
129
appname
If appname is given, it becomes the name of the application as it is known by the operating system. If no appname is given, the name of the executable file, with the extension removed, becomes the name of the application. Used to control the programs behavior under Windows. This information is kept in the executable-file header. The apptype field may have one of the following values: WINDOWAPI The application uses the API provided by Windows and must be executed in the Windows environment. GUI Same as WINDOWAPI. CUI The program uses a character based user interface, like DOS.
apptype
If the NAME statement is included in the module-definition file, then the LIBRARY statement cannot appear. If neither a NAME statement nor a LIBRARY statement appears in a module-definition file, NAME is assumed. The following example assigns the name wdemo to the application being defined:
NAME wdemo WINDOWAPI
130
LIBRARY [libraryname][initialization]
libraryname
If libraryname is specified, it becomes the name of the library as it is known by the operating system. This name can be any valid file name. If no libraryname is given, the name of the executable file, with the extension removed, becomes the name of the library. The initialization field is optional and can have one of the two values listed below. If neither is given, then the initialization default is INITINSTANCE. INITGLOBAL The library-initialization routine is called only when the library module is initially loaded into memory. INITINSTANCE The library-initialization routine is called each time a new process gains access to the library.
initialization
If the LIBRARY statement is included in a module definition file, then the NAME statement cannot appear. The following example assigns the name mydll to the dynamic-link module being defined, and specifies that library initialization is performed each time a new process gains access to myDLL:
LIBRARY myDLL INITINSTANCE
131
132
Advanced Topics & Reference Guide For more information search MSDN for "Base Address" or "Rebase". Example: IMAGE_BASE 00600000h
It's best to supply the address in hex since all documentation on the OS will show a hex address and it's easy to tell you've got a good address because it always ends with 4 zeros.
133
FILE_ALIGNMENT
EXPORTS exportdefinitions The EXPORTS keyword marks the beginning of the export definitions. It may be followed by up to 3072 export definitions, each on a separate line. You should give an export definition for each dynamic-link routine that you want to make available to other modules. The syntax for an export definition is as follows: entryname [pwords] @number | ? [NODATA] entryname pwords Defines the function name as it is known to other modules. Specifies the total size of the functions parameters, as measured in words (the total number of bytes divided by two). This field is required only if the function executes with I/O privilege. When a function with I/O privilege is called, OS/2 consults the pwords field to determine how many words to copy from the callers stack to the I/O-privileged functions stack. Defines the functions ordinal position within the module-definition table. The @ may be followed by the position number of the function, or it may be followed by a question mark ( ? ) if the position is unknown. The numbers must be in sequence.
@number | ?
134
Advanced Topics & Reference Guide The EXPORTS statement is meaningful for functions within dynamic link libraries, functions which execute with I/O privilege, and call back functions in Windows programs. For example:
EXPORTS Func1 Func2 CharTest @? @? @?
Exporting CLASSes
Exporting CLASS declarations requires a special form of export definition. You must create two export definitions for the CLASS itself. The first begins with VMT$ followed by the name of the CLASS as the entryname. The second begins with TYPE$ followed by the name of the CLASS as the entryname. These are followed by an export definition for each method in the CLASS to export whose pwords must begin with the name of the CLASS as the first parameter. For example:
EXPORTS VMT$MYCLASS TYPE$MYCLASS FIRSTMETHOD@F7MYCLASS SECONDMETHOD@F7MYCLASS @? @? @? @?
135
136
Here is an example of the export file (EntryPoint is the procedure entry into the DLL) :
-------------------------------------EXPORTS EntryPoint@F @? __checkversion @? __sysstart @? __sysinit @? _exit @? Cla$code @? Cla$init @? Wsl$Closedown @?
In this example, the entry point procedure name in the Local DLL is: "EntryPoint"
Use the Inside the Export List Global Embed to add to your export list within the application. 3. The starter EXE must use External link mode. The source is written so that it just calls the DLL's entry point procedure. Example starter EXE code:
--------------------------PROGRAM MAP MODULE('') EntryPoint() END END CODE EntryPoint
137
A version script file is simply a text file with the extension of .Version. When included into a Clarion project (application or hand coded), the version file stamps, or writes, a variety of information into the target executable. This information can be viewed by right-clicking on the executable file, and selecting Properties from the popup menu. A Version tab should be available with the designated version information. More detail regarding the standard format of the version info script can be found at the Microsoft web site. Point your search engine to Version Resource. Clarion also adds the following exceptions to this standard: 1. A LANGUAGE directive can precede the Version script as follows:
LANGUAGE <language code> VS_VERSION_INFO VERSIONINFO ... END
If the LANGUAGE directive is present in the version file, the language code for the resource target executable is set. This allows a developer to have multiple version info resources for different languages. 2. In the version information group, numbers must use one of the following formats: - decimal numbers (0-9) - hexadecimal numbers in C/C++ format (Example: 0x3fL) - hexadecimal numbers in Modula-2/Clarion format (Example: 040904E4) - binary numbers in Modula-2/Clarion format
3. Strings must be of C/C++ format. The \u and \x escape characters are not supported in strings. 4. #include directives are not supported, but all standard mnemonics for the version info related constants are built in to the compiler.
1 VERSIONINFO FILEVERSION 1,0,0,1 PRODUCTVERSION 1,0,0,1 FILEFLAGSMASK 0x3fL FILEFLAGS 0 FILEOS VOS__WINDOWS32 FILETYPE VFT_APP FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "This just a test\0" VALUE "FileVersion", "1, 0, 0, 1\0" VALUE "InternalName", "Version Info Script Example\0" VALUE "LegalCopyright", "Copyright (C) 2003\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "TEST\0" VALUE "ProductName", "Version Info Script compiler\0" VALUE "ProductVersion", "1, 0, 0, 1\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1252 VALUE "Translation", 0x419, 1251 VALUE "", 0x409, 1111 END END
This file is a working example. You can use this as a template for your real world version script files. Simply copy this example to a text file, name it yourfilename.version, and include it in the Library, object, and resource files section of the Project Tree.
139
140
Compiler Integration
With the SoftVelocity 3GL compilers installed, the Clarion development environment takes all the action necessary to call the correct compiler for each source module in the application. You cannot mix languages in a single source module; however, an application can contain any number of source modules written in any of the 3GLs or Clarion. The development environment calls the correct compiler for each module at compile time by looking at the source file extensions, as follows: Source File Extension .CLW .CPP or .C .MOD Compiler Called Clarion C++ Modula-2
Source files with any other extensions will generate an Unknown compiler for ... error message at compile time. The Development Environment will also ensure that all modules are linked correctly and that the SoftVelocity SmartLinker is given all the information that it requires.
The Application Generator generates the MODULE and END statements. Failure to correctly prototype your functions will almost certainly result in a General Protection Fault at run time. 2. Use the Text Editor to write your 3GL code. Be sure to save the code with a file extension that the compiler can recognize (.C, .CPP, .MOD, or .PAS).
Multi Language Programming 3. Add the module to the application as an External Source Module. Select Application > Insert Module from the main menu. Then select class External Source from the Select Module Type dialog. Enter the name of the 3GL module in the Name field, then enter the name of the include file in the Map Include File field of the Module Properties dialog 4. Compile and run the application.
141
In a hand-coded Clarion application: 1. Create the function prototypes for the Clarion compiler. You must prototype the functions you intend to call from Clarion code (see Procedure Prototyping in the Language Reference). The global MAP structure should contain the prototypes. Each 3GL module should have its prototypes in a separate MODULE structure, something like this:
MODULE(module name) MyFunc(*CSTRING),CSTRING,RAW,PASCAL,NAME(_MyFunc) END
You must include a complete MODULE structure in your Clarion MAP for all your 3GL modules. Failure to correctly prototype your functions will almost certainly result in a General Protection Fault at run time. 2. 3. Use the Text Editor to write your 3GL code, saving the code with a file extension that the compiler can recognize (.C, .CPP, .MOD, or .PAS). Add the module to the Project as an External Source File. Select Project > Edit from the main menu. Highlight External Source Files then press the Add File... button. Select the 3GL source mofule from the standard file open dialog that appears. 4. Compile and run the application.
142
Clarion STRING variables are normally passed as two parameters: first, a UNSIGNED which contains the length of the data buffer; second, the address of the data. CSTRINGs and PSTRINGs are passed the same as STRINGs (as two parameters). The RAW attribute can be used in the Clarion prototype to pass only the address of the string data to external 3GL functions (Clarion language procedures do not need, or support, RAW).
143
Clarion DATE and TIME data types may be passed to C functions as a CLALONG, the CLADATE and CLATIME unions can then be used to resolve the elements of the date or time from the CLALONG value.
typedef union { CLALONG struct { CLABYTE CLABYTE CLAUSHORT } } CLADATE; CLALONG struct { CLABYTE CLABYTE CLABYTE CLABYTE } } CLATIME; ucHund; ucSecond; ucMinute; ucHour; s; n; typedef union { ucDay; ucMonth; usYear; s; n;
144
Because of Clarions two-parameter method of passing STRINGs, the CLASTRING structure is useful for certain internal uses, but cannot be used to accept parameters from Clarion:
typedef struct { char *pucString; CLAUSHORT usLen } CLASTRING;
Clarion STRING variables are not NULL terminated, they are padded with spaces up to the length of the data buffer. The trailing spaces can be removed by using the Clarion CLIP procedure. The following code declares a STRING of 20 characters, assigns some data into it, and passes it as a parameter to a C or C++ function.
StringVar CODE StringVar = 'Hello World...' C_Write_Function(StringVar) STRING(20)
In the above example, usLen would have a value of 20 and bData would be padded with trailing spaces. This padding would be written to the screen by C_Write_Function(). Many C routines expect a string to be NULL terminated. To address this issue, Clarion provides the CSTRING data type. CSTRING variables are automatically NULL terminated when data is assigned to them. This makes it possible for existing C routines to operate on the data. A Clarion GROUP may be declared to contain related data. A group is roughly equivalent to a C or C++ struct. When passed as a parameter to a procedure, GROUPs are normally passed as three parameters: first, an UNSIGNED is passed which contains the size of the GROUP; second, the address of the GROUP structure; and third, the address of a buffer containing a type descriptor for the GROUP. The contents of the type descriptor are not discussed here and are subject to change in future versions of Clarion. GROUPs may be nested, and other
Multi Language Programming GROUPs may be defined to assume the same structure as a previously declared GROUP. There are several forms of declaration for Clarion GROUPs:
Struct1 ul1 ul2 GROUP ULONG ULONG END ! Struct1 is defined as a GROUP ! containing two ULONG values
145
This form of definition reserves space for Struct1 and is equivalent to the C definition:
struct { CLAULONG CLAULONG } Struct1; ul1; ul2;
In the following example, the declaration of Struct2 declares a GROUP similar to that defined by Struct1, however no space is reserved. In practice there need not be any instances of Struct2 defined.
Struct2 ul3 ul4 GROUP,TYPE ULONG ULONG END ! Struct2 is declared as a GROUP ! containing two ULONG values
In the following example, the definitions of Struct3 and Struct4 define them to be LIKE(Struct2), i.e. of the same internal structure. In order to distinguish members of Struct3 and Struct4 from those of Struct2 the S3 and S4 prefixes must be used. Struct3 and Struct4 define instances of Struct2 (which is not necessarily defined anywhere). In both cases space is reserved.
Struct3 Struct4 LIKE(Struct2) LIKE(Struct2)
Struct3 Struct4
S3; S4;
147
Clarion DATE and TIME data types may be passed to Modula-2 procedures as a LONG, the DATE and TIME RECORDs can then be used to resolve the elements of the date or time from the LONG value.
DATE = RECORD CASE : BOOLEAN OF | TRUE: l ELSE ucDay ucMonth usYear END END; TIME = RECORD CASE : BOOLEAN OF | TRUE: l ELSE ucHund ucSecond ucMinute ucHour END END; : BYTE; : BYTE; : BYTE; : BYTE; : LONG; : BYTE; : BYTE; : SHORT; : LONG;
148
Clarion STRINGs are passed in the same manner as Modula-2 open ARRAY OF CHAR parameters with the call(o_a_copy=>off) pragma in effect (the length and the address of the string are passed). The following example code declares a string of 20 characters, assigns some data into it and passes it as a parameter to a Modula-2 procedure
MAP MODULE('M2_Code') M2_Write_Proc(*STRING), NAME('M2_Code$M2_Write_Proc') END END StringVar CODE StringVar = 'Hello World...' M2_Write_Proc(StringVar) STRING(20)
Note that Clarion STRINGs are not NULL terminated, they are padded with spaces up to the length of the data buffer. In the above example, StringVar would be padded with spaces up to a length of 20 characters. Variables of type CSTRING are automatically NULL terminated when data is assigned to them. This makes it possible for existing Modula-2 routines to operate on the data.
Multi Language Programming A Clarion GROUP is roughly equivalent to a Modula-2 RECORD. There are several forms of declaration for Clarion GROUPs. The following conforms to the Modula-2 declaration of the DATE type above:
DateType GROUP n d ucDay ucMonth usYear END LONG GROUP,OVER(n) BYTE BYTE SHORT END
149
The OVER attribute is used to ensure that n and d occupy the same memory, the total size of the group is the size of the member n. When passed as parameters, GROUPs are normally passed as three parameters: first, an UNSIGNED is passed which contains the size of the GROUP; second, the address of the GROUP structure, and third, the address of a buffer containing a type descriptor for the GROUP. The contents of the type descriptor are not discussed here and are subject to change in future versions of Clarion. You may use the RAW attribute in your Clarion prototype for the Modula-2 procedure to instruct the compiler to pass only the address of the GROUP, otherwise you must define your Modula-2 procedure to take 2 extra parameters:
MAP MODULE('M2_Code') M2_Proc1(*GROUP) M2_Proc2(*GROUP), RAW END END
150
Clarion DATE and TIME data types may be passed to Pascal procedures as a LONG, the DATE and TIME records can then be used to resolve the elements of the date or time from the LONG value.
DATE = RECORD CASE BOOLEAN OF TRUE: (n FALSE: (ucDay ucMonth usYear END; TIME = RECORD CASE BOOLEAN OF TRUE: (n FALSE: (ucHund : BYTE; ucSecond : BYTE; ucMinute : BYTE; ucHour END; : BYTE); : LONG); : BYTE; : BYTE; : SHORT); : LONG);
Because of Clarions two parameter method of passing STRINGs, the STRING structure is useful for certain internal uses, but cannot be used to accept parameters from Clarion:
151
Clarion PSTRINGs are passed by address in the same manner as Pascal STRING parameters with the call(s_copy=>off) pragma in effect (the length and the address of the string are passed). The following example code declares a string of 20 characters, assigns some data into it, and passes it as a parameter to a Pascal procedure:
MAP MODULE('Pas_Code') Pas_Write_Proc(*PSTRING), NAME('Pas_Code$Pas_Write_Proc') END END StringVar CODE StringVar = 'Hello World...' Pas_Write_Proc(StringVar) PSTRING(20)
152
A Clarion GROUP is roughly equivalent to a Pascal RECORD. There are several forms of declaration for Clarion GROUPs. The following duplicates the Pascal declaration of the DATE type above:
DateType GROUP n d ucDay ucMonth usYear END LONG GROUP,OVER(n) BYTE BYTE SHORT END
The OVER attribute is used to ensure that n and d occupy the same memory, the total size of the group is the size of the member n. When passed as parameters, GROUPs are normally passed as three parameters: first, a USHORT is passed which contains the size of the GROUP; second, the address of the GROUP structure; and third, the address of a buffer containing a type descriptor for the GROUP. The contents of the type descriptor are not discussed here and are subject to change in future versions of Clarion. You may use the RAW attribute in your Clarion prototype for the Pascal procedure to instruct the compiler to pass only the address of the GROUP, otherwise you must define your Pascal procedure to take 2 extra parameters:
MAP MODULE('Pas_Code') Pas_Proc1(*GROUP) Pas_Proc2(*GROUP), RAW END END
153
154
Since the Clarion language does not have a signed BYTE data type, linker warnings (type inconsistency) will result when you prototype a function which receives a char parameter. As long as you are aware that the C function is expecting a signed value, and correctly adjust the BYTE fields bitmap to pass a value in the range -128 to 127, this warning may be safely ignored. The RAW attribute must be used when a C function expects to receive the address of a CSTRING or GROUP parameter. By default, Clarion STRING, CSTRING, PSTRING, and GROUP parameters are passed (internally) to other Clarion procedures as both the address and length of the string. C functions do not usually want or need the length, and expect to receive only the address of the data. Therefore, the RAW attribute overrides this default.
Multi Language Programming If the C function returns void, there is no data returned and the function fits the definition of a Clarion PROCEDURE. If the C function does return data, it is prototyped with the actual data type returned and the function fits the definition of a Clarion PROCEDURE that returns a value and may be called as part of a condition, assignment, or parameter list.
155
156
As you can see, the Clarion return type for a char * is CSTRING (not *CSTRING as you might expect). This is because the Clarion compiler automatically dereferences the pointer to the data when the function returns (as it does with all the pointer return types). Notice that the Clarion return data type for struct * is ULONG. This will generate a "type inconsistency" linker warning. This occurs because the Clarion language does not use pointers, and the ULONG is a four-byte integer which can serve as a replacement for a pointer return type. The warning is not a problem and can be safely ignored. You would probably use memcpy() to get at the returned data.
157
Passing Parameters
Clarion offers two distinct methods of passing parameters to functions or procedures: "passed by value" and "passed by address." "Passed by value" means that the calling code passes a copy of the data to the called function or procedure. The called code can then operate on the data without affecting the callers copy of the data. These parameters are specified by the parameters data type in the prototype. "Passed by address" means that the calling code passes the address of the data to the called function or procedure. With this method, the called function or procedure can modify the callers data. These parameters are specified by prefixing the parameters data type with an asterisk (*) in the prototype:
MAP MODULE('My_C_Lib') Var_Parameter(*USHORT) Val_Parameter(USHORT) END END
These declarations represent the Clarion interface to the functions contained in the C library My_C_Lib. The following example are the equivalent C declarations:
void void Var_Parameter(CLAUSHORT *uspVal); Val_Parameter(CLAUSHORT usVal);
Clarion parameters "passed by address" are equivalent to pointers to the relevant C type. Clarion "passed by value" parameters are passed in the same way as C and C++ value parameters. The corresponding Modula-2 definition module would be:
DEFINITION MODULE M2_Code; IMPORT Cla; PROCEDURE Var_Parameter(VAR us: Cla.USHORT); PROCEDURE Val_Parameter(us: Cla.USHORT); END M2_Code.
158
Advanced Topics & Reference Guide The corresponding Pascal interface unit would be:
INTERFACE UNIT Pas_Code; IMPORT Cla; PROCEDURE Var_Parameter(VAR us: Cla.USHORT); PROCEDURE Val_Parameter(us: Cla.USHORT); END.
You cannot pass a Clarion STRING or GROUP by value. For this reason, you must pass STRINGs or GROUPs by address.
159
You must also ensure that none of the functions return floating-point data types. There is no standard of compatibility between compilers regarding this issue. For example, Microsoft C returns floating-point values in a global variable while Borland C returns them on the stack (SoftVelocity also returns them on the stack but there is no guarantee of compatibility). Therefore, any functions from non-SoftVelocity compilers which must reference floating point values and modify them should receive them "passed by address" and directly modify the value do not have the function return the value. Most other compilers dont provide Clarion-compatible parameter passing conventions, but do provide standard C and Pascal parameter passing mechanisms (passed on the stack). Clarion has the C and PASCAL procedure prototype attributes to specify stackbased parameter passing. Most non-SoftVelocity C and C++ compilers use a calling convention where parameters are pushed onto the stack from right to left (as read from the parameter list). The Clarion C attribute specifies this convention. Many C and C++ compilers also offer a Pascal calling convention where parameters are pushed left to right from the parameter list. Most other languages on the PC also use this convention. The Clarion PASCAL attribute generates calls using this convention. In most cases, the C and PASCAL attributes are used in conjunction with the NAME attribute. This is because many compilers prepend an underscore to function names where the C convention is in use, and uppercase function names where the PASCAL convention is in use (Clarion uppercases procedure names also). For example:
MAP MODULE('My_C_Lib') StdC_Conv(UNSIGNED, ULONG), C, NAME('_StdC_Conv') StdPascal_Conv(UNSIGNED, ULONG), PASCAL, NAME('STDPASCAL_CONV') END END
160
Advanced Topics & Reference Guide When the StdC_Conv procedure is called, the ULONG parameter is pushed on the stack followed by the UNSIGNED parameter. When StdPascal_Conv is called, the UNSIGNED parameter is pushed followed by the ULONG parameter. You should be very careful that calling conventions match, otherwise the program may behave unpredictably. When interfacing with code produced by SoftVelocity compilers, the C and PASCAL calling convention attributes are not necessary because Clarion uses the SoftVelocity registerbased calling conventions. When writing SoftVelocity C functions to be called from a Clarion program, the CLA_CONV macro (discussed above) should be used to select the correct naming conventions. The best way of achieving this is to declare any interface functions in a separate header (.H) file and to apply the conventions to these declarations. C++ functions must be declared using "Pascal" external linkage (also discussed above). Modula-2 and Pascal naming conventions are best handled by using the NAME attribute on the prototype.
161
When the Clarion compiler encounters the StdStr_Parm() procedure, it generates the name _StdStr_Parm in the object code. Although Clarion names are not case sensitive, the name generated using the NAME attribute will appear exactly as specified. The following C language macro defines the Clarion naming conventions. This macro can be used when declaring C functions to interface with Clarion in order to force the C compiler to generate names following the Clarion naming convention (no prepended underscore and all upper case).
#define CLA_CONV name(prefix=>"", upper_case=>on)
C++ compilers encode the return and parameter types of a procedure into the name that appears in the object code in a process known as name mangling. Therefore, C++ compiled functions which may be called from Clarion can be declared within a extern "Pascal" {...}; modifier, which is the equivalent to the C language CLA_CONV macro (which does not affect the name mangling employed by the C++ compiler). For example:
extern "Pascal" void Clarion_Callable_Proc(void);
A more flexible form of the above, allowing for compilation by either a C or C++ compiler, is:
#ifdef __cplusplus extern "Pascal" { */ #else #pragma save, CLA_CONV */ /* Force Clarion conventions in C /* Force Clarion conventions in C++
162
#endif void Clarion_Callable_Proc(void); #ifdef __cplusplus } #else #pragma restore #endif
/* C or C++ declaration
*/
*/ */
This form of declaration usually appears in a header file to be included by any interface code. It ensures that the correct conventions are used when compiled with a C or C++ compiler and eliminates the need to use the NAME attribute on the Clarion language prototype of the procedure or function. Clarion is a case-insensitive language and the compiler converts the names of all procedures to upper-case. Modula-2 and Pascal, however, are case sensitive and also prefix the name of all procedure names with the name of the module in the form: MyModule$MyProcedure. The way to resolve these differences is to use Clarions NAME attribute to specify the full name of the Modula-2 or Pascal procedure to the Clarion compiler:
MAP MODULE('M2_Code') M2_Proc1(*GROUP), RAW, NAME('M2_Code$M2_Proc2') END MODULE('Pas_Code') Pas_Proc1(*GROUP), RAW, NAME('Pas_Code$Pas_Proc2') END END
163
The naming conventions used by Clarion for data differ from those used for PROCEDURES, and are more complex. Therefore, the NAME() attribute should be used to generate a Modula-2 or Pascal-compatible name for any Clarion data that needs to be accessed between languages. Modula-2 and Pascal data names are case sensitive and prefixed with the name of the module and a @ in the form: MyModule@MyProc. The EXTERNAL and DLL Attributes The EXTERNAL attribute is used to declare Clarion variables and functions that are defined in an external library. The DLL attribute declares that an EXTERNAL variable or functions is defined in a Dynamic Link Library (DLL). These attributes provide Clarion programs with a means of accessing public data in external libraries. The compiler will not reserve space for any variables declared as EXTERNAL. For example:
typedef struct { unsigned long unsigned long } StructType; #ifdef __cplusplus extern "C" { /* #endif /* StructType Str1; StructType Str2; #ifdef __cplusplus } #endif
ul1; ul2;
Use C naming conventions, which will require use */ of the NAME attribute in the Clarion prototype */ /* Define Str1 */ /* Define Str2 */ /* Restore C++ conventions */
The following Clarion declarations are all that is necessary to make Str1 and Str2 available to Clarion programs.
StructType ul1 ul2 GROUP,TYPE ! Declare a user defined type ULONG ULONG END ! Declare Str1 and Str2 which are defined in the C module Str1 LIKE(StructType),NAME('_Str1'),EXTERNAL Str2 LIKE(StructType),NAME('_Str2'),EXTERNAL
The NAME attribute is used to allow the linker to use the C naming convention when referencing Str1 or Str2.
164
Programming Considerations
Multi Language Programming The following code does nothing more than provide entry points for the Clarion code to access the functionality of the DIRLIST class library. Since Clarion performs no namemangling and cannot access classes or their members, this API is necessarily fairly simple.
DirList *FileList = NULL;
165
void MakeFileList(char *Path, CLAUSHORT Attr, CLAUSHORT Order) { if (FileList != NULL) // If we have a list { delete FileList; // invoke class destructor FileList = NULL; // so we can start again } FileList = new DirList(Path, Attr, Order); }
The following is the corresponding MAP structure prototype to allow Clarion to call the MakeFileList interface function:
MAP MODULE('DirList') MakeFileList(*CSTRING,USHORT,USHORT),RAW,NAME('_MakeFileList') END END
One disadvantage of this is that, given a large class library, it appears to involve a lot of extra work to create a suitable interface. In practice, however, it should only be necessary to provide a very small interface to begin taking advantage of an existing C++ class library. It is not possible to call C++ code compiled using non-SoftVelocity C++ compilers from a Clarion application. C++ modules usually require special initialization constructors for all static objects must be invoked in the correct order. This initialization process must be performed by the Clarion start-up code. Clarions startup code automatically performs the necessary initialization for any SoftVelocity C++ modules that are present, but it will not initialize modules compiled with other C++ compilers. Even if the modules did not require initialization, other C++ compilers use different calling and naming conventions, and adopt different internal class structures. This makes it impossible to use C++ class libraries in Clarion applications compiled with a compiler other than SoftVelocity C++.
166 Summary:
The Clarion API provides a number of features to assist developers who need to interface to code written in other programming languages. With a little care, it is possible to create Clarion interfaces to some extremely powerful external libraries.
When preparing interfaces to libraries written in other languages you should consider the following suggestions: * Dont write C, C++, Pascal, or Modula-2 functions to return CSTRING variables to Clarion. Have the other language routine place the CSTRING value in a public variable, or pass a *CSTRING (by address) parameter to the C routine to receive the value. Dont call Clarion procedures that return STRING variables from other language functions. Have the Clarion procedure place the return value in a public variable or pass a *CSTRING (by address) parameter to the other language procedure. For simplicity and efficiency, STRING and GROUP parameters should usually be passed by address with the RAW attribute to ensure only the address is passed. Test the application in XLARGE memory model first.
* *
C and C++ Considerations * If a C or C++ function takes a pointer parameter, the corresponding parameter in the Clarion prototype for that function should be declared as "passed by address" by prefixing the data type with an asterisk (*). If a C or C++ function takes a pointer to a GROUP, STRING, PSTRING or CSTRING, you should use the RAW attribute in the Clarion prototype. If a C or C++ function takes an ASCIIZ string as a parameter, the corresponding parameter in the Clarion prototype should be *CSTRING. If a C or C++ function takes a pointer to a structure as a parameter, the corresponding parameter in the Clarion prototype should be *GROUP. Use the header (.H) files as a template for developing a Clarion interface to a C or C++ library that eliminates the need to use the NAME attribute on the Clarion prototype to specify names. Use the NAME attribute on the Clarion prototype to specify names for C library functions that do not use the CLA_CONV macro - remember that C names are case sensitive and start with an underscore (_).
* * * *
167
Modula-2 and Pascal Considerations * If a Modula-2 or Pascal procedure takes a VAR parameter, the corresponding parameter in the Clarion prototype for that procedure should be declared as "passed by address" by prefixing the data type with an asterisk (*). If a Modula-2 or Pascal procedure takes a VAR parameter for a GROUP, STRING, PSTRING or CSTRING, you should use the RAW attribute in the Clarion prototype. If a Modula-2 or Pascal procedure takes a VAR record as a parameter, the corresponding parameter in the Clarion prototype should be *GROUP and the RAW attribute should be used in the prototype.
* *
Additional C++ Considerations * * * * Use the "Pascal" external linkage specification for your C++ interface functions. This eliminates the need to use the Clarion NAME attribute on the prototype. Dont call C++ class member functions from your Clarion code. Dont try to access C++ objects of class type from your Clarion code. Dont try to access C++ code compiled with a C++ compiler other than SoftVelocity.
Additional Modula-2 Considerations * * * Use the definition (.DEF) module as a template for developing a Clarion interface to a Modula-2 library. If a Modula-2 procedure takes an ASCIIZ string as a parameter, the corresponding parameter in the Clarion prototype should be *CSTRING. Use the NAME attribute to specify names for Modula-2 library procedures -remember that Modula-2 names are prefixed with the module name followed by a $ and are casesensitive. Additional Pascal Considerations * * Use the interface (.ITF) files as a template for developing a Clarion interface to a Pascal library. Use the NAME attribute to specify names for Pascal library procedures -remember that Pascal names are prefixed with the module name followed by a $ and are upper-case.
168
169
INCLUDE(CLIB.CLW)
This file contains Clarion prototypes for various string handling functions, integer math, character type functions, and low level file manipulation functions. Refer to your C/C++ Library Reference for more information on individual functions.
INCLUDE(WINAPI.CLW,Equates)
170
Advanced Topics & Reference Guide Include the Prototypes section of WINAPI.CLW in the "Inside the Global Map" embed point:
INCLUDE(WINAPI.CLW,Prototypes)
Refer to your Windows API reference for more information on the individual API functions available to you in categories such as: Creating Windows Window Support Message Processing Memory Management Bitmaps and Icons Color Palette Control Sound Character Sets and Strings Communications Metafiles Tool Help Library File Compression Installation and Version Information TrueType Fonts Multimedia
Modula-2 to Clarion
Clarions Runtime Library To call the Clarion runtime library procedures, use the \CWRUN.DEF file. This file contains Modula-2 declarations for various Clarion Language procedures, as well as the many standard C library functions that are found in the Clarion Runtime Library. The available functions are documented in the Clarions Runtime Library Functions section of this article. Clarions File Driver Procedures To call the Clarion database file driver procedures, use the \CWFILE.DEF file. This file contains Modula-2 declarations for Clarions FILE, RECORD, KEY, INDEX, MEMO, and BLOB handling procedures, including a complete description of Clarions file control block.
171
C/C++ to Clarion
Clarions Runtime Library To call the Clarion runtime library procedures, use the \CWRUN.H file. This file contains C/C++ prototypes for various Clarion Language procedures, as well as many standard C library functions that are found in the Clarion Runtime Library. The available functions are documented below in the Clarions Runtime Library Functions section. Clarions File Driver Procedures To call the Clarion database file driver procedures, use the \CWFILE.H file. This file contains C/C++ prototypes for Clarions FILE, RECORD, KEY, INDEX, MEMO, and BLOB handling procedures, including a complete description of Clarions file control block.
172
Run-Time Variables
An unsigned integer containing the last DOS error code. An integer containing the last Clarion error code. A character array of 80 chars containing the last Clarion error message. An unsigned short containing the instance ID of the application.
The following list of procedures are those internal Clarion procedures that are safe to call at run-time. Unless otherwise stated, assume that these procedures have been given external C linkage.
API Calls and Advanced Programming Cla$ACOS The Clarion ACOS() procedure. Returns the inverse cosine of the val parameter. C++: double Cla$ACOS(double val) Modula-2: Cla$ACOS(val :LONGREAL):LONGREAL; val: A numeric expression describing an angle in radians.
173
Cla$ARC
The Clarion ARC statement. Places an arc of an ellipse on the current window or report, bounded by the rectangle defined by the x, y, wd and ht parameters. void Cla$ARC(int x, int y, int wd, int ht, int start, int end) Cla$ARC(x,y,wd,ht,start,end: INTEGER); x: y: wd: ht: start: end: An integer specifying the horizontal position of the starting point. An integer specifying the vertical position of the starting point. An integer specifying then width. An integer specifying then height. An integer specifying the start of the arc in 10ths of a degree. An integer specifying the end of the arc in 10ths of a degree.
C++: Modula-2:
Cla$ASIN C++:
The Clarion ASIN() procedure. Returns the inverse sine of the val parameter. double Cla$ASIN(double val) Cla$ASIN(val LONGREAL): LONGREAL; val: A numeric expression describing an angle in radians.
Modula-2:
Advanced Topics & Reference Guide The Clarion ATAN() procedure. Returns the inverse tangent of the val parameter. double Cla$ATAN(double val) Cla$ATAN(val: LONGREAL):LONGREAL; val: A numeric expression describing an angle in radians.
Cla$BOX
The Clarion BOX statement. This procedure draws a box of the color specified by the COLORREF structure, starting at position x, y of the width and height specified on the current window or report. void Cla$BOX(int x, int y, int wd, int ht, COLORREF fillcolor) Cla$BOX(x, y, wd, ht: INTEGER; fillcolor: COLORREF); An integer specifying the horizontal start position. An integer specifying the vertical start position. An integer specifying the width. An integer specifying the height.
fillcolor: A COLORREF structure. Cla$BSHIFT The Clarion BSHIFT() procedure. This procedure returns the result of bit shifting val by count binary positions. If count is positive, val is shifted left, if count is negative val is shifted right. C++: long Cla$BSHIFT(long val, int count) Cla$BSHIFT(val: LONGINT; count: INTEGER): LONGINT;
Modula-2: val:
A numeric expression.
175
The Clarion CHORD statement. Draws a closed sector ellipse on the current window or report inside the box specified by the x, y, wd and ht parameters and in the color provided in the COLORREF structure. The start and end parameters specify which part of the ellipse to draw. void Cla$CHORD(int x, int y, int wd, int ht, int start, int end, COLORREF fillcolor) Cla$CHORD(x, y, wd, ht, start, end: INTEGER; fillcolor: COLORREF); An integer specifying the horizontal start position. An integer specifying the vertical start position. An integer specifying the width. An integer specifying the height. An integer expressing the string of the chord in 10ths of a degree. An integer expressing the end of the chord in 10ths of a degree.
The Clarion CLOCK() procedure. Returns the system time in the form of a Clarion standard time. long Cla$CLOCK(void) Cla$CLOCK(): LONGINT;
The Clarion COS() procedure. Returns the cosine of the val parameter. double Cla$COS(double val) Cla$COS(val: LONGREAL): LONGREAL; val: A numeric expression describing an angle in radians.
Advanced Topics & Reference Guide The Clarion DATE() procedure. Returns a Clarion standard date value form the component day, month and year parameters. long Cla$DATE(unsigned mn, unsigned dy, unsigned yr) Cla$DATE(mn, dy, yr: CARDINAL): LONGINT; mn: dy: yr A numeric expression for the month in the range 1 to 12. A numeric expression for the day in the range 1 to 31. A numeric expression for the year in the range 1801 to 2099.
The Clarion DAY() procedure. Returns the day in the range 1 to 31 from the Clarion standard date parameter. long Cla$DAY(long dt) Cla$DAY(dt: LONGINT): LONGINT; dt: A numeric expression for Clarion standard date.
Cla$ELLIPSE The Clarion ELLIPSE statement. Draws an ellipse on the current window or report, of the color specified in the COLORREF structure, inside the area bounded by the x, y, wd and ht parameters. C++: Modula-2: void Cla$ELLIPSE(int x, int y, int wd, int ht, COLORREF fillcolor) Cla$ELLIPSE(x, y, wd, ht: INTEGER; fillcolor: COLOREF); x: y: wd: ht: An integer expression. An integer expression. An integer expression. An integer expression.
177
The Clarion INT() procedure. Returns the integer portion of the val parameter. The value is truncated at the decimal point and no rounding is performed. double Cla$INT(double val) Cla$INT(val: LONGREAL): LONGREAL; val: A numeric expression.
C++: Modula-2:
The Clarion LOG10() procedure. Returns the base 10 logarithm of the val parameter. double Cla$LOG10(double val) Cla$LOG10(val: LONGREAL): LONGREAL; val: A numeric expression.
The Clarion LOGE() procedure. Returns the natural logarithm of the val parameter. double Cla$LOGE(double val) Cla$LOGE(val: LONGREAL): LONGREAL; val: A numeric expression.
The Clarion MONTH() procedure. Returns the month from a Clarion standard date in the range 1 to 12. long Cla$MONTH(long dt) Cla$MONTH(dt: LONGINT): LONGINT; dt: A numeric expression containing a Clarion standard date.
178
Advanced Topics & Reference Guide Cla$MOUSEX The Clarion MOUSEX() procedure. Returns the horizontal position of the mouse. C++: Modula-2: int Cla$MOUSEX(void) Cla$MOUSEX(): INTEGER;
Cla$MOUSEY The Clarion MOUSEY() procedure. Returns the horizontal position of the mouse. C++: Modula-2: int Cla$MOUSEY(void) Cla$MOUSEY(): INTEGER;
Cla$NUMERIC The Clarion NUMERIC() procedure. Returns 1 (true) if str contains a valid representation of a number, otherwise returns 0 (false). C++: Modula-2: unsigned Cla$NUMERIC(char *str, unsigned slen) Cla$NUMERIC(VAR str: ARRAY OF CHAR; slen:CARDINAL): CARDINAL; str: slen: Cla$RANDOM The Clarion RANDOM() procedure. Returns a pseudo-random number whos value will be between the low and high bound values. C++: Modula-2: long Cla$RANDOM(long low, long high) Cla$RANDOM(low, high: LONGINT): LONGINT; low: high: A numeric value specifying the lower bound. A numeric value specifying the upper bound. A pointer to a string. Length of the str parameter.
179
The Clarion ROUND() procedure. Returns the val parameter rounded to power of 10 specified by the ord parameter. double Cla$ROUND(double val, double ord) Cla$ROUND(val, ord: LONGREAL): LONGREAL; val: ord: A numeric expression. A numeric expression equal to a power of 10 (e.g. .001, .0, 1, 10, 100 etc...).
Cla$SETCLOCK The Clarion SETCLOCK statement. Sets the system clock to the time contained in the dt parameter. C++: Modula-2: void Cla$SETCLOCK(long dt) Cla$SETCLOCK(dt: LONGINT); dt: A numeric expression representing a Clarion standard time.
Cla$SETTODAY The Clarion SETTODAY statement. Sets the DOS system date to that contained in the dt parameter. C++: Modula-2: void Cla$SETTODAY(long dt) Cla&SETTODAY(dt: LONGINT); dt: A numeric expression containing a Clarion standard date.
The Clarion SIN() procedure. Returns the sine of the val parameter. double Cla$SIN(double val) CLA$SIN(val: LONGREAL): LONGREAL; val: A numeric expression describing an angle in radians.
Advanced Topics & Reference Guide The Clarion SQRT() procedure. Returns the square root of the val parameter. double Cla$SQRT(double val) Cla$SQRT(val:LONGREAL): LONGREAL; val: A numeric expression.
The Clarion TAN() procedure. Returns the tangent of the val parameter. double Cla$TAN(double val) Cla$TAN(val: LONGREAL): LONGREAL; val: A numeric expression describing an angle in radians.
The Clarion TODAY() procedure. Returns the system date in Clarion standard date format. long Cla$TODAY(void) Cla$TODAY(): LONGINT;
The Clarion YEAR() procedure. Extracts the year from a Clarion standard date, in the range 1801 to 2099. long Cla$YEAR(long dt) Cla$YEAR(dt: LONGINT): LONGINT; dt: A numeric expression describing a Clarion standard date.
181
Cla$PopPString
Takes the topmost item off the stack and copies it to the string pointed to by s; len contains the length of the string copied to s. The string is converted to a Pascal style string (i.e. first byte is string length) during copy. void Cla$PopPString(char *s, unsigned len) Cla$PopPString(VAR s: ARRAY OF CHAR; len: CARDINAL); s: len: A pointer to a string The length of string s
C++: Modula-2:
Advanced Topics & Reference Guide Pops the uppermost stack item and copies it to the string s. void Cla$PopString(char *s, unsigned len) Cla$PopString(VAR s: ARRAY OF CHAR; len: CARDINAL); s: len: A pointer to a null terminated string The length of string s
Pushes s onto the top of the stack. void Cla$PushCString(char *s) Cla$PushCString(VAR s: ARRAY OF CHAR); s: A pointer to a null terminated string
Pushes the string s onto the top of the stack. Len specifies the length of string s. void Cla$PushString(char *s, unsigned len) Cla$PushString(VAR s: ARRAY OF CHAR; len: CARDINAL); s: len: A pointer to a string The length of string s
Cla$StackALL
The Clarion ALL() procedure. Pops the top item of the stack and replaces it by a string containing the original string replicated as many times as necessary to produce a string of length len. void Cla$StackALL(unsigned len) Cla$StackALL(len: CARDINAL); len: An unsigned integer
C++: Modula-2:
183
The Clarion CENTER() procedure. Pops the topmost item of the stack and replaces it with a string padded with leading spaces so as to center the text in a string of length len. void Cla$StackCENTER(unsigned len) Cla$StackCENTER(len: CARDINAL); len: An unsigned integer
C++: Modula-2:
The Clarion CLIP() procedure. Removes trailing spaces from the top most item on the stack. void Cla$StackCLIP(void) Cla$StackCLIP();
Cla$StackCompare
Compares the top item on the stack (s1) with the 2nd item on the stack (s2) and returns one of the following values: -1: if s1 < s2 0: 1: if s1 = s2 if s1 > s2
After the compare instruction, s1 and s2 are removed from the stack automatically. C++: Modula-2: int Cla$StackCompare(void) Cla$StackCompare(): INTEGER;
184
Advanced Topics & Reference Guide Cla$StackCompareN Compares the topmost item on the stack to null. Returns true if the topmost item is null, otherwise returns false. C++: Modula-2: int Cla$StackCompareN(void) Cla$StackCompareN(): INTEGER;
Pops the top two items off the stack, concatenates them together and pushes the resulting string back onto the stack. void Cla$StackConcat(void) Cla$StackConcat();
Cla$StackINSTRING
The Clarion INSTRING() procedure. Searches the topmost item on the stack, for any occurrence of the second item on the stack. The search starts at character position start and increments the start position by step until the end of the string is reach. Returns the iteration count required to find the search string, or 0 if not found. unsigned Cla$StackINSTRING(unsigned step, unsigned start) Cla$StackINSTRING(step, start: CARDINAL): CARDINAL; step: start: An unsigned integer, the search increment An unsigned integer, the start position of the search
C++: Modula-2:
Cla$StackLEFT
The Clarion LEFT() procedure. Replaces the topmost string on the stack with its left justified equivalent. The replacement sting will have a length of len. void Cla$StackLEFT(unsigned len) Cla$StackLEFT(len: CARDINAL); len: An unsigned integer
C++: Modula-2:
185
Returns the length of the topmost item on the stack. Does not pop the item off the stack. unsigned Cla$StackLen(void) Cla$StackLen(): CARDINAL;
Returns the length of the topmost item on the stack. Pops the item of the stack after getting its length. unsigned Cla$StackLen2(void) Cla$StackLen2(): CARDINAL;
The Clarion LOWER() procedure. Replaces the topmost string on the stack with its lower case equivalent. void Cla$StackLOWER(void) Cla$StackLOWER();
Pops the top item off the stack. void Cla$STACKpop(void) Cla$STACKpop();
Returns true if the topmost string on stack contains a valid numeric representation, otherwise returns false. unsigned Cla$StackNUMERIC(void) Cla$StackNUMERIC(): CARDINAL;
The Clarion PRESS statement. Pushes every character in the topmost string of the stack into the Windows keyboard buffer. void Cla$StackPRESS(void) Cla$StackPRESS();
186
Cla$StackRIGHT
The Clarion RIGHT() procedure. Replaces the topmost item on the stack with its right justified equivalent. The replacement string will have a length of len characters. void Cla$StackRIGHT(unsigned len) Cla$StackRIGHT(len: CARDINAL); len: An unsigned integer
C++: Modula-2:
Cla$StackSUB
The Clarion SUB() procedure. Replaces the topmost string on the stack with a sub slice of the string starting at character position pos and of length len. void Cla$StackSUB(unsigned pos, unsigned len) Cla$StackSUB(pos, len: CARDINAL); pos: len: An unsigned integer; the start position of the sub string An unsigned integer; the length of the sub string
C++: Modula-2:
The Clarion VAL() procedure. Returns the ANSI value of the first character of the topmost string of the stack. unsigned char Cla$StackVAL(void) Cla$StackVAL(): BYTE;
Replace the topmost string on the stack with its uppercase equivalent. void Cla$StackUPPER(void) Cla$StackUPPER();
187
Conversion Functions
Please note that some of the following functions require pointers to null terminated strings as parameters. Modula-2 programmers should use the Modula library procedure Str.StrToC to convert strings to null terminated equivalents. Also, the pragma call(o_a_size=>off, o_a_copy=>off) must be issued to prevent the passing of array size information to the run-time procedures.
Convert string to floating point. double atof(const char *_nptr) atof( VAR _nptr: ARRAY OF CHAR): LONGREAL; AToF(*cstring),real,raw,name('_atof')
Convert string to integer. int atoi(const char *_nptr) atoi(VAR _nptr: ARRAY OF CHAR): INTEGER; AToI(*cstring),short,raw,name('_atoi')
188 atol C++: Modula-2: Clarion: Convert string to long. long atol(const char *_nptr)
Convert string to unsigned long. unsigned long atoul(const char *_nptr) atoul(VAR _nptr: ARRAY OF CHAR): LONGCARD; AToUL(*cstring),ulong,raw,name('_atoul')
Integer Math
Integer absolute value. int abs(int _num) abs(_num: INTEGER): INTEGER; API_Abs(short),short,name('_abs') !Renamed to avoid conflict with Builtins.C
Long integer absolute value. long labs(long _j) labs(_i: LONGINT): LONGINT; LAbs(long),long,name('_labs')
189
The following functions have only been tested when implemented as functions. We do not advise defining _CT_MTF to implement the functions as macros.
Test and convert if uppercase. int tolower(int c) tolower(c: INTEGER): INTEGER; ToLower(short),short,name('_tolower')
Control character test function. int iscntrl(int c) iscntrl(c: INTEGER): INTEGER; IsCntrl(short),short,name('_iscntrl')
190 isdigit C++: Modula-2: Clarion: Numerics test function. int isdigit(int c) isdigit(c: INTEGER): INTEGER;
IsDigit(short),short,name('_isdigit')
Printable including space test function. int isprint(int c) isprint(c: INTEGER): INTEGER; IsPrint(short),short,name('_isprint')
Punctuation character test function. int ispunc(int c) ispunc(c: INTEGER): INTEGER; IsPunct(short),short,name('_ispunct')
Hex digit test function. int isxdigit(int c) isxdigit(c: INTEGER): INTEGER; IsXDigit(short),short,name('_isxdigit')
191
Utility Functions
Set pseudorandom seed with system time. void randomize(void) randomize() Randomize(),name('_randomize')
Set pseudorandom seed with specified number. void srand(unsigned _seed) srand(_seed: CARDINAL); SRand(ushort),name('_srand')
192
String Functions
strcat C++: Modula-2: Clarion: Concatenate two strings. char *strcat(char *_dest, const char *_source) Not available StrCat(*cstring,*cstring),cstring,raw,name('_strcat')
Compare two strings. int strcmp(const char *_s1, const char *_s2) Not available StrCmp(*cstring,*cstring),short,raw,name('_strcmp')
Compare two characters int chrcmp(char _c1, char _c2) chrcmp(_c1,_c2: CHAR): INTEGER; ChrCmp(byte,byte),short,name('_chrcmp')
strequ C++: Modula-2: Clarion: int strequ(const char *_s1, const char *_s2) Not available StrEqu(*cstring,*cstring),short,raw,name('_strequ')
Copy one string to another, return destination address. char *strcpy(char *_dest, const char *_source) Not available StrCpy(*cstring, *cstring), cstring, raw,| name('_strcpy')
193
Return string length. unsigned strlen(const char *_s) strlen(VAR _s: ARRAY OF CHAR): CARDINAL; StrLen(*cstring),ushort,raw,name('_strlen')
Find character in string. char *strchr(const char *_s, int _c) Not available StrChr(*cstring,short),cstring,raw,name('_strchr')
Finds one of a set of characters in string. unsigned strcspn(const char *_s1, const char *_s2) Not available StrCSpn(*cstring, *cstring), ushort, raw,| name('_strcspn')
Find first character with no match in given character set. unsigned strspn(const char *_s1, const char *_s2) Not available StrSpn(*cstring,*cstring),ushort,raw,name('_strspn')
Find first occurrence of substring in a string. char *strstr(const char *_s1, const char *_s2) Not available StrStr(*cstring,*cstring),cstring,raw,name('_strstr')
194
Find next token in string. char *strtok(char *_s1, const char *_s2) Not available StrTok(*cstring,*cstring),cstring,raw,name('_strtok')
Find first occurrence of character. char *strpbrk(const char *_s1, const char *_s2) Not available StrPBrk(*cstring, *cstring), cstring, raw,| name('_strpbrk')
Find last occurrence of character. char *strrchr(const char *_s, int _c) Not available StrRChr(*cstring,short),cstring,raw,name('_strrchr')
195
Concatenate n characters. char *strncat(char *_dest, const char *_source, unsigned _n) Not available StrNCat(*cstring, *cstring, ushort), cstring, raw,| name('_strncat')
Compare n characters. int strncmp(const char *_s1, const char *_s2, unsigned _n) Not available StrNCmp(*cstring, *cstring, ushort), short, raw,| name('_strncmp')
Copy n characters. char * strncpy(char *_dest, const char *_source, unsigned _n) Not available StrNCpy(*cstring, *cstring, ushort), cstring, raw,| name('_strncpy')
196
Compare n characters regardless of case. int stricmp(const char *_s1, const char *_s2, unsigned _n) Not available StrNICmp(*cstring, *cstring, ushort), short, raw,| name('_strnicmp')
197
Set files access mode. int _chmod(const char *path, int mode) _chmod(VAR path: ARRAY OF CHAR; mode: INTEGER): INTEGER; ChMod(*cstring,short),short,raw,name('_chmod')
Deletes the file specified by the path parameter. int _remove(const char *_path) _remove(VAR _path: ARRAY OF CHAR): INTEGER; API_Remove(*cstring),short,raw,name('_remove') !Renamed to avoid conflict with Builtins.Clw
Changes the name of the file or directory specified by the oldname parameter. int _rename(const char *_oldname, const char *_newname) _rename(VAR _oldname, VAR _newname: ARRAY OF CHAR): INTEGER; API_Rename(*cstring, *cstring), short, raw,| name('_rename') !Renamed to avoid conflict with Builtins.Clw
Advanced Topics & Reference Guide Builds a complete path name from its component parts -- drive, directory, filename, and extension. void _fnmerge(char *_path, const char *_drive, const char *_dir, const char *_name, const char *_ext) _fnmerge(VAR _path, VAR _drive, VAR _dir, VAR _name, VAR _ext: ARRAY OF CHAR); FnMerge(*cstring, *cstring, *cstring, *cstring,| *cstring), raw, name('_fnmerge')
This function breaks a complete path name into its component parts -drive, directory, filename, and extension. int _fnsplit(const char *_path, char *_drive, char *_dir, char *_name, char *_ext) _fnsplit(VAR_path,VAR _drive,VAR _dir,VAR _name,VAR _ext:ARRAY OF CHAR):INTEGER; FnSplit(*cstring, *cstring, *cstring, *cstring,| *cstring), short, raw, name('_fnsplit')
Creates a new directory with the name passed in the path parameter. int _mkdir(const char *_path) _mkdir(VAR _path: ARRAY OF CHAR): INTEGER; MkDir(*cstring),short,raw,name('_mkdir')
removes the directory specified in the path parameter. int _rmdir(const char *_path) _rmdir(VAR _path: ARRAY OF CHAR):INTEGER; RmDir(*cstring),short,raw,name('_rmdir')
API Calls and Advanced Programming chdir C++: Modula-2: Clarion: Change directory. int _chdir(const char *_path) _chdir(VAR _path: ARRAY OF CHAR): INTEGER; ChDir(*cstring),short,raw,name('_chdir')
199
200
Index
201
Index:
#pragma... 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113 _C60_ ......................................................114 _CWVER_ ...............................................114 Basic Compiling and Linking .....................66 BeginUnique ..............................................18 BLOBTOFILE ............................................19 BYTETOHEX .............................................20 Clarion Language Utilities..........................17 Commonly Used Equates..........................42 Compiler Integration ................................140 Conditional Processing and Flow Control .71 Create a directory ......................................21 CreateDirectory .........................................21 Dictionary Class.........................................13 DLL Initialization ..........................................7 EndUnique .................................................22 Equates......................................................42 Error Managers..........................................12 FileExists ...................................................23 FILETOBLOB ............................................24 FullDrag .....................................................25 GetFileDate ...............................................26 GetFileTime ...............................................27 GETREG....................................................28 GetTempFileName ....................................29 GetTempPath ............................................30 GetUserName............................................31 Introduction ................................................59 IsTermServer .............................................32 Launching a thread - behind the scenes ...15 LONGTOHEX ............................................33 MANIFEST...............................................134 Multi Language Programming .................139 Overview ..................................................139 Programming Considerations ..................164 Project System Examples........................115 Project System Macros..............................64 PROP WindowsVersion ....................................34 Prototypes and Declarations....................169 Prototyping 3GL Functions in Clarion......153 PUTREG ....................................................35 Remove a directory....................................37 RemoveDirectory .......................................37 RESIZEIMAGE ..........................................38 Resolving Data Types..............................142 SHORTTOHEX ..........................................39 Threading...................................................14 ValidateOLE...............................................40 WindowExists ............................................41 WindowsVersion ........................................34
202