Purpose
This package contains a source code sample demonstrating the Alaska Xbase++ PreProcessor API. The API exposes the compiler preprocessor to Xbase++ applications, enabling runtime use of preprocessor features such as:- Expanding #define values
- Applying "#command/#translate rules from command header files (for example, converting SET INDEX TO ... into its function-based equivalent)
What’s included
The accompanying ZIP archive ppapi.zip contains:- A buildable Xbase++ project
- A minimal example showing how to:
- Install/select a command set (e.g. "std.ch")
- Preprocess an input line into expanded code
- Uninstall/cleanup the preprocessor
Prerequisites
- Alaska Xbase++ installed
- Access to the PreProcessor API header and library:
- Header: xpppp.ch
- Library: aspapib.lib (linked via #pragma in the sample)
Usage pattern
The intended call sequence is:1. Install the preprocessor and load command definitions
Xbase++:
PreProcessorInstall(<command-header>)
Xbase++:
PreProcessLine(<input>, @<output>) // and related API functions
Xbase++:
PreProcessorUninstall()
Example
The following program preprocesses a SET INDEX TO ... command and returns the expanded function-based code. It also demonstrates splitting a multi-statement expansion into separate lines.
Xbase++:
#include "xpppp.ch"
#pragma library("aspapib.lib")
PROCEDURE Main()
LOCAL cMulti
LOCAL aLines
LOCAL cInput
IF PreprocessorInstall("std.ch") != XPP_ERR_NONE
QUIT
ENDIF
cInput := "SET INDEX TO ( cAppPath + cNtxName )"
PreProcessLine(cInput, @cMulti)
? cMulti
// cMulti should now contain:
// "ordListClear() ;ordListAdd( ( cAppPath + cNtxName ) )"
? aLines := PPSplitLine(cMulti)
// aLines now contains two elements:
// aLines[1] => "ordListClear() "
// aLines[2] => "ordListAdd( ( cAppPath + cNtxName ) )"
PreprocessorUninstall()
RETURN
Notes / troubleshooting
- If PreProcessorInstall() fails, verify that the command header file (e.g. "std.ch") is accessible via your include paths.
- The preprocessor may expand a single input command into multiple statements separated by semicolons; use PPSplitLine() (or equivalent tooling) if you need statement-level processing.
- Always call PreProcessorUninstall() to avoid leaking resources or leaving the preprocessor in an installed state for subsequent operations.
Intended use cases
This sample is suitable as a starting point for tools that need to:- Inspect preprocessor results programmatically
- Convert command syntax into the underlying function calls for analysis, logging, code generation, or refactoring helpers
- Build lightweight “explain/expand” utilities for developers working with command-heavy codebases