Improved raylib parser to export data as XML

- Improved command-line
 - Added XML support
 - Added sample outputs: DEFAULT, JSON, XML
 - Reviewed LoadFileText() bug
 - Removed trailing spaces
This commit is contained in:
Ray 2021-06-13 16:34:51 +02:00
parent 3e68059556
commit d875891a3c
4 changed files with 13184 additions and 257 deletions

6668
parser/raylib_api.json Normal file

File diff suppressed because it is too large Load diff

3568
parser/raylib_api.txt Normal file

File diff suppressed because it is too large Load diff

2509
parser/raylib_api.xml Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,9 @@
/**********************************************************************************************
raylib parser - raylib header parser
raylib API parser
This parser scans raylib.h to get information about structs, enums and functions.
All data is separated into parts, usually as strings. The following types are used for data:
This parser scans raylib.h to get API information about structs, enums and functions.
All data is divided into pieces, usually as strings. The following types are used for data:
- struct FunctionInfo
- struct StructInfo
@ -38,13 +38,15 @@
<valueName[3]> <valueDesc[3]>
} <name>;
NOTE: Multiple options are supported:
NOTE: Multiple options are supported for enums:
- If value is not provided, (<valueInteger[i -1]> + 1) is assigned
- Value description can be provided or not
This parser could work with other C header files if mentioned constraints are followed.
OTHER NOTES:
This parser does not require <string.h> library, all data is parsed directly from char buffers.
- This parser could work with other C header files if mentioned constraints are followed.
- This parser does not require <string.h> library, all data is parsed directly from char buffers.
LICENSE: zlib/libpng
@ -55,6 +57,8 @@
**********************************************************************************************/
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h> // Required for: malloc(), calloc(), realloc(), free(), atoi(), strtol()
#include <stdio.h> // Required for: printf(), fopen(), fseek(), ftell(), fread(), fclose()
#include <stdbool.h> // Required for: bool
@ -66,8 +70,6 @@
#define MAX_LINE_LENGTH 512 // Maximum length of one line (including comments)
#define MAX_STRUCT_LINE_LENGTH 2048 // Maximum length of one struct (multiple lines)
enum OutputFormat { PlainText, JSON }; // Which format the header information should be in
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
@ -79,6 +81,7 @@ typedef struct FunctionInfo {
int paramCount; // Number of function parameters
char paramType[12][32]; // Parameters type (max: 12 parameters)
char paramName[12][32]; // Parameters name (max: 12 parameters)
char paramDesc[12][8]; // Parameters description (max: 12 parameters)
} FunctionInfo;
// Struct info data
@ -101,54 +104,65 @@ typedef struct EnumInfo {
char valueDesc[128][64]; // Value description (max: 128 values)
} EnumInfo;
// Output format for parsed data
typedef enum { DEFAULT = 0, JSON, XML } OutputFormat;
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
static int funcCount = 0;
static int structCount = 0;
static int enumCount = 0;
static FunctionInfo *funcs = NULL;
static StructInfo *structs = NULL;
static EnumInfo *enums = NULL;
// Command line variables
static char inFileName[512] = { 0 }; // Input file name (required in case of provided through CLI)
static char outFileName[512] = { 0 }; // Output file name (required for file save/export)
static int outputFormat = DEFAULT;
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
char *LoadFileText(const char *fileName, int *length);
char **GetTextLines(const char *buffer, int length, int *linesCount);
void GetDataTypeAndName(const char *typeName, int typeNameLen, char *type, char *name);
bool IsTextEqual(const char *text1, const char *text2, unsigned int count);
void MemoryCopy(void *dest, const void *src, unsigned int count);
char* CharReplace(char* text, char search, char replace);
static void ShowCommandLineInfo(void); // Show command line usage info
static void ProcessCommandLine(int argc, char *argv[]); // Process command line input
// Main entry point
static char *LoadFileText(const char *fileName, int *length);
static char **GetTextLines(const char *buffer, int length, int *linesCount);
static void GetDataTypeAndName(const char *typeName, int typeNameLen, char *type, char *name);
static unsigned int TextLength(const char *text); // Get text length in bytes, check for \0 character
static bool IsTextEqual(const char *text1, const char *text2, unsigned int count);
static void MemoryCopy(void *dest, const void *src, unsigned int count);
static char* CharReplace(char* text, char search, char replace);
static void ExportParsedData(const char *fileName, int format); // Export parsed data in desired format
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
// Help
if (argv[1] != NULL && IsTextEqual(argv[1], "--help", 6)) {
printf("Usage:\n");
printf(" raylib_parser [--json]\n");
return 0;
}
if (argc > 1) ProcessCommandLine(argc, argv);
// Allow changing the output format.
int outputFormat = 0;
if (argv[1] != NULL && IsTextEqual(argv[1], "--json", 6)) {
outputFormat = JSON;
}
if (inFileName[0] == '\0') MemoryCopy(inFileName, "../src/raylib.h\0", 16);
int length = 0;
char *buffer = LoadFileText("../src/raylib.h", &length);
char *buffer = LoadFileText(inFileName, &length);
// Preprocess buffer to get separate lines
// NOTE: GetTextLines() also removes leading spaces/tabs
int linesCount = 0;
char **lines = GetTextLines(buffer, length, &linesCount);
// Print buffer lines
//for (int i = 0; i < linesCount; i++) printf("_%s_\n", lines[i]);
// Function lines pointers, selected from buffer "lines"
int funcCount = 0;
char **funcLines = (char **)malloc(MAX_FUNCS_TO_PARSE*sizeof(char *));
// Structs data (multiple lines), selected from "buffer"
int structCount = 0;
char **structLines = (char **)malloc(MAX_STRUCTS_TO_PARSE*sizeof(char *));
for (int i = 0; i < MAX_STRUCTS_TO_PARSE; i++) structLines[i] = (char *)calloc(MAX_STRUCT_LINE_LENGTH, sizeof(char));
// Enums lines pointers, selected from buffer "lines"
int enumCount = 0;
int *enumLines = (int *)malloc(MAX_ENUMS_TO_PARSE*sizeof(int));
// Prepare required lines for parsing
@ -166,9 +180,6 @@ int main(int argc, char* argv[])
}
}
// Print function lines
//for (int i = 0; i < funcCount; i++) printf("%s\n", funcLines[i]);
// Read structs data (multiple lines, read directly from buffer)
// TODO: Parse structs data from "lines" instead of "buffer" -> Easier to get struct definition
for (int i = 0; i < length; i++)
@ -245,7 +256,7 @@ int main(int argc, char* argv[])
//--------------------------------------------------------------------------------------------------
// Structs info data
StructInfo *structs = (StructInfo *)calloc(MAX_STRUCTS_TO_PARSE, sizeof(StructInfo));
structs = (StructInfo *)calloc(MAX_STRUCTS_TO_PARSE, sizeof(StructInfo));
for (int i = 0; i < structCount; i++)
{
@ -318,7 +329,7 @@ int main(int argc, char* argv[])
free(structLines);
// Enum info data
EnumInfo *enums = (EnumInfo *)calloc(MAX_ENUMS_TO_PARSE, sizeof(EnumInfo));
enums = (EnumInfo *)calloc(MAX_ENUMS_TO_PARSE, sizeof(EnumInfo));
for (int i = 0; i < enumCount; i++)
{
@ -401,7 +412,7 @@ int main(int argc, char* argv[])
}
// Functions info data
FunctionInfo *funcs = (FunctionInfo *)calloc(MAX_FUNCS_TO_PARSE, sizeof(FunctionInfo));
funcs = (FunctionInfo *)calloc(MAX_FUNCS_TO_PARSE, sizeof(FunctionInfo));
for (int i = 0; i < funcCount; i++)
{
@ -471,7 +482,7 @@ int main(int argc, char* argv[])
}
}
for (int i = 0; i < linesCount; i++) free(lines[i]);
//for (int i = 0; i < linesCount; i++) free(lines[i]);
free(lines);
free(funcLines);
@ -481,132 +492,16 @@ int main(int argc, char* argv[])
// enums[] -> We have all the enums decomposed into pieces for further analysis
// funcs[] -> We have all the functions decomposed into pieces for further analysis
// Print structs info
switch (outputFormat)
{
case PlainText: {
printf("\nStructures found: %i\n\n", structCount);
for (int i = 0; i < structCount; i++)
{
printf("Struct %02i: %s (%i fields)\n", i + 1, structs[i].name, structs[i].fieldCount);
//printf("Description: %s\n", structs[i].desc);
for (int f = 0; f < structs[i].fieldCount; f++) printf(" Fields %i: %s %s %s\n", f + 1, structs[i].fieldType[f], structs[i].fieldName[f], structs[i].fieldDesc[f]);
}
// Process input file to output
if (outFileName[0] == '\0') MemoryCopy(outFileName, "raylib_api.txt\0", 15);
// Print enums info
printf("\nEnums found: %i\n\n", enumCount);
for (int i = 0; i < enumCount; i++)
{
printf("Enum %02i: %s (%i values)\n", i + 1, enums[i].name, enums[i].valueCount);
//printf("Description: %s\n", enums[i].desc);
for (int e = 0; e < enums[i].valueCount; e++) printf(" Value %s: %i\n", enums[i].valueName[e], enums[i].valueInteger[e]);
}
printf("\nInput file: %s", inFileName);
printf("\nOutput file: %s", outFileName);
if (outputFormat == DEFAULT) printf("\nOutput format: DEFAULT\n\n");
else if (outputFormat == JSON) printf("\nOutput format: JSON\n\n");
else if (outputFormat == XML) printf("\nOutput format: XML\n\n");
// Print function info
printf("\nFunctions found: %i\n\n", funcCount);
for (int i = 0; i < funcCount; i++)
{
printf("Function %03i: %s() (%i input parameters)\n", i + 1, funcs[i].name, funcs[i].paramCount);
printf(" Description: %s\n", funcs[i].desc);
printf(" Return type: %s\n", funcs[i].retType);
for (int p = 0; p < funcs[i].paramCount; p++) printf(" Param %i: %s (type: %s)\n", p + 1, funcs[i].paramName[p], funcs[i].paramType[p]);
if (funcs[i].paramCount == 0) printf(" No input parameters\n");
}
} break;
case JSON: {
printf("{\n");
printf(" \"structs\": [\n");
for (int i = 0; i < structCount; i++)
{
printf(" {\n");
printf(" \"name\": \"%s\",\n", structs[i].name);
printf(" \"description\": \"%s\",\n", structs[i].desc);
printf(" \"fields\": [\n");
for (int f = 0; f < structs[i].fieldCount; f++)
{
printf(" {\n");
printf(" \"name\": \"%s\",\n", structs[i].fieldName[f]),
printf(" \"type\": \"%s\",\n", structs[i].fieldType[f]),
printf(" \"description\": \"%s\"\n", structs[i].fieldDesc[f] + 3),
printf(" }");
if (f < structs[i].fieldCount - 1)
printf(",\n");
else
printf("\n");
}
printf(" ]\n");
printf(" }");
if (i < structCount - 1)
printf(",\n");
else
printf("\n");
}
printf(" ],\n");
// Print enums info
printf(" \"enums\": [\n");
for (int i = 0; i < enumCount; i++)
{
printf(" {\n");
printf(" \"name\": \"%s\",\n", enums[i].name);
printf(" \"description\": \"%s\",\n", enums[i].desc + 3);
printf(" \"values\": [\n");
for (int e = 0; e < enums[i].valueCount; e++)
{
printf(" {\n");
printf(" \"name\": \"%s\",\n", enums[i].valueName[e]),
printf(" \"value\": %i,\n", enums[i].valueInteger[e]),
printf(" \"description\": \"%s\"\n", enums[i].valueDesc[e] + 3),
printf(" }");
if (e < enums[i].valueCount - 1)
printf(",\n");
else
printf("\n");
}
printf(" ]\n");
printf(" }");
if (i < enumCount - 1)
printf(",\n");
else
printf("\n");
}
printf(" ],\n");
// Print function info
printf(" \"functions\": [\n");
for (int i = 0; i < funcCount; i++)
{
printf(" {\n");
printf(" \"name\": \"%s\",\n", funcs[i].name);
printf(" \"description\": \"%s\",\n", CharReplace(funcs[i].desc, '\\', ' ') + 3);
printf(" \"returnType\": \"%s\"", funcs[i].retType);
if (funcs[i].paramCount == 0)
printf("\n");
else
{
printf(",\n \"params\": {\n");
for (int p = 0; p < funcs[i].paramCount; p++)
{
printf(" \"%s\": \"%s\"", funcs[i].paramName[p], funcs[i].paramType[p]);
if (p < funcs[i].paramCount - 1)
printf(",\n");
else
printf("\n");
}
printf(" }\n");
}
printf(" }");
if (i < funcCount - 1)
printf(",\n");
else
printf("\n");
}
printf(" ]\n");
printf("}\n");
} break;
}
ExportParsedData(outFileName, outputFormat);
free(funcs);
free(structs);
@ -616,10 +511,84 @@ int main(int argc, char* argv[])
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
// Show command line usage info
static void ShowCommandLineInfo(void)
{
printf("\n//////////////////////////////////////////////////////////////////////////////////\n");
printf("// //\n");
printf("// raylib API parser //\n");
printf("// //\n");
printf("// more info and bugs-report: github.com/raysan5/raylib/parser //\n");
printf("// //\n");
printf("// Copyright (c) 2021 Ramon Santamaria (@raysan5) //\n");
printf("// //\n");
printf("//////////////////////////////////////////////////////////////////////////////////\n\n");
printf("USAGE:\n\n");
printf(" > raylib_parser [--help] [--input <filename.h>] [--output <filename.ext>] [--format <type>]\n");
printf("\nOPTIONS:\n\n");
printf(" -h, --help : Show tool version and command line usage help\n\n");
printf(" -i, --input <filename.h> : Define input header file to parse.\n");
printf(" NOTE: If not specified, defaults to: raylib.h\n\n");
printf(" -o, --output <filename.ext> : Define output file and format.\n");
printf(" Supported extensions: .txt, .json, .xml, .h\n");
printf(" NOTE: If not specified, defaults to: raylib_api.txt\n\n");
printf(" -f, --format <type> : Define output format for parser data.\n");
printf(" Supported types: DEFAULT, JSON, XML\n\n");
printf("\nEXAMPLES:\n\n");
printf(" > raylib_parser --input raylib.h --output api.json\n");
printf(" Process <raylib.h> to generate <api.json>\n\n");
printf(" > raylib_parser --output raylib_data.info --format XML\n");
printf(" Process <raylib.h> to generate <raylib_data.info> as XML text data\n\n");
}
// Process command line arguments
static void ProcessCommandLine(int argc, char *argv[])
{
for (int i = 1; i < argc; i++)
{
if (IsTextEqual(argv[i], "-h", 2) || IsTextEqual(argv[i], "--help", 6))
{
// Show info
ShowCommandLineInfo();
}
else if (IsTextEqual(argv[i], "-i", 2) || IsTextEqual(argv[i], "--input", 7))
{
// Check for valid argument and valid file extension
if (((i + 1) < argc) && (argv[i + 1][0] != '-'))
{
MemoryCopy(inFileName, argv[i + 1], TextLength(argv[i + 1])); // Read input filename
i++;
}
else printf("WARNING: No input file provided\n");
}
else if (IsTextEqual(argv[i], "-o", 2) || IsTextEqual(argv[i], "--output", 8))
{
if (((i + 1) < argc) && (argv[i + 1][0] != '-'))
{
MemoryCopy(outFileName, argv[i + 1], TextLength(argv[i + 1])); // Read output filename
i++;
}
else printf("WARNING: No output file provided\n");
}
else if (IsTextEqual(argv[i], "-f", 2) || IsTextEqual(argv[i], "--format", 8))
{
if (((i + 1) < argc) && (argv[i + 1][0] != '-'))
{
if (IsTextEqual(argv[i + 1], "DEFAULT\0", 8)) outputFormat = DEFAULT;
else if (IsTextEqual(argv[i + 1], "JSON\0", 5)) outputFormat = JSON;
else if (IsTextEqual(argv[i + 1], "XML\0", 4)) outputFormat = XML;
}
else printf("WARNING: No format parameters provided\n");
}
}
}
// Load text data from file, returns a '\0' terminated string
// NOTE: text chars array should be freed manually
char *LoadFileText(const char *fileName, int *length)
static char *LoadFileText(const char *fileName, int *length)
{
char *text = NULL;
@ -638,14 +607,17 @@ char *LoadFileText(const char *fileName, int *length)
if (size > 0)
{
*length = size;
text = (char *)calloc((size + 1), sizeof(char));
unsigned int count = (unsigned int)fread(text, sizeof(char), size, file);
// WARNING: \r\n is converted to \n on reading, so,
// read bytes count gets reduced by the number of lines
if (count < (unsigned int)size) text = realloc(text, count + 1);
if (count < (unsigned int)size)
{
text = realloc(text, count + 1);
*length = count;
}
else *length = size;
// Zero-terminate the string
text[count] = '\0';
@ -659,15 +631,13 @@ char *LoadFileText(const char *fileName, int *length)
}
// Get all lines from a text buffer (expecting lines ending with '\n')
char **GetTextLines(const char *buffer, int length, int *linesCount)
static char **GetTextLines(const char *buffer, int length, int *linesCount)
{
//#define MAX_LINE_LENGTH 512
// Get the number of lines in the text
int count = 0;
for (int i = 0; i < length; i++) if (buffer[i] == '\n') count++;
//printf("Number of text lines in buffer: %i\n", count);
printf("Number of text lines in buffer: %i\n", count);
// Allocate as many pointers as lines
char **lines = (char **)malloc(count*sizeof(char **));
@ -699,7 +669,7 @@ char **GetTextLines(const char *buffer, int length, int *linesCount)
// Get data type and name from a string containing both
// NOTE: Useful to parse function parameters and struct fields
void GetDataTypeAndName(const char *typeName, int typeNameLen, char *type, char *name)
static void GetDataTypeAndName(const char *typeName, int typeNameLen, char *type, char *name)
{
for (int k = typeNameLen; k > 0; k--)
{
@ -719,8 +689,18 @@ void GetDataTypeAndName(const char *typeName, int typeNameLen, char *type, char
}
}
// Get text length in bytes, check for \0 character
static unsigned int TextLength(const char *text)
{
unsigned int length = 0;
if (text != NULL) while (*text++) length++;
return length;
}
// Custom memcpy() to avoid <string.h>
void MemoryCopy(void *dest, const void *src, unsigned int count)
static void MemoryCopy(void *dest, const void *src, unsigned int count)
{
char *srcPtr = (char *)src;
char *destPtr = (char *)dest;
@ -729,7 +709,7 @@ void MemoryCopy(void *dest, const void *src, unsigned int count)
}
// Compare two text strings, requires number of characters to compare
bool IsTextEqual(const char *text1, const char *text2, unsigned int count)
static bool IsTextEqual(const char *text1, const char *text2, unsigned int count)
{
bool result = true;
@ -746,7 +726,7 @@ bool IsTextEqual(const char *text1, const char *text2, unsigned int count)
}
// Search and replace a character within a string.
char* CharReplace(char* text, char search, char replace)
static char* CharReplace(char* text, char search, char replace)
{
for (int i = 0; text[i] != '\0'; i++)
if (text[i] == search)
@ -758,7 +738,7 @@ char* CharReplace(char* text, char search, char replace)
// Replace text string
// REQUIRES: strlen(), strstr(), strncpy(), strcpy() -> TODO: Replace by custom implementations!
// WARNING: Returned buffer must be freed by the user (if return != NULL)
char *TextReplace(char *text, const char *replace, const char *by)
static char *TextReplace(char *text, const char *replace, const char *by)
{
// Sanity checks and initialization
if (!text || !replace || !by) return NULL;
@ -805,3 +785,205 @@ char *TextReplace(char *text, const char *replace, const char *by)
return result;
}
*/
// Export parsed data in desired format
static void ExportParsedData(const char *fileName, int format)
{
FILE *outFile = fopen(fileName, "wt");
switch (format)
{
case DEFAULT:
{
// Print structs info
fprintf(outFile, "\nStructures found: %i\n\n", structCount);
for (int i = 0; i < structCount; i++)
{
fprintf(outFile, "Struct %02i: %s (%i fields)\n", i + 1, structs[i].name, structs[i].fieldCount);
fprintf(outFile, " Name: %s\n", structs[i].name);
fprintf(outFile, " Description: %s\n", structs[i].desc + 3);
for (int f = 0; f < structs[i].fieldCount; f++) fprintf(outFile, " Field[%i]: %s %s %s\n", f + 1, structs[i].fieldType[f], structs[i].fieldName[f], structs[i].fieldDesc[f]);
}
// Print enums info
fprintf(outFile, "\nEnums found: %i\n\n", enumCount);
for (int i = 0; i < enumCount; i++)
{
fprintf(outFile, "Enum %02i: %s (%i values)\n", i + 1, enums[i].name, enums[i].valueCount);
fprintf(outFile, " Name: %s\n", enums[i].name);
fprintf(outFile, " Description: %s\n", enums[i].desc + 3);
for (int e = 0; e < enums[i].valueCount; e++) fprintf(outFile, " Value[%s]: %i\n", enums[i].valueName[e], enums[i].valueInteger[e]);
}
// Print functions info
fprintf(outFile, "\nFunctions found: %i\n\n", funcCount);
for (int i = 0; i < funcCount; i++)
{
fprintf(outFile, "Function %03i: %s() (%i input parameters)\n", i + 1, funcs[i].name, funcs[i].paramCount);
fprintf(outFile, " Name: %s\n", funcs[i].name);
fprintf(outFile, " Return type: %s\n", funcs[i].retType);
fprintf(outFile, " Description: %s\n", funcs[i].desc + 3);
for (int p = 0; p < funcs[i].paramCount; p++) fprintf(outFile, " Param[%i]: %s (type: %s)\n", p + 1, funcs[i].paramName[p], funcs[i].paramType[p]);
if (funcs[i].paramCount == 0) fprintf(outFile, " No input parameters\n");
}
} break;
case JSON:
{
fprintf(outFile, "{\n");
// Print structs info
fprintf(outFile, " \"structs\": [\n");
for (int i = 0; i < structCount; i++)
{
fprintf(outFile, " {\n");
fprintf(outFile, " \"name\": \"%s\",\n", structs[i].name);
fprintf(outFile, " \"description\": \"%s\",\n", structs[i].desc);
fprintf(outFile, " \"fields\": [\n");
for (int f = 0; f < structs[i].fieldCount; f++)
{
fprintf(outFile, " {\n");
fprintf(outFile, " \"name\": \"%s\",\n", structs[i].fieldName[f]),
fprintf(outFile, " \"type\": \"%s\",\n", structs[i].fieldType[f]),
fprintf(outFile, " \"description\": \"%s\"\n", structs[i].fieldDesc[f] + 3),
fprintf(outFile, " }");
if (f < structs[i].fieldCount - 1) fprintf(outFile, ",\n");
else fprintf(outFile, "\n");
}
fprintf(outFile, " ]\n");
fprintf(outFile, " }");
if (i < structCount - 1) fprintf(outFile, ",\n");
else fprintf(outFile, "\n");
}
fprintf(outFile, " ],\n");
// Print enums info
fprintf(outFile, " \"enums\": [\n");
for (int i = 0; i < enumCount; i++)
{
fprintf(outFile, " {\n");
fprintf(outFile, " \"name\": \"%s\",\n", enums[i].name);
fprintf(outFile, " \"description\": \"%s\",\n", enums[i].desc + 3);
fprintf(outFile, " \"values\": [\n");
for (int e = 0; e < enums[i].valueCount; e++)
{
fprintf(outFile, " {\n");
fprintf(outFile, " \"name\": \"%s\",\n", enums[i].valueName[e]),
fprintf(outFile, " \"value\": %i,\n", enums[i].valueInteger[e]),
fprintf(outFile, " \"description\": \"%s\"\n", enums[i].valueDesc[e] + 3),
fprintf(outFile, " }");
if (e < enums[i].valueCount - 1) fprintf(outFile, ",\n");
else fprintf(outFile, "\n");
}
fprintf(outFile, " ]\n");
fprintf(outFile, " }");
if (i < enumCount - 1) fprintf(outFile, ",\n");
else fprintf(outFile, "\n");
}
fprintf(outFile, " ],\n");
// Print functions info
fprintf(outFile, " \"functions\": [\n");
for (int i = 0; i < funcCount; i++)
{
fprintf(outFile, " {\n");
fprintf(outFile, " \"name\": \"%s\",\n", funcs[i].name);
fprintf(outFile, " \"description\": \"%s\",\n", CharReplace(funcs[i].desc, '\\', ' ') + 3);
fprintf(outFile, " \"returnType\": \"%s\"", funcs[i].retType);
if (funcs[i].paramCount == 0) fprintf(outFile, "\n");
else
{
fprintf(outFile, ",\n \"params\": {\n");
for (int p = 0; p < funcs[i].paramCount; p++)
{
fprintf(outFile, " \"%s\": \"%s\"", funcs[i].paramName[p], funcs[i].paramType[p]);
if (p < funcs[i].paramCount - 1) fprintf(outFile, ",\n");
else fprintf(outFile, "\n");
}
fprintf(outFile, " }\n");
}
fprintf(outFile, " }");
if (i < funcCount - 1) fprintf(outFile, ",\n");
else fprintf(outFile, "\n");
}
fprintf(outFile, " ]\n");
fprintf(outFile, "}\n");
} break;
case XML:
{
// XML format to export data:
/*
<?xml version="1.0" encoding="Windows-1252" ?>
<raylibAPI>
<Structs count="">
<Struct name="" fieldCount="" desc="">
<Field type="" name="" desc="">
<Field type="" name="" desc="">
</Struct>
<Structs>
<Enums count="">
<Enum name="" valueCount="" desc="">
<Value name="" integer="" desc="">
<Value name="" integer="" desc="">
</Enum>
</Enums>
<Functions count="">
<Function name="" retType="" paramCount="" desc="">
<Param type="" name="" desc="" />
<Param type="" name="" desc="" />
</Function>
</Functions>
</raylibAPI>
*/
fprintf(outFile, "<?xml version=\"1.0\" encoding=\"Windows-1252\" ?>\n");
fprintf(outFile, "<raylibAPI>\n");
// Print structs info
fprintf(outFile, " <Structs count=\"%i\">\n", structCount);
for (int i = 0; i < structCount; i++)
{
fprintf(outFile, " <Struct name=\"%s\" fieldCount=\"%i\" desc=\"%s\">\n", structs[i].name, structs[i].fieldCount, structs[i].desc + 3);
for (int f = 0; f < structs[i].fieldCount; f++)
{
fprintf(outFile, " <Field type=\"%s\" name=\"%s\" desc=\"%s\" />\n", structs[i].fieldType[f], structs[i].fieldName[f], structs[i].fieldDesc[f] + 3);
}
fprintf(outFile, " </Struct>\n");
}
fprintf(outFile, " </Structs>\n");
// Print enums info
fprintf(outFile, " <Enums count=\"%i\">\n", enumCount);
for (int i = 0; i < enumCount; i++)
{
fprintf(outFile, " <Enum name=\"%s\" valueCount=\"%i\" desc=\"%s\">\n", enums[i].name, enums[i].valueCount, enums[i].desc + 3);
for (int v = 0; v < enums[i].valueCount; v++)
{
fprintf(outFile, " <Value name=\"%s\" integer=\"%i\" desc=\"%s\" />\n", enums[i].valueName[v], enums[i].valueInteger[v], enums[i].valueDesc[v] + 3);
}
fprintf(outFile, " </Enum>\n");
}
fprintf(outFile, " </Enums>\n");
// Print functions info
fprintf(outFile, " <Functions count=\"%i\">\n", funcCount);
for (int i = 0; i < funcCount; i++)
{
fprintf(outFile, " <Function name=\"%s\" retType=\"%s\" paramCount=\"%i\" desc=\"%s\">\n", funcs[i].name, funcs[i].retType, funcs[i].paramCount, funcs[i].desc + 3);
for (int p = 0; p < funcs[i].paramCount; p++)
{
fprintf(outFile, " <Param type=\"%s\" name=\"%s\" desc=\"%s\" />\n", funcs[i].paramType[p], funcs[i].paramName[p], funcs[i].paramDesc[p] + 3);
}
fprintf(outFile, " </Function>\n");
}
fprintf(outFile, " </Functions>\n");
fprintf(outFile, "</raylibAPI>\n");
} break;
default: break;
}
fclose(outFile);
}