Artistic Style can be compiled as a shared library (DLL) or a static library and linked with a C or C++ program.
To compile AStyle for use with a C or C++ program the compile option ASTYLE_LIB must be defined. Then AStyle will accept the files and options as parameters from a function call. It is the responsibility of the calling program to read the source files and accept the options from the user via a graphical interface or other method. These are then passed via the function call. After the source files are formatted they will be returned to the calling program, which must then save the source file and take other appropriate action.
Visual Studio users can also use the option ASTYLE_NO_VCX (no Visual C exports) to remove the __declspec(dllexport) definition from Visual C. Use this only for static libraries or when the AStyle source is included in the compile. Do NOT use this when compiled as a shared (dynamic) library. It is effective only for Visual Studio 2012 and higher. It will NOT work with previous versions. It has no effect with other compilers since they require a separate option to create the import library and export files.
The source can also be included in a program or another shared library (DLL) instead of being compiled by itself. It should be compiled with the options ASTYLE_LIB (and ASTYLE_NO_VCX for Visual C) to get the function call instead of the console build. Then include it with the other source modules and call it using the AStyleMain function.
This function is called to format the source code.
extern "C" char* STDCALL AStyleMain(const char* pSourceIn, const char* pOptions, void (STDCALL* fpError)(int, char*), char* (STDCALL* fpAlloc)(unsigned long));
pSourceIn
A pointer to the source file to be formatted.
pOptions
A pointer to the formatting options. They should be in the same format as in the default options file. The options
may be set apart by new-lines, commas, tabs or spaces. The long options do not need the "--" prefix. Comments
may be used but they must be terminated by a new-line "\n" character.
If the file is not a C/C++ file, the file mode option "mode=java" or "mode=cs" must be included. Otherwise the default mode of C/C++ is used.
fpError
A pointer to the error handling function. If there are errors in the parameters pSourceIn
or pOptions, this function is called. It should display an error message and then either abort or continue the
program depending on the error. The first parameter is a number identifying the error. The second parameter is
a pointer to a standard error message.
Error messages numbered 100-199 are errors that prevent the file from being formatted. A NULL pointer is returned to the calling program. Error messages numbered 200-299 are errors that do NOT prevent the file from being formatted. A valid pointer and a formatted file are returned. This will occur if an invalid option is sent to AStyleMain. The calling program has the option of accepting or rejecting the formatted file.
fpAlloc
A pointer to the memory allocation function. The calling program must allocate memory for
the output source file. This function will be called when the memory is needed. The parameter is the amount of
memory that should be allocated.
Memory should be allocated using the operator "new (nothrow)". With this method, if there is an allocation exception, Artistic Style will generate an error message and return a NULL pointer from the AStyleMain function. The calling program can handle the exception at this point rather than in the memory allocation function. See the following example program for the procedure.
A "new" without "(nothrow)" can be used if you want, but do not abort the program in the memory allocation function. An error message may be printed but return a NULL pointer to AStyle and handle the error when AStyle returns from formatting the text.
The calling program is responsible for freeing the allocated memory when it is no longer needed.
If the function succeeds, the return value is a pointer to the formatted source code.
If the function fails, the return value is NULL. Before the NULL is returned, an error message will be sent to the error handling function.
This function typically fails for one of the following reasons:
The function will NOT fail for an invalid option in the formatting options. In this case, an error message is sent to the error handling function and the formatted source code is returned without using the invalid option.
The STDCALL macro is defined for Windows as __stdcall. It is needed if AStyle is compiled as a Windows shared library (DLL). For Linux, it is defined but does not have a value.
The calling program is responsible for freeing the memory allocated by fpAlloc when it is no longer needed.
This function is called to get the Artistic Style version number.
extern "C" char* STDCALL AStyleGetVersion();
A pointer to the Artistic Style version number.
The STDCALL macro is defined for Windows as __stdcall. It is needed if AStyle is compiled as a Windows shared library (DLL). For Linux it is defined but does not have a value.
The following example formats source files by calling the Artistic Style formatter. It is a console application, but the procedure for a GUI is the same. The example can be copied and pasted into a source file. Or it can be downloaded with test data from the "Developer Information" page. The source code for Artistic Style must be added as a shared library (DLL), a static library, or included with the example source.
// Example.cpp /* This program calls the Artistic Style formatter (AStyleMain) * to format the astyle source files in a test-data directory. */ #include <stdlib.h> #include <string> #include <fstream> #include <iostream> #if defined(__GNUC__) #include <string.h> // need both string and string.h for GCC #endif using namespace std; // allow for different calling conventions in Linux and Windows #ifdef _WIN32 #define STDCALL __stdcall #else #define STDCALL #endif // functions to call AStyleMain extern "C" const char* STDCALL AStyleGetVersion(void); extern "C" char* STDCALL AStyleMain(const char* sourceIn, const char* optionsIn, void (STDCALL* fpError)(int, const char*), char* (STDCALL* fpAlloc)(unsigned long)); void STDCALL ASErrorHandler(int errorNumber, const char* errorMessage); char* STDCALL ASMemoryAlloc(unsigned long memoryNeeded); // other functions void error(const string message); string getProjectDirectory(const string& subPath); char* getText(const string& filePath); void setText(const char* textOut, const string& filePathStr); // Main function for this example. int main(int, char**) { // options to pass to AStyle const string fileName[] = { "AStyleDev/test-data/ASBeautifier.cpp", "AStyleDev/test-data/ASFormatter.cpp", "AStyleDev/test-data/astyle.h" }; const char* options = "-A2tOP"; size_t arraySize = sizeof(fileName) / sizeof(fileName[0]); // get Artistic Style version const char* version = AStyleGetVersion(); cout << "Example C++ - AStyle " << version << endl; // process the input files for (size_t i = 0; i < arraySize; i++) { // get the text to format string filePath = getProjectDirectory(fileName[i]); char* textIn = getText(filePath); // call the Artistic Style formatting function char* textOut = AStyleMain(textIn, options, ASErrorHandler, ASMemoryAlloc); // does not need to terminate on an error // an error message has been displayed by the error handler if (textOut == NULL) error(string("Cannot format " + filePath)); // return the formatted text cout << "Formatted " << fileName[i] << endl; setText(textOut, filePath); // must delete the temporary buffers delete [] textIn; delete [] textOut; } // system("pause"); return EXIT_SUCCESS; } // Error handler for the Artistic Style formatter. void STDCALL ASErrorHandler(int errorNumber, const char* errorMessage) { cout << "astyle error " << errorNumber << "\n" << errorMessage << endl; } // Allocate memory for the Artistic Style formatter. char* STDCALL ASMemoryAlloc(unsigned long memoryNeeded) { // error condition is checked after return from AStyleMain char* buffer = new (nothrow) char [memoryNeeded]; return buffer; } // Error message function for this example. void error(string message) { cout << message << endl; cout << "The program has terminated!" << endl; exit(EXIT_FAILURE); } // Prepend the project directory to the subpath. // This may need to be changed for your directory structure. string getProjectDirectory(const string& subPath) { #ifdef _WIN32 char* homeDirectory = getenv("USERPROFILE"); #else char* homeDirectory = getenv("HOME"); #endif if (!homeDirectory) error("Cannot find HOME directory"); string projectPath = string(homeDirectory) + "/Projects/" + subPath; return projectPath; } // Get the text to be formatted. // Usually the text would be obtained from an edit control. char* getText(const string& filePath) { // open input file ifstream in(filePath.c_str()); if (!in) error("Cannot open input file " + filePath); // get length of buffer const int bufferSizeIn = 131072; // 128 KB // allocate memory char* bufferIn = new (nothrow) char [bufferSizeIn]; if (bufferIn == NULL) { in.close(); error("Memory allocation failure on input"); } // read data as a block in.read(bufferIn, bufferSizeIn); // get actual size - must be smaller than buffer size int textSizeIn = static_cast<int>(in.gcount()); if (textSizeIn > bufferSizeIn) { in.close(); error("Read buffer is too small"); } bufferIn[textSizeIn] = '\0'; in.close(); return bufferIn; } // Return the formatted text. // Usually the text would be returned to an edit control. void setText(const char* textOut, const string& filePathStr) { // create a backup file const char* filePath = filePathStr.c_str(); string origfilePathStr = filePathStr + ".orig"; const char* origfilePath = origfilePathStr.c_str(); remove(origfilePath); // remove a pre-existing file if (rename(filePath, origfilePath) < 0) error("Cannot open input file " + filePathStr); // open the output file ofstream out(filePath); if (!out) error("Cannot open output file " + filePathStr); // write the text size_t textSizeOut = strlen(textOut); out.write(textOut, static_cast<streamsize>(textSizeOut)); out.close(); }