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:
parent
3e68059556
commit
d875891a3c
4 changed files with 13184 additions and 257 deletions
6668
parser/raylib_api.json
Normal file
6668
parser/raylib_api.json
Normal file
File diff suppressed because it is too large
Load diff
3568
parser/raylib_api.txt
Normal file
3568
parser/raylib_api.txt
Normal file
File diff suppressed because it is too large
Load diff
2509
parser/raylib_api.xml
Normal file
2509
parser/raylib_api.xml
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue