Artistic Style can be compiled as a shared library (DLL) or a static library and linked with an Objective‑C program. This is usually done on a Mac OS computer. However, Objective‑C on Windows and Linux contains information on compiling and running Objective‑C programs using GNUstep. It has instructions for compiling the following example program on Windows or Linux.
To compile AStyle for use with an Objective‑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.
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.
NSZoneMalloc is typically used to allocate variable sized memory. An error in this results in a NSMallocException. This means that exception handling must be used to catch the error. If instead, a “C” malloc function is used, the error results in a NULL return. In this case it simplifies the error handling since the NULL is simply returned to AStyle. The example program uses malloc instead of NSZoneMalloc.
A NSZoneMalloc 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.
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.m /* This program calls the Artistic Style formatter (AStyleMain) * to format the astyle source files in a test-data directory. */ #include <Foundation/Foundation.h> // allow for different calling conventions in Linux and Windows #ifdef _WIN32 #define STDCALL __stdcall #else #define STDCALL #endif // functions to call AStyleMain char* STDCALL AStyleGetVersion(); char* STDCALL AStyleMain(const char* pSourceIn, const char* pOptions, 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(NSString* message) __attribute__((noreturn)); NSString* getProjectDirectory(const NSString* subPath); NSString* getText(NSString* filePath); void setText(const NSString* textOut, NSString* filePath); // Main function for this example. int main() { #if __has_feature(objc_arc) // clang directive @autoreleasepool #else NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; #endif { // options to pass to AStyle const NSArray* fileNames = [NSArray arrayWithObjects: @"AStyleDev/test-data/ASBeautifier.cpp", @"AStyleDev/test-data/ASFormatter.cpp", @"AStyleDev/test-data/astyle.h", nil]; const NSString* options = @"-A2tOP"; // get Artistic Style version const char* versionChar = AStyleGetVersion(); NSLog(@"Example Obj-C - AStyle %s", versionChar); // process the input files for (NSString* fileName in fileNames) { // get the text to format NSString* filePath = getProjectDirectory(fileName); NSString* textIn = getText(filePath); // call the Artistic Style formatting function char* textOutChar = AStyleMain([textIn UTF8String], [options UTF8String], ASErrorHandler, ASMemoryAlloc); // does not need to terminate on an error // an error message has been displayed by the error handler if (textOutChar == NULL) error([NSString stringWithFormat: @"Cannot format %@", fileName]); // return the formatted text NSString* textOut = [NSString stringWithUTF8String: textOutChar]; NSLog(@"Formatted %@", fileName); setText(textOut, filePath); // free the buffer allocated with malloc // Malloc is used instead of NSZoneMalloc to simplify the error handling. // Malloc errors result in a NULL return instead of a NSMallocException. free(textOutChar); textOutChar = NULL; } // system("pause"); } #if !__has_feature(objc_arc) // clang directive [pool drain]; #endif return EXIT_SUCCESS; } // Error handler for the Artistic Style formatter. void STDCALL ASErrorHandler(int errorNumber, const char* errorMessage) { NSLog(@"astyle error %d", errorNumber); NSLog(@"%s", errorMessage); } // Allocate memory for the Artistic Style formatter. // Malloc is used instead of NSZoneMalloc to simplify the error handling. // Malloc errors result in a NULL return instead of a NSMallocException. char* STDCALL ASMemoryAlloc(unsigned long memoryNeeded) { char* buffer = malloc(memoryNeeded); return buffer; } // Error message function for this example. void error(NSString* message) { NSLog(@"%@", message); NSLog(@"The program has terminated!"); exit(EXIT_FAILURE); } // Prepend the project directory to the subpath. // This may need to be changed for your directory structure. NSString* getProjectDirectory(const NSString* subPath) { #ifdef _WIN32 char* homeDirectoryChar = getenv("USERPROFILE"); #else char* homeDirectoryChar = getenv("HOME"); #endif if (!homeDirectoryChar) error(@"Cannot find HOME directory"); NSString* homeDirectory = [NSString stringWithCString: homeDirectoryChar encoding: [NSString defaultCStringEncoding]]; NSString* projectPath = [NSString stringWithFormat: @"%@/%@/%@", homeDirectory, @"Projects", subPath]; return projectPath; } // Get the text to be formatted and convert to a NSString. // Usually the text would be obtained from an edit control. NSString* getText(NSString* filePath) { NSString* textIn = [NSString stringWithContentsOfFile: filePath encoding: NSASCIIStringEncoding error: NULL]; if (!textIn) error([NSString stringWithFormat: @"Cannot open input file %@", filePath]); return textIn; } // Return the formatted text. // Usually the text would be returned to an edit control. void setText(const NSString* textOut, NSString* filePath) { // create a backup file NSFileManager* fm = [NSFileManager defaultManager]; NSString* origfilePath = [NSString stringWithFormat: @"%@%@", filePath, @".orig"]; if ([fm fileExistsAtPath: origfilePath]) [fm removeItemAtPath: origfilePath error: NULL]; if (![fm moveItemAtPath: filePath toPath: origfilePath error: NULL]) NSLog(@"Cannot create backup for %@", filePath); // write the text [textOut writeToFile: filePath atomically: YES encoding: NSASCIIStringEncoding error: NULL]; }