From df6caea25db9c9fdf9a9040f853a87fbe1c7867f Mon Sep 17 00:00:00 2001
From: lazaray <104470294+lazaray@users.noreply.github.com>
Date: Wed, 4 May 2022 11:06:01 +0200
Subject: [PATCH] Parser improvements (#2461)
* Fix parser function description detection
Some functions in easings.h are defined on a single line and include a
division which was mistaken for the start of the description.
* Fix parser detection of macros including spaces
* Add support for self-referencing structs to parser
* Fix parser code style
* Fix parser handling of multiple fields on one line
* Increase parser MAX_STRUCT_FIELDS
For internal rlglData State struct (internal structs are still not
supported but this makes it less wrong).
* Add description helper to parser
* Regenerate parser output
* Add cakkbacks to parser
* Regenerate parser output
* Refactor funcLines to be an array of line numbers
It used to be an array of pointers into the text buffer but was changed
to be an array of pointers to the lines. Now it is an array of line
numbers like the others.
* Fix code style
* Move array size from name to type
* Regenerate parser output
---
parser/raylib_api.json | 158 +++++++++---
parser/raylib_api.lua | 119 ++++++---
parser/raylib_api.txt | 78 ++++--
parser/raylib_api.xml | 65 +++--
parser/raylib_parser.c | 555 ++++++++++++++++++++++++++++++-----------
5 files changed, 735 insertions(+), 240 deletions(-)
diff --git a/parser/raylib_api.json b/parser/raylib_api.json
index d9565c5c..98a939b2 100644
--- a/parser/raylib_api.json
+++ b/parser/raylib_api.json
@@ -471,7 +471,7 @@
{
"type": "float *",
"name": "texcoords2",
- "description": "Vertex second texture coordinates (useful for lightmaps) (shader-location = 5)"
+ "description": "Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5)"
},
{
"type": "float *",
@@ -577,8 +577,8 @@
"description": "Material maps array (MAX_MATERIAL_MAPS)"
},
{
- "type": "float",
- "name": "params[4]",
+ "type": "float[4]",
+ "name": "params",
"description": "Material generic parameters (if required)"
}
]
@@ -609,8 +609,8 @@
"description": "Bone, skeletal animation bone",
"fields": [
{
- "type": "char",
- "name": "name[32]",
+ "type": "char[32]",
+ "name": "name",
"description": "Bone name"
},
{
@@ -909,13 +909,13 @@
"description": "IPD (distance between pupils) in meters"
},
{
- "type": "float",
- "name": "lensDistortionValues[4]",
+ "type": "float[4]",
+ "name": "lensDistortionValues",
"description": "Lens distortion constant parameters"
},
{
- "type": "float",
- "name": "chromaAbCorrection[4]",
+ "type": "float[4]",
+ "name": "chromaAbCorrection",
"description": "Chromatic aberration correction parameters"
}
]
@@ -925,43 +925,43 @@
"description": "VrStereoConfig, VR stereo rendering configuration for simulator",
"fields": [
{
- "type": "Matrix",
- "name": "projection[2]",
+ "type": "Matrix[2]",
+ "name": "projection",
"description": "VR projection matrices (per eye)"
},
{
- "type": "Matrix",
- "name": "viewOffset[2]",
+ "type": "Matrix[2]",
+ "name": "viewOffset",
"description": "VR view offset matrices (per eye)"
},
{
- "type": "float",
- "name": "leftLensCenter[2]",
+ "type": "float[2]",
+ "name": "leftLensCenter",
"description": "VR left lens center"
},
{
- "type": "float",
- "name": "rightLensCenter[2]",
+ "type": "float[2]",
+ "name": "rightLensCenter",
"description": "VR right lens center"
},
{
- "type": "float",
- "name": "leftScreenCenter[2]",
+ "type": "float[2]",
+ "name": "leftScreenCenter",
"description": "VR left screen center"
},
{
- "type": "float",
- "name": "rightScreenCenter[2]",
+ "type": "float[2]",
+ "name": "rightScreenCenter",
"description": "VR right screen center"
},
{
- "type": "float",
- "name": "scale[2]",
+ "type": "float[2]",
+ "name": "scale",
"description": "VR distortion scale"
},
{
- "type": "float",
- "name": "scaleIn[2]",
+ "type": "float[2]",
+ "name": "scaleIn",
"description": "VR distortion scale in"
}
]
@@ -4116,7 +4116,7 @@
},
{
"name": "GetDirectoryFiles",
- "description": "Get filenames in a directory path (memory should be freed)",
+ "description": "Get filenames in a directory path (memory must be freed)",
"returnType": "char **",
"params": [
{
@@ -4152,7 +4152,7 @@
},
{
"name": "GetDroppedFiles",
- "description": "Get dropped files names (memory should be freed)",
+ "description": "Get dropped files names (memory must be freed)",
"returnType": "char **",
"params": [
{
@@ -4179,7 +4179,7 @@
},
{
"name": "CompressData",
- "description": "Compress data (DEFLATE algorithm)",
+ "description": "Compress data (DEFLATE algorithm), memory must be MemFree()",
"returnType": "unsigned char *",
"params": [
{
@@ -4198,7 +4198,7 @@
},
{
"name": "DecompressData",
- "description": "Decompress data (DEFLATE algorithm)",
+ "description": "Decompress data (DEFLATE algorithm), memory must be MemFree()",
"returnType": "unsigned char *",
"params": [
{
@@ -4217,7 +4217,7 @@
},
{
"name": "EncodeDataBase64",
- "description": "Encode data to Base64 string",
+ "description": "Encode data to Base64 string, memory must be MemFree()",
"returnType": "char *",
"params": [
{
@@ -4236,7 +4236,7 @@
},
{
"name": "DecodeDataBase64",
- "description": "Decode Base64 string data",
+ "description": "Decode Base64 string data, memory must be MemFree()",
"returnType": "unsigned char *",
"params": [
{
@@ -10556,5 +10556,101 @@
}
]
}
+ ],
+ "callbacks": [
+ {
+ "name": "TraceLogCallback",
+ "description": "Logging: Redirect trace log messages",
+ "returnType": "void",
+ "params": [
+ {
+ "type": "int",
+ "name": "logLevel"
+ },
+ {
+ "type": "const char *",
+ "name": "text"
+ },
+ {
+ "type": "va_list",
+ "name": "args"
+ }
+ ]
+ },
+ {
+ "name": "LoadFileDataCallback",
+ "description": "FileIO: Load binary data",
+ "returnType": "unsigned char *",
+ "params": [
+ {
+ "type": "const char *",
+ "name": "fileName"
+ },
+ {
+ "type": "unsigned int *",
+ "name": "bytesRead"
+ }
+ ]
+ },
+ {
+ "name": "SaveFileDataCallback",
+ "description": "FileIO: Save binary data",
+ "returnType": "bool",
+ "params": [
+ {
+ "type": "const char *",
+ "name": "fileName"
+ },
+ {
+ "type": "void *",
+ "name": "data"
+ },
+ {
+ "type": "unsigned int",
+ "name": "bytesToWrite"
+ }
+ ]
+ },
+ {
+ "name": "LoadFileTextCallback",
+ "description": "FileIO: Load text data",
+ "returnType": "char *",
+ "params": [
+ {
+ "type": "const char *",
+ "name": "fileName"
+ }
+ ]
+ },
+ {
+ "name": "SaveFileTextCallback",
+ "description": "FileIO: Save text data",
+ "returnType": "bool",
+ "params": [
+ {
+ "type": "const char *",
+ "name": "fileName"
+ },
+ {
+ "type": "char *",
+ "name": "text"
+ }
+ ]
+ },
+ {
+ "name": "AudioCallback",
+ "description": "",
+ "returnType": "void",
+ "params": [
+ {
+ "type": "void *",
+ "name": "bufferData"
+ },
+ {
+ "type": "unsigned int",
+ "name": "frames"
+ }
+ ]
+ }
]
}
diff --git a/parser/raylib_api.lua b/parser/raylib_api.lua
index 0a127e47..8888fade 100644
--- a/parser/raylib_api.lua
+++ b/parser/raylib_api.lua
@@ -471,7 +471,7 @@ return {
{
type = "float *",
name = "texcoords2",
- description = "Vertex second texture coordinates (useful for lightmaps) (shader-location = 5)"
+ description = "Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5)"
},
{
type = "float *",
@@ -577,8 +577,8 @@ return {
description = "Material maps array (MAX_MATERIAL_MAPS)"
},
{
- type = "float",
- name = "params[4]",
+ type = "float[4]",
+ name = "params",
description = "Material generic parameters (if required)"
}
}
@@ -609,8 +609,8 @@ return {
description = "Bone, skeletal animation bone",
fields = {
{
- type = "char",
- name = "name[32]",
+ type = "char[32]",
+ name = "name",
description = "Bone name"
},
{
@@ -909,13 +909,13 @@ return {
description = "IPD (distance between pupils) in meters"
},
{
- type = "float",
- name = "lensDistortionValues[4]",
+ type = "float[4]",
+ name = "lensDistortionValues",
description = "Lens distortion constant parameters"
},
{
- type = "float",
- name = "chromaAbCorrection[4]",
+ type = "float[4]",
+ name = "chromaAbCorrection",
description = "Chromatic aberration correction parameters"
}
}
@@ -925,43 +925,43 @@ return {
description = "VrStereoConfig, VR stereo rendering configuration for simulator",
fields = {
{
- type = "Matrix",
- name = "projection[2]",
+ type = "Matrix[2]",
+ name = "projection",
description = "VR projection matrices (per eye)"
},
{
- type = "Matrix",
- name = "viewOffset[2]",
+ type = "Matrix[2]",
+ name = "viewOffset",
description = "VR view offset matrices (per eye)"
},
{
- type = "float",
- name = "leftLensCenter[2]",
+ type = "float[2]",
+ name = "leftLensCenter",
description = "VR left lens center"
},
{
- type = "float",
- name = "rightLensCenter[2]",
+ type = "float[2]",
+ name = "rightLensCenter",
description = "VR right lens center"
},
{
- type = "float",
- name = "leftScreenCenter[2]",
+ type = "float[2]",
+ name = "leftScreenCenter",
description = "VR left screen center"
},
{
- type = "float",
- name = "rightScreenCenter[2]",
+ type = "float[2]",
+ name = "rightScreenCenter",
description = "VR right screen center"
},
{
- type = "float",
- name = "scale[2]",
+ type = "float[2]",
+ name = "scale",
description = "VR distortion scale"
},
{
- type = "float",
- name = "scaleIn[2]",
+ type = "float[2]",
+ name = "scaleIn",
description = "VR distortion scale in"
}
}
@@ -3771,7 +3771,7 @@ return {
},
{
name = "GetDirectoryFiles",
- description = "Get filenames in a directory path (memory should be freed)",
+ description = "Get filenames in a directory path (memory must be freed)",
returnType = "char **",
params = {
{type = "const char *", name = "dirPath"},
@@ -3798,7 +3798,7 @@ return {
},
{
name = "GetDroppedFiles",
- description = "Get dropped files names (memory should be freed)",
+ description = "Get dropped files names (memory must be freed)",
returnType = "char **",
params = {
{type = "int *", name = "count"}
@@ -3819,7 +3819,7 @@ return {
},
{
name = "CompressData",
- description = "Compress data (DEFLATE algorithm)",
+ description = "Compress data (DEFLATE algorithm), memory must be MemFree()",
returnType = "unsigned char *",
params = {
{type = "const unsigned char *", name = "data"},
@@ -3829,7 +3829,7 @@ return {
},
{
name = "DecompressData",
- description = "Decompress data (DEFLATE algorithm)",
+ description = "Decompress data (DEFLATE algorithm), memory must be MemFree()",
returnType = "unsigned char *",
params = {
{type = "const unsigned char *", name = "compData"},
@@ -3839,7 +3839,7 @@ return {
},
{
name = "EncodeDataBase64",
- description = "Encode data to Base64 string",
+ description = "Encode data to Base64 string, memory must be MemFree()",
returnType = "char *",
params = {
{type = "const unsigned char *", name = "data"},
@@ -3849,7 +3849,7 @@ return {
},
{
name = "DecodeDataBase64",
- description = "Decode Base64 string data",
+ description = "Decode Base64 string data, memory must be MemFree()",
returnType = "unsigned char *",
params = {
{type = "const unsigned char *", name = "data"},
@@ -7322,5 +7322,62 @@ return {
{type = "AudioCallback", name = "processor"}
}
}
+ },
+ callbacks = {
+ {
+ name = "TraceLogCallback",
+ description = "Logging: Redirect trace log messages",
+ returnType = "void",
+ params = {
+ {type = "int", name = "logLevel"},
+ {type = "const char *", name = "text"},
+ {type = "va_list", name = "args"}
+ }
+ },
+ {
+ name = "LoadFileDataCallback",
+ description = "FileIO: Load binary data",
+ returnType = "unsigned char *",
+ params = {
+ {type = "const char *", name = "fileName"},
+ {type = "unsigned int *", name = "bytesRead"}
+ }
+ },
+ {
+ name = "SaveFileDataCallback",
+ description = "FileIO: Save binary data",
+ returnType = "bool",
+ params = {
+ {type = "const char *", name = "fileName"},
+ {type = "void *", name = "data"},
+ {type = "unsigned int", name = "bytesToWrite"}
+ }
+ },
+ {
+ name = "LoadFileTextCallback",
+ description = "FileIO: Load text data",
+ returnType = "char *",
+ params = {
+ {type = "const char *", name = "fileName"}
+ }
+ },
+ {
+ name = "SaveFileTextCallback",
+ description = "FileIO: Save text data",
+ returnType = "bool",
+ params = {
+ {type = "const char *", name = "fileName"},
+ {type = "char *", name = "text"}
+ }
+ },
+ {
+ name = "AudioCallback",
+ description = "",
+ returnType = "void",
+ params = {
+ {type = "void *", name = "bufferData"},
+ {type = "unsigned int", name = "frames"}
+ }
+ }
}
}
diff --git a/parser/raylib_api.txt b/parser/raylib_api.txt
index cf673d4d..972b4d65 100644
--- a/parser/raylib_api.txt
+++ b/parser/raylib_api.txt
@@ -122,7 +122,7 @@ Struct 15: Mesh (15 fields)
Field[2]: int triangleCount // Number of triangles stored (indexed or not)
Field[3]: float * vertices // Vertex position (XYZ - 3 components per vertex) (shader-location = 0)
Field[4]: float * texcoords // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
- Field[5]: float * texcoords2 // Vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
+ Field[5]: float * texcoords2 // Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5)
Field[6]: float * normals // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
Field[7]: float * tangents // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4)
Field[8]: unsigned char * colors // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
@@ -149,7 +149,7 @@ Struct 18: Material (3 fields)
Description: Material, includes shader and maps
Field[1]: Shader shader // Material shader
Field[2]: MaterialMap * maps // Material maps array (MAX_MATERIAL_MAPS)
- Field[3]: float params[4] // Material generic parameters (if required)
+ Field[3]: float[4] params // Material generic parameters (if required)
Struct 19: Transform (3 fields)
Name: Transform
Description: Transform, vectex transformation data
@@ -159,7 +159,7 @@ Struct 19: Transform (3 fields)
Struct 20: BoneInfo (2 fields)
Name: BoneInfo
Description: Bone, skeletal animation bone
- Field[1]: char name[32] // Bone name
+ Field[1]: char[32] name // Bone name
Field[2]: int parent // Bone parent
Struct 21: Model (9 fields)
Name: Model
@@ -237,19 +237,19 @@ Struct 30: VrDeviceInfo (10 fields)
Field[6]: float eyeToScreenDistance // Distance between eye and display in meters
Field[7]: float lensSeparationDistance // Lens separation distance in meters
Field[8]: float interpupillaryDistance // IPD (distance between pupils) in meters
- Field[9]: float lensDistortionValues[4] // Lens distortion constant parameters
- Field[10]: float chromaAbCorrection[4] // Chromatic aberration correction parameters
+ Field[9]: float[4] lensDistortionValues // Lens distortion constant parameters
+ Field[10]: float[4] chromaAbCorrection // Chromatic aberration correction parameters
Struct 31: VrStereoConfig (8 fields)
Name: VrStereoConfig
Description: VrStereoConfig, VR stereo rendering configuration for simulator
- Field[1]: Matrix projection[2] // VR projection matrices (per eye)
- Field[2]: Matrix viewOffset[2] // VR view offset matrices (per eye)
- Field[3]: float leftLensCenter[2] // VR left lens center
- Field[4]: float rightLensCenter[2] // VR right lens center
- Field[5]: float leftScreenCenter[2] // VR left screen center
- Field[6]: float rightScreenCenter[2] // VR right screen center
- Field[7]: float scale[2] // VR distortion scale
- Field[8]: float scaleIn[2] // VR distortion scale in
+ Field[1]: Matrix[2] projection // VR projection matrices (per eye)
+ Field[2]: Matrix[2] viewOffset // VR view offset matrices (per eye)
+ Field[3]: float[2] leftLensCenter // VR left lens center
+ Field[4]: float[2] rightLensCenter // VR right lens center
+ Field[5]: float[2] leftScreenCenter // VR left screen center
+ Field[6]: float[2] rightScreenCenter // VR right screen center
+ Field[7]: float[2] scale // VR distortion scale
+ Field[8]: float[2] scaleIn // VR distortion scale in
Aliases found: 5
@@ -1281,7 +1281,7 @@ Function 121: GetApplicationDirectory() (0 input parameters)
Function 122: GetDirectoryFiles() (2 input parameters)
Name: GetDirectoryFiles
Return type: char **
- Description: Get filenames in a directory path (memory should be freed)
+ Description: Get filenames in a directory path (memory must be freed)
Param[1]: dirPath (type: const char *)
Param[2]: count (type: int *)
Function 123: ClearDirectoryFiles() (0 input parameters)
@@ -1302,7 +1302,7 @@ Function 125: IsFileDropped() (0 input parameters)
Function 126: GetDroppedFiles() (1 input parameters)
Name: GetDroppedFiles
Return type: char **
- Description: Get dropped files names (memory should be freed)
+ Description: Get dropped files names (memory must be freed)
Param[1]: count (type: int *)
Function 127: ClearDroppedFiles() (0 input parameters)
Name: ClearDroppedFiles
@@ -1317,28 +1317,28 @@ Function 128: GetFileModTime() (1 input parameters)
Function 129: CompressData() (3 input parameters)
Name: CompressData
Return type: unsigned char *
- Description: Compress data (DEFLATE algorithm)
+ Description: Compress data (DEFLATE algorithm), memory must be MemFree()
Param[1]: data (type: const unsigned char *)
Param[2]: dataSize (type: int)
Param[3]: compDataSize (type: int *)
Function 130: DecompressData() (3 input parameters)
Name: DecompressData
Return type: unsigned char *
- Description: Decompress data (DEFLATE algorithm)
+ Description: Decompress data (DEFLATE algorithm), memory must be MemFree()
Param[1]: compData (type: const unsigned char *)
Param[2]: compDataSize (type: int)
Param[3]: dataSize (type: int *)
Function 131: EncodeDataBase64() (3 input parameters)
Name: EncodeDataBase64
Return type: char *
- Description: Encode data to Base64 string
+ Description: Encode data to Base64 string, memory must be MemFree()
Param[1]: data (type: const unsigned char *)
Param[2]: dataSize (type: int)
Param[3]: outputSize (type: int *)
Function 132: DecodeDataBase64() (2 input parameters)
Name: DecodeDataBase64
Return type: unsigned char *
- Description: Decode Base64 string data
+ Description: Decode Base64 string data, memory must be MemFree()
Param[1]: data (type: const unsigned char *)
Param[2]: outputSize (type: int *)
Function 133: SaveStorageValue() (2 input parameters)
@@ -3782,6 +3782,46 @@ Function 499: DetachAudioStreamProcessor() (2 input parameters)
Param[1]: stream (type: AudioStream)
Param[2]: processor (type: AudioCallback)
+Callbacks found: 6
+
+Callback 001: TraceLogCallback() (3 input parameters)
+ Name: TraceLogCallback
+ Return type: void
+ Description: Logging: Redirect trace log messages
+ Param[1]: logLevel (type: int)
+ Param[2]: text (type: const char *)
+ Param[3]: args (type: va_list)
+Callback 002: LoadFileDataCallback() (2 input parameters)
+ Name: LoadFileDataCallback
+ Return type: unsigned char *
+ Description: FileIO: Load binary data
+ Param[1]: fileName (type: const char *)
+ Param[2]: bytesRead (type: unsigned int *)
+Callback 003: SaveFileDataCallback() (3 input parameters)
+ Name: SaveFileDataCallback
+ Return type: bool
+ Description: FileIO: Save binary data
+ Param[1]: fileName (type: const char *)
+ Param[2]: data (type: void *)
+ Param[3]: bytesToWrite (type: unsigned int)
+Callback 004: LoadFileTextCallback() (1 input parameters)
+ Name: LoadFileTextCallback
+ Return type: char *
+ Description: FileIO: Load text data
+ Param[1]: fileName (type: const char *)
+Callback 005: SaveFileTextCallback() (2 input parameters)
+ Name: SaveFileTextCallback
+ Return type: bool
+ Description: FileIO: Save text data
+ Param[1]: fileName (type: const char *)
+ Param[2]: text (type: char *)
+Callback 006: AudioCallback() (2 input parameters)
+ Name: AudioCallback
+ Return type: void
+ Description:
+ Param[1]: bufferData (type: void *)
+ Param[2]: frames (type: unsigned int)
+
Defines found: 52
Define 001: RAYLIB_H
diff --git a/parser/raylib_api.xml b/parser/raylib_api.xml
index d1f58b5c..db7761c5 100644
--- a/parser/raylib_api.xml
+++ b/parser/raylib_api.xml
@@ -106,7 +106,7 @@
-
+
@@ -130,7 +130,7 @@
-
+
@@ -138,7 +138,7 @@
-
+
@@ -206,18 +206,18 @@
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
@@ -975,7 +975,7 @@
-
+
@@ -986,7 +986,7 @@
-
+
@@ -994,22 +994,22 @@
-
+
-
+
-
+
-
+
@@ -2695,4 +2695,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/parser/raylib_parser.c b/parser/raylib_parser.c
index 01cdc1ac..d7eee55f 100644
--- a/parser/raylib_parser.c
+++ b/parser/raylib_parser.c
@@ -67,6 +67,7 @@
#include // Required for: isdigit()
#define MAX_FUNCS_TO_PARSE 512 // Maximum number of functions to parse
+#define MAX_CALLBACKS_TO_PARSE 64 // Maximum number of callbacks to parse
#define MAX_STRUCTS_TO_PARSE 64 // Maximum number of structures to parse
#define MAX_ALIASES_TO_PARSE 64 // Maximum number of aliases to parse
#define MAX_ENUMS_TO_PARSE 64 // Maximum number of enums to parse
@@ -76,7 +77,7 @@
#define MAX_STRUCT_LINE_LENGTH 2048 // Maximum length of one struct (multiple lines)
#define MAX_FUNCTION_PARAMETERS 12 // Maximum number of function parameters
-#define MAX_STRUCT_FIELDS 32 // Maximum number of struct fields
+#define MAX_STRUCT_FIELDS 64 // Maximum number of struct fields
#define MAX_ENUM_VALUES 512 // Maximum number of enum values
//----------------------------------------------------------------------------------
@@ -139,11 +140,13 @@ typedef enum { DEFAULT = 0, JSON, XML, LUA } OutputFormat;
// Global Variables Definition
//----------------------------------------------------------------------------------
static int funcCount = 0;
+static int callbackCount = 0;
static int structCount = 0;
static int aliasCount = 0;
static int enumCount = 0;
static int defineCount = 0;
static FunctionInfo *funcs = NULL;
+static FunctionInfo *callbacks = NULL;
static StructInfo *structs = NULL;
static AliasInfo *aliases = NULL;
static EnumInfo *enums = NULL;
@@ -164,6 +167,7 @@ static void ProcessCommandLine(int argc, char *argv[]); // Process command l
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 void GetDescription(const char *source, char *description);
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);
@@ -173,6 +177,8 @@ static void ExportParsedData(const char *fileName, int format); // Export parsed
static const char *StrDefineType(DefineType type); // Get string of define type
+static void MoveArraySize(char *name, char *type); // Move array size from name to type
+
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
@@ -190,19 +196,22 @@ int main(int argc, char* argv[])
int linesCount = 0;
char **lines = GetTextLines(buffer, length, &linesCount);
- // Function lines pointers, selected from buffer "lines"
- char **funcLines = (char **)malloc(MAX_FUNCS_TO_PARSE*sizeof(char *));
+ // Function line indices
+ int *funcLines = (int *)malloc(MAX_FUNCS_TO_PARSE*sizeof(int));
+
+ // Callbacks line indices
+ int *callbackLines = (int *)malloc(MAX_CALLBACKS_TO_PARSE*sizeof(int));
- // Structs lines pointers, selected from buffer "lines"
+ // Structs line indices
int *structLines = (int *)malloc(MAX_STRUCTS_TO_PARSE*sizeof(int));
- // Aliases lines pointers, selected from buffer "lines"
+ // Aliases line indices
int *aliasLines = (int *)malloc(MAX_ALIASES_TO_PARSE*sizeof(int));
- // Enums lines pointers, selected from buffer "lines"
+ // Enums line indices
int *enumLines = (int *)malloc(MAX_ENUMS_TO_PARSE*sizeof(int));
- // Defines lines pointers, selected from buffer "lines"
+ // Defines line indices
int *defineLines = (int *)malloc(MAX_DEFINES_TO_PARSE*sizeof(int));
// Prepare required lines for parsing
@@ -214,30 +223,54 @@ int main(int argc, char* argv[])
// Read function line (starting with `define`, i.e. for raylib.h "RLAPI")
if (IsTextEqual(lines[i], apiDefine, TextLength(apiDefine)))
{
- // Keep a pointer to the function line
- funcLines[funcCount] = lines[i];
+ funcLines[funcCount] = i;
funcCount++;
}
}
- // Read struct lines
+ // Read callback lines
for (int i = 0; i < linesCount; i++)
{
- // Find structs (starting with "typedef struct ... {", ending with '} ... ;')
- if (IsTextEqual(lines[i], "typedef struct", 14))
+ // Find callbacks (lines with "typedef ... (* ... )( ... );")
+ if (IsTextEqual(lines[i], "typedef", 7))
{
- int j = 0;
- bool validStruct = false;
+ bool hasBeginning = false;
+ bool hasMiddle = false;
+ bool hasEnd = false;
for (int c = 0; c < MAX_LINE_LENGTH; c++)
{
- char v = lines[i][c];
- if (v == '{') validStruct = true;
- if (v == '{' || v == ';' || v == '\0')
+ if ((lines[i][c] == '(') && (lines[i][c + 1] == '*')) hasBeginning = true;
+ if ((lines[i][c] == ')') && (lines[i][c + 1] == '(')) hasMiddle = true;
+ if ((lines[i][c] == ')') && (lines[i][c + 1] == ';')) hasEnd = true;
+ if (hasEnd) break;
+ }
+
+ if (hasBeginning && hasMiddle && hasEnd)
+ {
+ callbackLines[callbackCount] = i;
+ callbackCount++;
+ }
+ }
+ }
+
+ // Read struct lines
+ for (int i = 0; i < linesCount; i++)
+ {
+ // Find structs
+ // starting with "typedef struct ... {" or "typedef struct ... ; \n struct ... {"
+ // ending with "} ... ;"
+ // i.e. excluding "typedef struct rAudioBuffer rAudioBuffer;" -> Typedef and forward declaration only
+ if (IsTextEqual(lines[i], "typedef struct", 14))
+ {
+ bool validStruct = IsTextEqual(lines[i + 1], "struct", 6);
+ if (!validStruct)
+ {
+ for (int c = 0; c < MAX_LINE_LENGTH; c++)
{
- // Not valid struct if it ends without '{':
- // i.e typedef struct rAudioBuffer rAudioBuffer; -> Typedef and forward declaration
- break;
+ char v = lines[i][c];
+ if (v == '{') validStruct = true;
+ if ((v == '{') || (v == ';') || (v == '\0')) break;
}
}
if (!validStruct) continue;
@@ -261,8 +294,8 @@ int main(int argc, char* argv[])
{
char v = lines[i][c];
if (v == ' ') spaceCount++;
- if (v == ';' && spaceCount == 2) validAlias = true;
- if (v == ';' || v == '(' || v == '\0') break;
+ if ((v == ';') && (spaceCount == 2)) validAlias = true;
+ if ((v == ';') || (v == '(') || (v == '\0')) break;
}
if (!validAlias) continue;
aliasLines[aliasCount] = i;
@@ -274,7 +307,7 @@ int main(int argc, char* argv[])
for (int i = 0; i < linesCount; i++)
{
// Read enum line
- if (IsTextEqual(lines[i], "typedef enum {", 14) && lines[i][TextLength(lines[i])-1] != ';') // ignore inline enums
+ if (IsTextEqual(lines[i], "typedef enum {", 14) && (lines[i][TextLength(lines[i])-1] != ';')) // ignore inline enums
{
// Keep the line position in the array of lines,
// so, we can scan that position and following lines
@@ -287,7 +320,7 @@ int main(int argc, char* argv[])
for (int i = 0; i < linesCount; i++)
{
int j = 0;
- while (lines[i][j] == ' ' || lines[i][j] == '\t') j++; // skip spaces and tabs in the begining
+ while ((lines[i][j] == ' ') || (lines[i][j] == '\t')) j++; // skip spaces and tabs in the begining
// Read define line
if (IsTextEqual(lines[i]+j, "#define ", 8))
{
@@ -313,18 +346,17 @@ int main(int argc, char* argv[])
char **linesPtr = &lines[structLines[i]];
// Parse struct description
- if (linesPtr[-1][0] == '/')
- {
- MemoryCopy(structs[i].desc, linesPtr[-1], TextLength(linesPtr[-1]));
- }
+ GetDescription(linesPtr[-1], structs[i].desc);
// Get struct name: typedef struct name {
const int TDS_LEN = 15; // length of "typedef struct "
for (int c = TDS_LEN; c < 64 + TDS_LEN; c++)
{
- if (linesPtr[0][c] == '{')
+ if ((linesPtr[0][c] == '{') || (linesPtr[0][c] == ' '))
{
- MemoryCopy(structs[i].name, &linesPtr[0][TDS_LEN], c - TDS_LEN - 1);
+ int nameLen = c - TDS_LEN;
+ while (linesPtr[0][TDS_LEN + nameLen - 1] == ' ') nameLen--;
+ MemoryCopy(structs[i].name, &linesPtr[0][TDS_LEN], nameLen);
break;
}
}
@@ -341,7 +373,7 @@ int main(int argc, char* argv[])
int fieldEndPos = 0;
while (fieldLine[fieldEndPos] != ';') fieldEndPos++;
- if (fieldLine[0] != '/') // Field line is not a comment
+ if ((fieldLine[0] != '/') && !IsTextEqual(fieldLine, "struct", 6)) // Field line is not a comment and not a struct declaration
{
//printf("Struct field: %s_\n", fieldLine); // OK!
@@ -349,77 +381,125 @@ int main(int argc, char* argv[])
GetDataTypeAndName(fieldLine, fieldEndPos, structs[i].fieldType[structs[i].fieldCount], structs[i].fieldName[structs[i].fieldCount]);
// Get the field description
- // We start skipping spaces in front of description comment
- int descStart = fieldEndPos;
- while ((fieldLine[descStart] != '/') && (fieldLine[descStart] != '\0')) descStart++;
-
- int k = 0;
- while ((fieldLine[descStart + k] != '\0') && (fieldLine[descStart + k] != '\n'))
- {
- structs[i].fieldDesc[structs[i].fieldCount][k] = fieldLine[descStart + k];
- k++;
- }
+ GetDescription(&fieldLine[fieldEndPos], structs[i].fieldDesc[structs[i].fieldCount]);
structs[i].fieldCount++;
// Split field names containing multiple fields (like Matrix)
+ int additionalFields = 0;
int originalIndex = structs[i].fieldCount - 1;
- int originalLength = -1;
- int lastStart;
- for (int c = 0; c < TextLength(structs[i].fieldName[originalIndex]) + 1; c++)
+ for (int c = 0; c < TextLength(structs[i].fieldName[originalIndex]); c++)
+ {
+ if (structs[i].fieldName[originalIndex][c] == ',') additionalFields++;
+ }
+ if (additionalFields > 0)
{
- char v = structs[i].fieldName[originalIndex][c];
- bool isEndOfString = v == '\0';
- if ((v == ',') || isEndOfString)
+ int originalLength = -1;
+ int lastStart;
+ for (int c = 0; c < TextLength(structs[i].fieldName[originalIndex]) + 1; c++)
{
- if (originalLength == -1)
+ char v = structs[i].fieldName[originalIndex][c];
+ bool isEndOfString = (v == '\0');
+ if ((v == ',') || isEndOfString)
{
- // Save length of original field name
- // Don't truncate yet, still needed for copying
- originalLength = c;
+ if (originalLength == -1)
+ {
+ // Save length of original field name
+ // Don't truncate yet, still needed for copying
+ originalLength = c;
+ }
+ else
+ {
+ // Copy field data from original field
+ int nameLength = c - lastStart;
+ MemoryCopy(structs[i].fieldName[structs[i].fieldCount], &structs[i].fieldName[originalIndex][lastStart], nameLength);
+ MemoryCopy(structs[i].fieldType[structs[i].fieldCount], &structs[i].fieldType[originalIndex][0], TextLength(structs[i].fieldType[originalIndex]));
+ MemoryCopy(structs[i].fieldDesc[structs[i].fieldCount], &structs[i].fieldDesc[originalIndex][0], TextLength(structs[i].fieldDesc[originalIndex]));
+ structs[i].fieldCount++;
+ }
+ if (!isEndOfString)
+ {
+ // Skip comma and spaces
+ c++;
+ while (structs[i].fieldName[originalIndex][c] == ' ') c++;
+
+ // Save position for next field
+ lastStart = c;
+ }
}
- else
+ }
+ // Set length of original field to truncate the first field name
+ structs[i].fieldName[originalIndex][originalLength] = '\0';
+ }
+
+ // Split field types containing multiple fields (like MemNode)
+ additionalFields = 0;
+ originalIndex = structs[i].fieldCount - 1;
+ for (int c = 0; c < TextLength(structs[i].fieldType[originalIndex]); c++)
+ {
+ if (structs[i].fieldType[originalIndex][c] == ',') additionalFields++;
+ }
+ if (additionalFields > 0) {
+ // Copy original name to last additional field
+ structs[i].fieldCount += additionalFields;
+ MemoryCopy(structs[i].fieldName[originalIndex + additionalFields], &structs[i].fieldName[originalIndex][0], TextLength(structs[i].fieldName[originalIndex]));
+
+ // Copy names from type to additional fields
+ int fieldsRemaining = additionalFields;
+ int nameStart = -1;
+ int nameEnd = -1;
+ for (int k = TextLength(structs[i].fieldType[originalIndex]); k > 0; k--)
+ {
+ char v = structs[i].fieldType[originalIndex][k];
+ if ((v == '*') || (v == ' ') || (v == ','))
{
- // Copy field data from original field
- int nameLength = c - lastStart;
- MemoryCopy(structs[i].fieldName[structs[i].fieldCount], &(structs[i].fieldName[originalIndex][lastStart]), nameLength);
- MemoryCopy(structs[i].fieldType[structs[i].fieldCount], &(structs[i].fieldType[originalIndex][0]), TextLength(structs[i].fieldType[originalIndex]));
- MemoryCopy(structs[i].fieldDesc[structs[i].fieldCount], &(structs[i].fieldDesc[originalIndex][0]), TextLength(structs[i].fieldDesc[originalIndex]));
- structs[i].fieldCount++;
+ if (nameEnd != -1) {
+ // Don't copy to last additional field
+ if (fieldsRemaining != additionalFields)
+ {
+ nameStart = k + 1;
+ MemoryCopy(structs[i].fieldName[originalIndex + fieldsRemaining], &structs[i].fieldType[originalIndex][nameStart], nameEnd - nameStart + 1);
+ }
+ nameEnd = -1;
+ fieldsRemaining--;
+ }
}
- if (!isEndOfString)
- {
- // Skip comma and spaces
- c++;
- while (structs[i].fieldName[originalIndex][c] == ' ') c++;
+ else if (nameEnd == -1) nameEnd = k;
+ }
- // Save position for next field
- lastStart = c;
- }
+ // Truncate original field type
+ int fieldTypeLength = nameStart;
+ structs[i].fieldType[originalIndex][fieldTypeLength] = '\0';
+
+ // Set field type and description of additional fields
+ for (int j = 1; j <= additionalFields; j++)
+ {
+ MemoryCopy(structs[i].fieldType[originalIndex + j], &structs[i].fieldType[originalIndex][0], fieldTypeLength);
+ MemoryCopy(structs[i].fieldDesc[originalIndex + j], &structs[i].fieldDesc[originalIndex][0], TextLength(structs[i].fieldDesc[originalIndex]));
+
}
}
- // Set length of original field
- // This has no effect on fields that are on their own line
- // But it truncates the first field name of fields that share a line
- structs[i].fieldName[originalIndex][originalLength] = '\0';
}
}
l++;
}
+ // Move array sizes from name to type
+ for (int j = 0; j < structs[i].fieldCount; j++)
+ {
+ MoveArraySize(structs[i].fieldName[j], structs[i].fieldType[j]);
+ }
}
free(structLines);
// Alias info data
aliases = (AliasInfo *)calloc(MAX_ALIASES_TO_PARSE, sizeof(AliasInfo));
- int aliasIndex = 0;
for (int i = 0; i < aliasCount; i++)
{
// Description from previous line
- char *previousLinePtr = lines[aliasLines[i] - 1];
- if (previousLinePtr[0] == '/') MemoryCopy(aliases[i].desc, previousLinePtr, MAX_LINE_LENGTH);
+ GetDescription(lines[aliasLines[i] - 1], aliases[i].desc);
char *linePtr = lines[aliasLines[i]];
@@ -430,7 +510,7 @@ int main(int argc, char* argv[])
int typeStart = c;
while(linePtr[c] != ' ') c++;
int typeLen = c - typeStart;
- MemoryCopy(aliases[i].type, linePtr + typeStart, typeLen);
+ MemoryCopy(aliases[i].type, &linePtr[typeStart], typeLen);
// Skip space
c++;
@@ -439,14 +519,69 @@ int main(int argc, char* argv[])
int nameStart = c;
while(linePtr[c] != ';') c++;
int nameLen = c - nameStart;
- MemoryCopy(aliases[i].name, linePtr + nameStart, nameLen);
+ MemoryCopy(aliases[i].name, &linePtr[nameStart], nameLen);
// Description
- while((linePtr[c] != '\0') && (linePtr[c] != '/')) c++;
- if (linePtr[c] == '/') MemoryCopy(aliases[i].desc, linePtr + c, MAX_LINE_LENGTH);
+ GetDescription(&linePtr[c], aliases[i].desc);
}
free(aliasLines);
+ // Callback info data
+ callbacks = (FunctionInfo *)calloc(MAX_CALLBACKS_TO_PARSE, sizeof(FunctionInfo));
+
+ for (int i = 0; i < callbackCount; i++)
+ {
+ char *linePtr = lines[callbackLines[i]];
+
+ // Skip "typedef "
+ int c = 8;
+
+ // Return type
+ int retTypeStart = c;
+ while(linePtr[c] != '(') c++;
+ int retTypeLen = c - retTypeStart;
+ while(linePtr[retTypeStart + retTypeLen - 1] == ' ') retTypeLen--;
+ MemoryCopy(callbacks[i].retType, &linePtr[retTypeStart], retTypeLen);
+
+ // Skip "(*"
+ c += 2;
+
+ // Name
+ int nameStart = c;
+ while(linePtr[c] != ')') c++;
+ int nameLen = c - nameStart;
+ MemoryCopy(callbacks[i].name, &linePtr[nameStart], nameLen);
+
+ // Skip ")("
+ c += 2;
+
+ // Params
+ int paramStart = c;
+ for (c; c < MAX_LINE_LENGTH; c++)
+ {
+ if ((linePtr[c] == ',') || (linePtr[c] == ')'))
+ {
+ // Get parameter type + name, extract info
+ int paramLen = c - paramStart;
+ GetDataTypeAndName(&linePtr[paramStart], paramLen, callbacks[i].paramType[callbacks[i].paramCount], callbacks[i].paramName[callbacks[i].paramCount]);
+ callbacks[i].paramCount++;
+ paramStart = c + 1;
+ while(linePtr[paramStart] == ' ') paramStart++;
+ }
+ if (linePtr[c] == ')') break;
+ }
+
+ // Description
+ GetDescription(&linePtr[c], callbacks[i].desc);
+
+ // Move array sizes from name to type
+ for (int j = 0; j < callbacks[i].paramCount; j++)
+ {
+ MoveArraySize(callbacks[i].paramName[j], callbacks[i].paramType[j]);
+ }
+ }
+ free(callbackLines);
+
// Enum info data
enums = (EnumInfo *)calloc(MAX_ENUMS_TO_PARSE, sizeof(EnumInfo));
@@ -462,7 +597,7 @@ int main(int argc, char* argv[])
char *linePtr = lines[j];
if ((linePtr[0] != '/') || (linePtr[2] != ' '))
{
- MemoryCopy(enums[i].desc, &lines[j + 1][0], sizeof(enums[i].desc) - 1);
+ GetDescription(&lines[j + 1][0], enums[i].desc);
break;
}
}
@@ -536,13 +671,8 @@ int main(int argc, char* argv[])
}
else enums[i].valueInteger[enums[i].valueCount] = (enums[i].valueInteger[enums[i].valueCount - 1] + 1);
- // Look for description or end of line
- while ((linePtr[c] != '/') && (linePtr[c] != '\0')) c++;
- if (linePtr[c] == '/')
- {
- // Parse value description
- MemoryCopy(enums[i].valueDesc[enums[i].valueCount], &linePtr[c], sizeof(enums[0].valueDesc[0]) - c - 1);
- }
+ // Parse value description
+ GetDescription(&linePtr[c], enums[i].valueDesc[enums[i].valueCount]);
enums[i].valueCount++;
}
@@ -577,7 +707,14 @@ int main(int argc, char* argv[])
// Extract name
int defineNameStart = j;
- while ((linePtr[j] != ' ') && (linePtr[j] != '\t') && (linePtr[j] != '\0')) j++;
+ int openBraces = 0;
+ while (linePtr[j] != '\0')
+ {
+ if (((linePtr[j] == ' ') || (linePtr[j] == '\t')) && (openBraces == 0)) break;
+ if (linePtr[j] == '(') openBraces++;
+ if (linePtr[j] == ')') openBraces--;
+ j++;
+ }
int defineNameEnd = j-1;
// Skip duplicates
@@ -585,7 +722,7 @@ int main(int argc, char* argv[])
bool isDuplicate = false;
for (int k = 0; k < defineIndex; k++)
{
- if ((nameLen == TextLength(defines[k].name)) && IsTextEqual(defines[k].name, linePtr + defineNameStart, nameLen))
+ if ((nameLen == TextLength(defines[k].name)) && IsTextEqual(defines[k].name, &linePtr[defineNameStart], nameLen))
{
isDuplicate = true;
break;
@@ -593,7 +730,7 @@ int main(int argc, char* argv[])
}
if (isDuplicate) continue;
- MemoryCopy(defines[defineIndex].name, linePtr + defineNameStart, nameLen);
+ MemoryCopy(defines[defineIndex].name, &linePtr[defineNameStart], nameLen);
// Determine type
if (linePtr[defineNameEnd] == ')') defines[defineIndex].type = MACRO;
@@ -645,18 +782,20 @@ int main(int argc, char* argv[])
int valueLen = defineValueEnd - defineValueStart + 1;
if (valueLen > 255) valueLen = 255;
- if (valueLen > 0) MemoryCopy(defines[defineIndex].value, linePtr + defineValueStart, valueLen);
+ if (valueLen > 0) MemoryCopy(defines[defineIndex].value, &linePtr[defineValueStart], valueLen);
// Extracting description
- if (linePtr[j] == '/')
+ if ((linePtr[j] == '/') && linePtr[j + 1] == '/')
{
+ j += 2;
+ while (linePtr[j] == ' ') j++;
int commentStart = j;
while ((linePtr[j] != '\\') && (linePtr[j] != '\0')) j++;
int commentEnd = j-1;
int commentLen = commentEnd - commentStart + 1;
if (commentLen > 127) commentLen = 127;
- MemoryCopy(defines[defineIndex].desc, linePtr + commentStart, commentLen);
+ MemoryCopy(defines[defineIndex].desc, &linePtr[commentStart], commentLen);
}
defineIndex++;
@@ -669,13 +808,15 @@ int main(int argc, char* argv[])
for (int i = 0; i < funcCount; i++)
{
+ char *linePtr = lines[funcLines[i]];
+
int funcParamsStart = 0;
int funcEnd = 0;
// Get return type and function name from func line
- for (int c = 0; (c < MAX_LINE_LENGTH) && (funcLines[i][c] != '\n'); c++)
+ for (int c = 0; (c < MAX_LINE_LENGTH) && (linePtr[c] != '\n'); c++)
{
- if (funcLines[i][c] == '(') // Starts function parameters
+ if (linePtr[c] == '(') // Starts function parameters
{
funcParamsStart = c + 1;
@@ -683,7 +824,7 @@ int main(int argc, char* argv[])
char funcRetTypeName[128] = { 0 };
int dc = TextLength(apiDefine) + 1;
int funcRetTypeNameLen = c - dc; // Substract `define` ("RLAPI " for raylib.h)
- MemoryCopy(funcRetTypeName, &funcLines[i][dc], funcRetTypeNameLen);
+ MemoryCopy(funcRetTypeName, &linePtr[dc], funcRetTypeNameLen);
GetDataTypeAndName(funcRetTypeName, funcRetTypeNameLen, funcs[i].retType, funcs[i].name);
break;
@@ -693,30 +834,30 @@ int main(int argc, char* argv[])
// Get parameters from func line
for (int c = funcParamsStart; c < MAX_LINE_LENGTH; c++)
{
- if (funcLines[i][c] == ',') // Starts function parameters
+ if (linePtr[c] == ',') // Starts function parameters
{
// Get parameter type + name, extract info
char funcParamTypeName[128] = { 0 };
int funcParamTypeNameLen = c - funcParamsStart;
- MemoryCopy(funcParamTypeName, &funcLines[i][funcParamsStart], funcParamTypeNameLen);
+ MemoryCopy(funcParamTypeName, &linePtr[funcParamsStart], funcParamTypeNameLen);
GetDataTypeAndName(funcParamTypeName, funcParamTypeNameLen, funcs[i].paramType[funcs[i].paramCount], funcs[i].paramName[funcs[i].paramCount]);
funcParamsStart = c + 1;
- if (funcLines[i][c + 1] == ' ') funcParamsStart += 1;
+ if (linePtr[c + 1] == ' ') funcParamsStart += 1;
funcs[i].paramCount++; // Move to next parameter
}
- else if (funcLines[i][c] == ')')
+ else if (linePtr[c] == ')')
{
funcEnd = c + 2;
// Check if previous word is void
- if ((funcLines[i][c - 4] == 'v') && (funcLines[i][c - 3] == 'o') && (funcLines[i][c - 2] == 'i') && (funcLines[i][c - 1] == 'd')) break;
+ if ((linePtr[c - 4] == 'v') && (linePtr[c - 3] == 'o') && (linePtr[c - 2] == 'i') && (linePtr[c - 1] == 'd')) break;
// Get parameter type + name, extract info
char funcParamTypeName[128] = { 0 };
int funcParamTypeNameLen = c - funcParamsStart;
- MemoryCopy(funcParamTypeName, &funcLines[i][funcParamsStart], funcParamTypeNameLen);
+ MemoryCopy(funcParamTypeName, &linePtr[funcParamsStart], funcParamTypeNameLen);
GetDataTypeAndName(funcParamTypeName, funcParamTypeNameLen, funcs[i].paramType[funcs[i].paramCount], funcs[i].paramName[funcs[i].paramCount]);
@@ -726,27 +867,27 @@ int main(int argc, char* argv[])
}
// Get function description
- for (int c = funcEnd; c < MAX_LINE_LENGTH; c++)
+ GetDescription(&linePtr[funcEnd], funcs[i].desc);
+
+ // Move array sizes from name to type
+ for (int j = 0; j < funcs[i].paramCount; j++)
{
- if (funcLines[i][c] == '/')
- {
- MemoryCopy(funcs[i].desc, &funcLines[i][c], 127); // WARNING: Size could be too long for funcLines[i][c]?
- break;
- }
+ MoveArraySize(funcs[i].paramName[j], funcs[i].paramType[j]);
}
}
+ free(funcLines);
for (int i = 0; i < linesCount; i++) free(lines[i]);
free(lines);
- free(funcLines);
// At this point, all raylib data has been parsed!
//-----------------------------------------------------------------------------------------
- // structs[] -> We have all the structs decomposed into pieces for further analysis
- // aliases[] -> We have all the aliases decomposed into pieces for further analysis
- // enums[] -> We have all the enums decomposed into pieces for further analysis
- // funcs[] -> We have all the functions decomposed into pieces for further analysis
- // defines[] -> We have all the defines decomposed into pieces for further analysis
+ // structs[] -> We have all the structs decomposed into pieces for further analysis
+ // aliases[] -> We have all the aliases decomposed into pieces for further analysis
+ // enums[] -> We have all the enums decomposed into pieces for further analysis
+ // funcs[] -> We have all the functions decomposed into pieces for further analysis
+ // callbacks[] -> We have all the callbacks decomposed into pieces for further analysis
+ // defines[] -> We have all the defines decomposed into pieces for further analysis
// Process input file to output
if (outFileName[0] == '\0') MemoryCopy(outFileName, "raylib_api.txt\0", 15);
@@ -761,6 +902,7 @@ int main(int argc, char* argv[])
ExportParsedData(outFileName, outputFormat);
free(funcs);
+ free(callbacks);
free(structs);
free(aliases);
free(enums);
@@ -969,6 +1111,26 @@ static void GetDataTypeAndName(const char *typeName, int typeNameLen, char *type
}
}
+// Get comment from a line, do nothing if no comment in line
+static void GetDescription(const char *line, char *description)
+{
+ int c = 0;
+ int descStart = -1;
+ int lastSlash = -2;
+ bool isValid = false;
+ while (line[c] != '\0')
+ {
+ if (isValid && (descStart == -1) && (line[c] != ' ')) descStart = c;
+ else if (line[c] == '/')
+ {
+ if (lastSlash == c - 1) isValid = true;
+ lastSlash = c;
+ }
+ c++;
+ }
+ if (descStart != -1) MemoryCopy(description, &line[descStart], c - descStart);
+}
+
// Get text length in bytes, check for \0 character
static unsigned int TextLength(const char *text)
{
@@ -1047,6 +1209,24 @@ static const char *StrDefineType(DefineType type)
return "";
}
+// Move array size from name to type
+static void MoveArraySize(char *name, char *type)
+{
+ int nameLength = TextLength(name);
+ if (name[nameLength - 1] == ']')
+ {
+ for (int k = nameLength; k > 0; k--)
+ {
+ if (name[k] == '[')
+ {
+ int sizeLength = nameLength - k;
+ MemoryCopy(&type[TextLength(type)], &name[k], sizeLength);
+ name[k] = '\0';
+ }
+ }
+ }
+}
+
/*
// Replace text string
// REQUIRES: strlen(), strstr(), strncpy(), strcpy() -> TODO: Replace by custom implementations!
@@ -1114,8 +1294,13 @@ static void ExportParsedData(const char *fileName, int format)
{
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]);
+ fprintf(outFile, " Description: %s\n", structs[i].desc);
+ for (int f = 0; f < structs[i].fieldCount; f++)
+ {
+ fprintf(outFile, " Field[%i]: %s %s ", f + 1, structs[i].fieldType[f], structs[i].fieldName[f]);
+ if (structs[i].fieldDesc[f][0]) fprintf(outFile, "// %s\n", structs[i].fieldDesc[f]);
+ else fprintf(outFile, "\n");
+ }
}
// Print aliases info
@@ -1125,7 +1310,7 @@ static void ExportParsedData(const char *fileName, int format)
fprintf(outFile, "Alias %03i: %s\n", i + 1, aliases[i].name);
fprintf(outFile, " Type: %s\n", aliases[i].type);
fprintf(outFile, " Name: %s\n", aliases[i].name);
- fprintf(outFile, " Description: %s\n", aliases[i].desc + 3);
+ fprintf(outFile, " Description: %s\n", aliases[i].desc);
}
// Print enums info
@@ -1134,7 +1319,7 @@ static void ExportParsedData(const char *fileName, int format)
{
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);
+ fprintf(outFile, " Description: %s\n", enums[i].desc);
for (int e = 0; e < enums[i].valueCount; e++) fprintf(outFile, " Value[%s]: %i\n", enums[i].valueName[e], enums[i].valueInteger[e]);
}
@@ -1145,11 +1330,23 @@ static void ExportParsedData(const char *fileName, int format)
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);
+ fprintf(outFile, " Description: %s\n", funcs[i].desc);
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");
}
+ // Print callbacks info
+ fprintf(outFile, "\nCallbacks found: %i\n\n", callbackCount);
+ for (int i = 0; i < callbackCount; i++)
+ {
+ fprintf(outFile, "Callback %03i: %s() (%i input parameters)\n", i + 1, callbacks[i].name, callbacks[i].paramCount);
+ fprintf(outFile, " Name: %s\n", callbacks[i].name);
+ fprintf(outFile, " Return type: %s\n", callbacks[i].retType);
+ fprintf(outFile, " Description: %s\n", callbacks[i].desc);
+ for (int p = 0; p < callbacks[i].paramCount; p++) fprintf(outFile, " Param[%i]: %s (type: %s)\n", p + 1, callbacks[i].paramName[p], callbacks[i].paramType[p]);
+ if (callbacks[i].paramCount == 0) fprintf(outFile, " No input parameters\n");
+ }
+
// Print defines info
fprintf(outFile, "\nDefines found: %i\n\n", defineCount);
for (int i = 0; i < defineCount; i++)
@@ -1158,7 +1355,7 @@ static void ExportParsedData(const char *fileName, int format)
fprintf(outFile, " Name: %s\n", defines[i].name);
fprintf(outFile, " Type: %s\n", StrDefineType(defines[i].type));
fprintf(outFile, " Value: %s\n", defines[i].value);
- fprintf(outFile, " Description: %s\n", defines[i].desc + 3);
+ fprintf(outFile, " Description: %s\n", defines[i].desc);
}
} break;
case LUA:
@@ -1171,14 +1368,14 @@ static void ExportParsedData(const char *fileName, int format)
{
fprintf(outFile, " {\n");
fprintf(outFile, " name = \"%s\",\n", structs[i].name);
- fprintf(outFile, " description = \"%s\",\n", EscapeBackslashes(structs[i].desc + 3));
+ fprintf(outFile, " description = \"%s\",\n", EscapeBackslashes(structs[i].desc));
fprintf(outFile, " fields = {\n");
for (int f = 0; f < structs[i].fieldCount; f++)
{
fprintf(outFile, " {\n");
fprintf(outFile, " type = \"%s\",\n", structs[i].fieldType[f]);
fprintf(outFile, " name = \"%s\",\n", structs[i].fieldName[f]);
- fprintf(outFile, " description = \"%s\"\n", EscapeBackslashes(structs[i].fieldDesc[f] + 3));
+ fprintf(outFile, " description = \"%s\"\n", EscapeBackslashes(structs[i].fieldDesc[f]));
fprintf(outFile, " }");
if (f < structs[i].fieldCount - 1) fprintf(outFile, ",\n");
else fprintf(outFile, "\n");
@@ -1197,7 +1394,7 @@ static void ExportParsedData(const char *fileName, int format)
fprintf(outFile, " {\n");
fprintf(outFile, " type = \"%s\",\n", aliases[i].type);
fprintf(outFile, " name = \"%s\",\n", aliases[i].name);
- fprintf(outFile, " description = \"%s\"\n", aliases[i].desc + 3);
+ fprintf(outFile, " description = \"%s\"\n", aliases[i].desc);
fprintf(outFile, " }");
if (i < aliasCount - 1) fprintf(outFile, ",\n");
@@ -1211,14 +1408,14 @@ static void ExportParsedData(const char *fileName, int format)
{
fprintf(outFile, " {\n");
fprintf(outFile, " name = \"%s\",\n", enums[i].name);
- fprintf(outFile, " description = \"%s\",\n", EscapeBackslashes(enums[i].desc + 3));
+ fprintf(outFile, " description = \"%s\",\n", EscapeBackslashes(enums[i].desc));
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", EscapeBackslashes(enums[i].valueDesc[e] + 3));
+ fprintf(outFile, " description = \"%s\"\n", EscapeBackslashes(enums[i].valueDesc[e]));
fprintf(outFile, " }");
if (e < enums[i].valueCount - 1) fprintf(outFile, ",\n");
else fprintf(outFile, "\n");
@@ -1249,7 +1446,7 @@ static void ExportParsedData(const char *fileName, int format)
{
fprintf(outFile, " value = \"%s\",\n", defines[i].value);
}
- fprintf(outFile, " description = \"%s\"\n", defines[i].desc + 3);
+ fprintf(outFile, " description = \"%s\"\n", defines[i].desc);
fprintf(outFile, " }");
if (i < defineCount - 1) fprintf(outFile, ",\n");
@@ -1263,7 +1460,7 @@ static void ExportParsedData(const char *fileName, int format)
{
fprintf(outFile, " {\n");
fprintf(outFile, " name = \"%s\",\n", funcs[i].name);
- fprintf(outFile, " description = \"%s\",\n", EscapeBackslashes(funcs[i].desc + 3));
+ fprintf(outFile, " description = \"%s\",\n", EscapeBackslashes(funcs[i].desc));
fprintf(outFile, " returnType = \"%s\"", funcs[i].retType);
if (funcs[i].paramCount == 0) fprintf(outFile, "\n");
@@ -1283,6 +1480,34 @@ static void ExportParsedData(const char *fileName, int format)
if (i < funcCount - 1) fprintf(outFile, ",\n");
else fprintf(outFile, "\n");
}
+ fprintf(outFile, " },\n");
+
+ // Print callbacks info
+ fprintf(outFile, " callbacks = {\n");
+ for (int i = 0; i < callbackCount; i++)
+ {
+ fprintf(outFile, " {\n");
+ fprintf(outFile, " name = \"%s\",\n", callbacks[i].name);
+ fprintf(outFile, " description = \"%s\",\n", EscapeBackslashes(callbacks[i].desc));
+ fprintf(outFile, " returnType = \"%s\"", callbacks[i].retType);
+
+ if (callbacks[i].paramCount == 0) fprintf(outFile, "\n");
+ else
+ {
+ fprintf(outFile, ",\n params = {\n");
+ for (int p = 0; p < callbacks[i].paramCount; p++)
+ {
+ fprintf(outFile, " {type = \"%s\", name = \"%s\"}", callbacks[i].paramType[p], callbacks[i].paramName[p]);
+ if (p < callbacks[i].paramCount - 1) fprintf(outFile, ",\n");
+ else fprintf(outFile, "\n");
+ }
+ fprintf(outFile, " }\n");
+ }
+ fprintf(outFile, " }");
+
+ if (i < callbackCount - 1) fprintf(outFile, ",\n");
+ else fprintf(outFile, "\n");
+ }
fprintf(outFile, " }\n");
fprintf(outFile, "}\n");
} break;
@@ -1296,14 +1521,14 @@ static void ExportParsedData(const char *fileName, int format)
{
fprintf(outFile, " {\n");
fprintf(outFile, " \"name\": \"%s\",\n", structs[i].name);
- fprintf(outFile, " \"description\": \"%s\",\n", EscapeBackslashes(structs[i].desc + 3));
+ fprintf(outFile, " \"description\": \"%s\",\n", EscapeBackslashes(structs[i].desc));
fprintf(outFile, " \"fields\": [\n");
for (int f = 0; f < structs[i].fieldCount; f++)
{
fprintf(outFile, " {\n");
fprintf(outFile, " \"type\": \"%s\",\n", structs[i].fieldType[f]);
fprintf(outFile, " \"name\": \"%s\",\n", structs[i].fieldName[f]);
- fprintf(outFile, " \"description\": \"%s\"\n", EscapeBackslashes(structs[i].fieldDesc[f] + 3));
+ fprintf(outFile, " \"description\": \"%s\"\n", EscapeBackslashes(structs[i].fieldDesc[f]));
fprintf(outFile, " }");
if (f < structs[i].fieldCount - 1) fprintf(outFile, ",\n");
else fprintf(outFile, "\n");
@@ -1322,7 +1547,7 @@ static void ExportParsedData(const char *fileName, int format)
fprintf(outFile, " {\n");
fprintf(outFile, " \"type\": \"%s\",\n", aliases[i].type);
fprintf(outFile, " \"name\": \"%s\",\n", aliases[i].name);
- fprintf(outFile, " \"description\": \"%s\"\n", aliases[i].desc + 3);
+ fprintf(outFile, " \"description\": \"%s\"\n", aliases[i].desc);
fprintf(outFile, " }");
if (i < aliasCount - 1) fprintf(outFile, ",\n");
@@ -1336,14 +1561,14 @@ static void ExportParsedData(const char *fileName, int format)
{
fprintf(outFile, " {\n");
fprintf(outFile, " \"name\": \"%s\",\n", enums[i].name);
- fprintf(outFile, " \"description\": \"%s\",\n", EscapeBackslashes(enums[i].desc + 3));
+ fprintf(outFile, " \"description\": \"%s\",\n", EscapeBackslashes(enums[i].desc));
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", EscapeBackslashes(enums[i].valueDesc[e] + 3));
+ fprintf(outFile, " \"description\": \"%s\"\n", EscapeBackslashes(enums[i].valueDesc[e]));
fprintf(outFile, " }");
if (e < enums[i].valueCount - 1) fprintf(outFile, ",\n");
else fprintf(outFile, "\n");
@@ -1378,7 +1603,7 @@ static void ExportParsedData(const char *fileName, int format)
{
fprintf(outFile, " \"value\": \"%s\",\n", defines[i].value);
}
- fprintf(outFile, " \"description\": \"%s\"\n", defines[i].desc + 3);
+ fprintf(outFile, " \"description\": \"%s\"\n", defines[i].desc);
fprintf(outFile, " }");
if (i < defineCount - 1) fprintf(outFile, ",\n");
@@ -1392,7 +1617,7 @@ static void ExportParsedData(const char *fileName, int format)
{
fprintf(outFile, " {\n");
fprintf(outFile, " \"name\": \"%s\",\n", funcs[i].name);
- fprintf(outFile, " \"description\": \"%s\",\n", EscapeBackslashes(funcs[i].desc + 3));
+ fprintf(outFile, " \"description\": \"%s\",\n", EscapeBackslashes(funcs[i].desc));
fprintf(outFile, " \"returnType\": \"%s\"", funcs[i].retType);
if (funcs[i].paramCount == 0) fprintf(outFile, "\n");
@@ -1415,6 +1640,37 @@ static void ExportParsedData(const char *fileName, int format)
if (i < funcCount - 1) fprintf(outFile, ",\n");
else fprintf(outFile, "\n");
}
+ fprintf(outFile, " ],\n");
+
+ // Print callbacks info
+ fprintf(outFile, " \"callbacks\": [\n");
+ for (int i = 0; i < callbackCount; i++)
+ {
+ fprintf(outFile, " {\n");
+ fprintf(outFile, " \"name\": \"%s\",\n", callbacks[i].name);
+ fprintf(outFile, " \"description\": \"%s\",\n", EscapeBackslashes(callbacks[i].desc));
+ fprintf(outFile, " \"returnType\": \"%s\"", callbacks[i].retType);
+
+ if (callbacks[i].paramCount == 0) fprintf(outFile, "\n");
+ else
+ {
+ fprintf(outFile, ",\n \"params\": [\n");
+ for (int p = 0; p < callbacks[i].paramCount; p++)
+ {
+ fprintf(outFile, " {\n");
+ fprintf(outFile, " \"type\": \"%s\",\n", callbacks[i].paramType[p]);
+ fprintf(outFile, " \"name\": \"%s\"\n", callbacks[i].paramName[p]);
+ fprintf(outFile, " }");
+ if (p < callbacks[i].paramCount - 1) fprintf(outFile, ",\n");
+ else fprintf(outFile, "\n");
+ }
+ fprintf(outFile, " ]\n");
+ }
+ fprintf(outFile, " }");
+
+ if (i < callbackCount - 1) fprintf(outFile, ",\n");
+ else fprintf(outFile, "\n");
+ }
fprintf(outFile, " ]\n");
fprintf(outFile, "}\n");
} break;
@@ -1448,6 +1704,12 @@ static void ExportParsedData(const char *fileName, int format)
+
+
+
+
+
+
*/
@@ -1458,10 +1720,10 @@ static void ExportParsedData(const char *fileName, int format)
fprintf(outFile, " \n", structCount);
for (int i = 0; i < structCount; i++)
{
- fprintf(outFile, " \n", structs[i].name, structs[i].fieldCount, structs[i].desc + 3);
+ fprintf(outFile, " \n", structs[i].name, structs[i].fieldCount, structs[i].desc);
for (int f = 0; f < structs[i].fieldCount; f++)
{
- fprintf(outFile, " \n", structs[i].fieldType[f], structs[i].fieldName[f], structs[i].fieldDesc[f] + 3);
+ fprintf(outFile, " \n", structs[i].fieldType[f], structs[i].fieldName[f], structs[i].fieldDesc[f]);
}
fprintf(outFile, " \n");
}
@@ -1471,7 +1733,7 @@ static void ExportParsedData(const char *fileName, int format)
fprintf(outFile, " \n", aliasCount);
for (int i = 0; i < aliasCount; i++)
{
- fprintf(outFile, " \n", aliases[i].name, aliases[i].type, aliases[i].desc + 3);
+ fprintf(outFile, " \n", aliases[i].name, aliases[i].type, aliases[i].desc);
}
fprintf(outFile, " \n");
@@ -1479,10 +1741,10 @@ static void ExportParsedData(const char *fileName, int format)
fprintf(outFile, " \n", enumCount);
for (int i = 0; i < enumCount; i++)
{
- fprintf(outFile, " \n", enums[i].name, enums[i].valueCount, enums[i].desc + 3);
+ fprintf(outFile, " \n", enums[i].name, enums[i].valueCount, enums[i].desc);
for (int v = 0; v < enums[i].valueCount; v++)
{
- fprintf(outFile, " \n", enums[i].valueName[v], enums[i].valueInteger[v], enums[i].valueDesc[v] + 3);
+ fprintf(outFile, " \n", enums[i].valueName[v], enums[i].valueInteger[v], enums[i].valueDesc[v]);
}
fprintf(outFile, " \n");
}
@@ -1501,7 +1763,7 @@ static void ExportParsedData(const char *fileName, int format)
{
fprintf(outFile, "value=\"%s\"", defines[i].value);
}
- fprintf(outFile, " desc=\"%s\" />\n", defines[i].desc + 3);
+ fprintf(outFile, " desc=\"%s\" />\n", defines[i].desc);
}
fprintf(outFile, " \n");
@@ -1509,15 +1771,28 @@ static void ExportParsedData(const char *fileName, int format)
fprintf(outFile, " \n", funcCount);
for (int i = 0; i < funcCount; i++)
{
- fprintf(outFile, " \n", funcs[i].name, funcs[i].retType, funcs[i].paramCount, funcs[i].desc + 3);
+ fprintf(outFile, " \n", funcs[i].name, funcs[i].retType, funcs[i].paramCount, funcs[i].desc);
for (int p = 0; p < funcs[i].paramCount; p++)
{
- fprintf(outFile, " \n", funcs[i].paramType[p], funcs[i].paramName[p], funcs[i].paramDesc[p] + 3);
+ fprintf(outFile, " \n", funcs[i].paramType[p], funcs[i].paramName[p], funcs[i].paramDesc[p]);
}
fprintf(outFile, " \n");
}
fprintf(outFile, " \n");
+ // Print callbacks info
+ fprintf(outFile, " \n", callbackCount);
+ for (int i = 0; i < callbackCount; i++)
+ {
+ fprintf(outFile, " \n", callbacks[i].name, callbacks[i].retType, callbacks[i].paramCount, callbacks[i].desc);
+ for (int p = 0; p < callbacks[i].paramCount; p++)
+ {
+ fprintf(outFile, " \n", callbacks[i].paramType[p], callbacks[i].paramName[p], callbacks[i].paramDesc[p]);
+ }
+ fprintf(outFile, " \n");
+ }
+ fprintf(outFile, " \n");
+
fprintf(outFile, "\n");
} break;