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
This commit is contained in:
lazaray 2022-05-04 11:06:01 +02:00 committed by GitHub
parent 8cb03ef524
commit df6caea25d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 737 additions and 242 deletions

View file

@ -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"
}
]
}
]
}

View file

@ -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"}
}
}
}
}

View file

@ -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

View file

@ -106,7 +106,7 @@
<Field type="int" name="triangleCount" desc="Number of triangles stored (indexed or not)" />
<Field type="float *" name="vertices" desc="Vertex position (XYZ - 3 components per vertex) (shader-location = 0)" />
<Field type="float *" name="texcoords" desc="Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)" />
<Field type="float *" name="texcoords2" desc="Vertex second texture coordinates (useful for lightmaps) (shader-location = 5)" />
<Field type="float *" name="texcoords2" desc="Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5)" />
<Field type="float *" name="normals" desc="Vertex normals (XYZ - 3 components per vertex) (shader-location = 2)" />
<Field type="float *" name="tangents" desc="Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4)" />
<Field type="unsigned char *" name="colors" desc="Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)" />
@ -130,7 +130,7 @@
<Struct name="Material" fieldCount="3" desc="Material, includes shader and maps">
<Field type="Shader" name="shader" desc="Material shader" />
<Field type="MaterialMap *" name="maps" desc="Material maps array (MAX_MATERIAL_MAPS)" />
<Field type="float" name="params[4]" desc="Material generic parameters (if required)" />
<Field type="float[4]" name="params" desc="Material generic parameters (if required)" />
</Struct>
<Struct name="Transform" fieldCount="3" desc="Transform, vectex transformation data">
<Field type="Vector3" name="translation" desc="Translation" />
@ -138,7 +138,7 @@
<Field type="Vector3" name="scale" desc="Scale" />
</Struct>
<Struct name="BoneInfo" fieldCount="2" desc="Bone, skeletal animation bone">
<Field type="char" name="name[32]" desc="Bone name" />
<Field type="char[32]" name="name" desc="Bone name" />
<Field type="int" name="parent" desc="Bone parent" />
</Struct>
<Struct name="Model" fieldCount="9" desc="Model, meshes, materials and animation data">
@ -206,18 +206,18 @@
<Field type="float" name="eyeToScreenDistance" desc="Distance between eye and display in meters" />
<Field type="float" name="lensSeparationDistance" desc="Lens separation distance in meters" />
<Field type="float" name="interpupillaryDistance" desc="IPD (distance between pupils) in meters" />
<Field type="float" name="lensDistortionValues[4]" desc="Lens distortion constant parameters" />
<Field type="float" name="chromaAbCorrection[4]" desc="Chromatic aberration correction parameters" />
<Field type="float[4]" name="lensDistortionValues" desc="Lens distortion constant parameters" />
<Field type="float[4]" name="chromaAbCorrection" desc="Chromatic aberration correction parameters" />
</Struct>
<Struct name="VrStereoConfig" fieldCount="8" desc="VrStereoConfig, VR stereo rendering configuration for simulator">
<Field type="Matrix" name="projection[2]" desc="VR projection matrices (per eye)" />
<Field type="Matrix" name="viewOffset[2]" desc="VR view offset matrices (per eye)" />
<Field type="float" name="leftLensCenter[2]" desc="VR left lens center" />
<Field type="float" name="rightLensCenter[2]" desc="VR right lens center" />
<Field type="float" name="leftScreenCenter[2]" desc="VR left screen center" />
<Field type="float" name="rightScreenCenter[2]" desc="VR right screen center" />
<Field type="float" name="scale[2]" desc="VR distortion scale" />
<Field type="float" name="scaleIn[2]" desc="VR distortion scale in" />
<Field type="Matrix[2]" name="projection" desc="VR projection matrices (per eye)" />
<Field type="Matrix[2]" name="viewOffset" desc="VR view offset matrices (per eye)" />
<Field type="float[2]" name="leftLensCenter" desc="VR left lens center" />
<Field type="float[2]" name="rightLensCenter" desc="VR right lens center" />
<Field type="float[2]" name="leftScreenCenter" desc="VR left screen center" />
<Field type="float[2]" name="rightScreenCenter" desc="VR right screen center" />
<Field type="float[2]" name="scale" desc="VR distortion scale" />
<Field type="float[2]" name="scaleIn" desc="VR distortion scale in" />
</Struct>
</Structs>
<Aliases count="5">
@ -975,7 +975,7 @@
</Function>
<Function name="GetApplicationDirectory" retType="const char *" paramCount="0" desc="Get the directory if the running application (uses static string)">
</Function>
<Function name="GetDirectoryFiles" retType="char **" paramCount="2" desc="Get filenames in a directory path (memory should be freed)">
<Function name="GetDirectoryFiles" retType="char **" paramCount="2" desc="Get filenames in a directory path (memory must be freed)">
<Param type="const char *" name="dirPath" desc="" />
<Param type="int *" name="count" desc="" />
</Function>
@ -986,7 +986,7 @@
</Function>
<Function name="IsFileDropped" retType="bool" paramCount="0" desc="Check if a file has been dropped into window">
</Function>
<Function name="GetDroppedFiles" retType="char **" paramCount="1" desc="Get dropped files names (memory should be freed)">
<Function name="GetDroppedFiles" retType="char **" paramCount="1" desc="Get dropped files names (memory must be freed)">
<Param type="int *" name="count" desc="" />
</Function>
<Function name="ClearDroppedFiles" retType="void" paramCount="0" desc="Clear dropped files paths buffer (free memory)">
@ -994,22 +994,22 @@
<Function name="GetFileModTime" retType="long" paramCount="1" desc="Get file modification time (last write time)">
<Param type="const char *" name="fileName" desc="" />
</Function>
<Function name="CompressData" retType="unsigned char *" paramCount="3" desc="Compress data (DEFLATE algorithm)">
<Function name="CompressData" retType="unsigned char *" paramCount="3" desc="Compress data (DEFLATE algorithm), memory must be MemFree()">
<Param type="const unsigned char *" name="data" desc="" />
<Param type="int" name="dataSize" desc="" />
<Param type="int *" name="compDataSize" desc="" />
</Function>
<Function name="DecompressData" retType="unsigned char *" paramCount="3" desc="Decompress data (DEFLATE algorithm)">
<Function name="DecompressData" retType="unsigned char *" paramCount="3" desc="Decompress data (DEFLATE algorithm), memory must be MemFree()">
<Param type="const unsigned char *" name="compData" desc="" />
<Param type="int" name="compDataSize" desc="" />
<Param type="int *" name="dataSize" desc="" />
</Function>
<Function name="EncodeDataBase64" retType="char *" paramCount="3" desc="Encode data to Base64 string">
<Function name="EncodeDataBase64" retType="char *" paramCount="3" desc="Encode data to Base64 string, memory must be MemFree()">
<Param type="const unsigned char *" name="data" desc="" />
<Param type="int" name="dataSize" desc="" />
<Param type="int *" name="outputSize" desc="" />
</Function>
<Function name="DecodeDataBase64" retType="unsigned char *" paramCount="2" desc="Decode Base64 string data">
<Function name="DecodeDataBase64" retType="unsigned char *" paramCount="2" desc="Decode Base64 string data, memory must be MemFree()">
<Param type="const unsigned char *" name="data" desc="" />
<Param type="int *" name="outputSize" desc="" />
</Function>
@ -2695,4 +2695,31 @@
<Param type="AudioCallback" name="processor" desc="" />
</Function>
</Functions>
<Callbacks count="6">
<Callback name="TraceLogCallback" retType="void" paramCount="3" desc="Logging: Redirect trace log messages">
<Param type="int" name="logLevel" desc="" />
<Param type="const char *" name="text" desc="" />
<Param type="va_list" name="args" desc="" />
</Callback>
<Callback name="LoadFileDataCallback" retType="unsigned char *" paramCount="2" desc="FileIO: Load binary data">
<Param type="const char *" name="fileName" desc="" />
<Param type="unsigned int *" name="bytesRead" desc="" />
</Callback>
<Callback name="SaveFileDataCallback" retType="bool" paramCount="3" desc="FileIO: Save binary data">
<Param type="const char *" name="fileName" desc="" />
<Param type="void *" name="data" desc="" />
<Param type="unsigned int" name="bytesToWrite" desc="" />
</Callback>
<Callback name="LoadFileTextCallback" retType="char *" paramCount="1" desc="FileIO: Load text data">
<Param type="const char *" name="fileName" desc="" />
</Callback>
<Callback name="SaveFileTextCallback" retType="bool" paramCount="2" desc="FileIO: Save text data">
<Param type="const char *" name="fileName" desc="" />
<Param type="char *" name="text" desc="" />
</Callback>
<Callback name="AudioCallback" retType="void" paramCount="2" desc="">
<Param type="void *" name="bufferData" desc="" />
<Param type="unsigned int" name="frames" desc="" />
</Callback>
</Callbacks>
</raylibAPI>

