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>)
2. Invoke preprocessing as needed
Xbase++:
PreProcessLine(<input>, @<output>) //  and related API functions
3. Cleanup and release resources
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