View file

@ -67,6 +67,7 @@
#include <ctype.h> // 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));
// Structs lines pointers, selected from buffer "lines"
// Callbacks line indices
int *callbackLines = (int *)malloc(MAX_CALLBACKS_TO_PARSE*sizeof(int));
// 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 callback lines
for (int i = 0; i < linesCount; i++)
{
// Find callbacks (lines with "typedef ... (* ... )( ... );")
if (IsTextEqual(lines[i], "typedef", 7))
{
bool hasBeginning = false;
bool hasMiddle = false;
bool hasEnd = false;
for (int c = 0; c < MAX_LINE_LENGTH; c++)
{
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 ... {", ending with '} ... ;')
// 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))
{
int j = 0;
bool validStruct = false;
bool validStruct = IsTextEqual(lines[i + 1], "struct", 6);
if (!validStruct)
{
for (int c = 0; c < MAX_LINE_LENGTH; c++)
{
char v = lines[i][c];
if (v == '{') validStruct = true;
if (v == '{' || v == ';' || v == '\0')
{
// Not valid struct if it ends without '{':
// i.e typedef struct rAudioBuffer rAudioBuffer; -> Typedef and forward declaration
break;
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,27 +381,25 @@ 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;
for (int c = 0; c < TextLength(structs[i].fieldName[originalIndex]); c++)
{
if (structs[i].fieldName[originalIndex][c] == ',') additionalFields++;
}
if (additionalFields > 0)
{
int originalLength = -1;
int lastStart;
for (int c = 0; c < TextLength(structs[i].fieldName[originalIndex]) + 1; c++)
{
char v = structs[i].fieldName[originalIndex][c];
bool isEndOfString = v == '\0';
bool isEndOfString = (v == '\0');
if ((v == ',') || isEndOfString)
{
if (originalLength == -1)
@ -382,9 +412,9 @@ int main(int argc, char* argv[])
{
// 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]));
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)
@ -398,28 +428,78 @@ int main(int argc, char* argv[])
}
}
}
// 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
// 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 == ','))
{
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--;
}
}
else if (nameEnd == -1) nameEnd = k;
}
// 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]));
}
}
}
}
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);
}
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,19 +867,18 @@ 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!
//-----------------------------------------------------------------------------------------
@ -746,6 +886,7 @@ int main(int argc, char* argv[])
// 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
@ -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)
<Param type="" name="" desc="" />
</Function>
</Functions>
<Callbacks count="">
<Callback name="" retType="" paramCount="" desc="">
<Param type="" name="" desc="" />
<Param type="" name="" desc="" />
</Callback>
</Callbacks>
</raylibAPI>
*/
@ -1458,10 +1720,10 @@ static void ExportParsedData(const char *fileName, int format)
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);
fprintf(outFile, " <Struct name=\"%s\" fieldCount=\"%i\" desc=\"%s\">\n", structs[i].name, structs[i].fieldCount, structs[i].desc);
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, " <Field type=\"%s\" name=\"%s\" desc=\"%s\" />\n", structs[i].fieldType[f], structs[i].fieldName[f], structs[i].fieldDesc[f]);
}
fprintf(outFile, " </Struct>\n");
}
@ -1471,7 +1733,7 @@ static void ExportParsedData(const char *fileName, int format)
fprintf(outFile, " <Aliases count=\"%i\">\n", aliasCount);
for (int i = 0; i < aliasCount; i++)
{
fprintf(outFile, " <Alias type=\"%s\" name=\"%s\" desc=\"%s\" />\n", aliases[i].name, aliases[i].type, aliases[i].desc + 3);
fprintf(outFile, " <Alias type=\"%s\" name=\"%s\" desc=\"%s\" />\n", aliases[i].name, aliases[i].type, aliases[i].desc);
}
fprintf(outFile, " </Aliases>\n");
@ -1479,10 +1741,10 @@ static void ExportParsedData(const char *fileName, int format)
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);
fprintf(outFile, " <Enum name=\"%s\" valueCount=\"%i\" desc=\"%s\">\n", enums[i].name, enums[i].valueCount, enums[i].desc);
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, " <Value name=\"%s\" integer=\"%i\" desc=\"%s\" />\n", enums[i].valueName[v], enums[i].valueInteger[v], enums[i].valueDesc[v]);
}
fprintf(outFile, " </Enum>\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, " </Defines>\n");
@ -1509,15 +1771,28 @@ static void ExportParsedData(const char *fileName, int format)
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);
fprintf(outFile, " <Function name=\"%s\" retType=\"%s\" paramCount=\"%i\" desc=\"%s\">\n", funcs[i].name, funcs[i].retType, funcs[i].paramCount, funcs[i].desc);
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, " <Param type=\"%s\" name=\"%s\" desc=\"%s\" />\n", funcs[i].paramType[p], funcs[i].paramName[p], funcs[i].paramDesc[p]);
}
fprintf(outFile, " </Function>\n");
}
fprintf(outFile, " </Functions>\n");
// Print callbacks info
fprintf(outFile, " <Callbacks count=\"%i\">\n", callbackCount);
for (int i = 0; i < callbackCount; i++)
{
fprintf(outFile, " <Callback name=\"%s\" retType=\"%s\" paramCount=\"%i\" desc=\"%s\">\n", callbacks[i].name, callbacks[i].retType, callbacks[i].paramCount, callbacks[i].desc);
for (int p = 0; p < callbacks[i].paramCount; p++)
{
fprintf(outFile, " <Param type=\"%s\" name=\"%s\" desc=\"%s\" />\n", callbacks[i].paramType[p], callbacks[i].paramName[p], callbacks[i].paramDesc[p]);
}
fprintf(outFile, " </Callback>\n");
}
fprintf(outFile, " </Callbacks>\n");
fprintf(outFile, "</raylibAPI>\n");
} break;