浏览代码

Added defines to parser (#2269)

* added defines to parser

* added value and description for defines in parser

* parser: fixed lua defines output, fixed makefile for raygui, added LONG type for defines

* parser defines: remove postfix for LONG/FLOAT, support for hexadecimal consts, convert hex ints to decimal for JSON output

* removed defines from raylib_apis
pull/2329/head
iskolbin 3 年前
committed by GitHub
父节点
当前提交
c895bed5e6
找不到此签名对应的密钥 GPG 密钥 ID: 4AEE18F83AFDEB23
共有 2 个文件被更改,包括 208 次插入5 次删除
  1. +2
    -1
      parser/Makefile
  2. +206
    -4
      parser/raylib_parser.c

+ 2
- 1
parser/Makefile 查看文件

@ -20,8 +20,9 @@ parse:
./raylib_parser -i ../src/raymath.h -o raymath_api.$(EXTENSION) -f $(FORMAT) -d RMAPI
./raylib_parser -i ../src/extras/easings.h -o easings_api.$(EXTENSION) -f $(FORMAT) -d EASEDEF
./raylib_parser -i ../src/extras/physac.h -o physac_api.$(EXTENSION) -f $(FORMAT) -d PHYSACDEF
./raylib_parser -i ../src/extras/raygui.h -o raygui_api.$(EXTENSION) -f $(FORMAT) -d RAYGUIDEF
./raylib_parser -i ../src/extras/raygui.h -o raygui_api.$(EXTENSION) -f $(FORMAT) -d RAYGUIAPI
./raylib_parser -i ../src/extras/rmem.h -o rmem_api.$(EXTENSION) -f $(FORMAT) -d RMEMAPI
./raylib_parser -i ../src/rlgl.h -o rlgl_api.$(EXTENSION) -f $(FORMAT) -d RLAPI
clean:
rm -f raylib_parser *.json *.txt *.xml *.lua

+ 206
- 4
parser/raylib_parser.c 查看文件

@ -2,12 +2,13 @@
raylib API parser
This parser scans raylib.h to get API information about structs, enums and functions.
This parser scans raylib.h to get API information about structs, enums, functions and defines.
All data is divided into pieces, usually as strings. The following types are used for data:
- struct FunctionInfo
- struct StructInfo
- struct EnumInfo
- struct DefInfo
CONSTRAINTS:
@ -62,10 +63,12 @@
#include <stdlib.h> // Required for: malloc(), calloc(), realloc(), free(), atoi(), strtol()
#include <stdio.h> // Required for: printf(), fopen(), fseek(), ftell(), fread(), fclose()
#include <stdbool.h> // Required for: bool
#include <ctype.h> // Required for: isdigit()
#define MAX_FUNCS_TO_PARSE 512 // Maximum number of functions to parse
#define MAX_STRUCTS_TO_PARSE 64 // Maximum number of structures to parse
#define MAX_ENUMS_TO_PARSE 64 // Maximum number of enums to parse
#define MAX_DEFINES_TO_PARSE 2048 // Maximum number of defines to parse
#define MAX_LINE_LENGTH 512 // Maximum length of one line (including comments)
#define MAX_STRUCT_LINE_LENGTH 2048 // Maximum length of one struct (multiple lines)
@ -108,6 +111,18 @@ typedef struct EnumInfo {
char valueDesc[MAX_ENUM_VALUES][128]; // Value description
} EnumInfo;
// Type of parsed define
typedef enum { UNKNOWN = 0, MACRO, GUARD, INT, LONG, FLOAT, DOUBLE, CHAR, STRING, COLOR } DefineType;
// Define info data
typedef struct DefineInfo {
char name[64]; // Define name
DefineType type; // Define type
char value[256]; // Define value
char desc[128]; // Define description
bool isHex; // Define is hex number (for types INT, LONG)
} DefineInfo;
// Output format for parsed data
typedef enum { DEFAULT = 0, JSON, XML, LUA } OutputFormat;
@ -117,9 +132,11 @@ typedef enum { DEFAULT = 0, JSON, XML, LUA } OutputFormat;
static int funcCount = 0;
static int structCount = 0;
static int enumCount = 0;
static int defineCount = 0;
static FunctionInfo *funcs = NULL;
static StructInfo *structs = NULL;
static EnumInfo *enums = NULL;
static DefineInfo *defines = NULL;
static char apiDefine[32] = "RLAPI\0";
// Command line variables
@ -143,6 +160,8 @@ static char *EscapeBackslashes(char *text); // Replace '\' by "\
static void ExportParsedData(const char *fileName, int format); // Export parsed data in desired format
static const char *StrDefineType(DefineType type); // Get string of define type
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
@ -169,6 +188,9 @@ int main(int argc, char* argv[])
// Enums lines pointers, selected from buffer "lines"
int *enumLines = (int *)malloc(MAX_ENUMS_TO_PARSE*sizeof(int));
// Defines lines pointers, selected from buffer "lines"
int *defineLines = (int *)malloc(MAX_DEFINES_TO_PARSE*sizeof(int));
// Prepare required lines for parsing
//--------------------------------------------------------------------------------------------------
@ -228,7 +250,22 @@ int main(int argc, char* argv[])
}
}
// At this point we have all raylib structs, enums, functions lines data to start parsing
// Read const lines
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
// Read define line
if (IsTextEqual(lines[i]+j, "#define ", 8))
{
// Keep the line position in the array of lines,
// so, we can scan that position and following lines
defineLines[defineCount] = i;
defineCount++;
}
}
// At this point we have all raylib structs, enums, functions, defines lines data to start parsing
free(buffer); // Unload text buffer
@ -402,9 +439,94 @@ int main(int argc, char* argv[])
}
}
}
free(enumLines);
// Define info data
defines = (DefineInfo *)calloc(MAX_DEFINES_TO_PARSE, sizeof(DefineInfo));
int defineIndex = 0;
for (int i = 0; i < defineCount; i++)
{
char *linePtr = lines[defineLines[i]];
int j = 0;
while (linePtr[j] == ' ' || linePtr[j] == '\t') j++; // Skip spaces and tabs in the begining
j += 8; // Skip "#define "
while (linePtr[j] == ' ' || linePtr[j] == '\t') j++; // Skip spaces and tabs after "#define "
// Extract name
int defineNameStart = j;
while (linePtr[j] != ' ' && linePtr[j] != '\t' && linePtr[j] != '\0') j++;
int defineNameEnd = j-1;
// Skip duplicates
int nameLen = defineNameEnd - defineNameStart + 1;
bool isDuplicate = false;
for (int k = 0; k < defineIndex; k++) {
if (nameLen == TextLength(defines[k].name) && IsTextEqual(defines[k].name, linePtr + defineNameStart, nameLen)) {
isDuplicate = true;
break;
}
}
if (isDuplicate) continue;
MemoryCopy(defines[defineIndex].name, linePtr + defineNameStart, nameLen);
// Determine type
if (linePtr[defineNameEnd] == ')') defines[defineIndex].type = MACRO;
while (linePtr[j] == ' ' || linePtr[j] == '\t') j++; // Skip spaces and tabs after name
int defineValueStart = j;
if (linePtr[j] == '\0' || linePtr == "/") defines[defineIndex].type = GUARD;
if (linePtr[j] == '"') defines[defineIndex].type = STRING;
else if (linePtr[j] == '\'') defines[defineIndex].type = CHAR;
else if (IsTextEqual(linePtr+j, "CLITERAL(Color)", 15)) defines[defineIndex].type = COLOR;
else if (isdigit(linePtr[j])) { // Parsing numbers
bool isFloat = false, isNumber = true, isHex = false;
while (linePtr[j] != ' ' && linePtr[j] != '\t' && linePtr[j] != '\0') {
char ch = linePtr[j];
if (ch == '.') isFloat = true;
if (ch == 'x') isHex = true;
if (!(isdigit(ch)||(ch >= 'a' && ch <= 'f')||(ch >= 'A' && ch <= 'F')||ch=='x'||ch=='L'||ch=='.'||ch=='+'||ch=='-')) isNumber = false;
j++;
}
if (isNumber) {
if (isFloat) {
defines[defineIndex].type = linePtr[j-1] == 'f' ? FLOAT : DOUBLE;
} else {
defines[defineIndex].type = linePtr[j-1] == 'L' ? LONG : INT;
defines[defineIndex].isHex = isHex;
}
}
}
// Extracting value
while (linePtr[j] != '\\' && linePtr[j] != '\0' && !(linePtr[j] == '/' && linePtr[j+1] == '/')) j++;
int defineValueEnd = j-1;
while (linePtr[defineValueEnd] == ' ' || linePtr[defineValueEnd] == '\t') defineValueEnd--; // Remove trailing spaces and tabs
if (defines[defineIndex].type == LONG || defines[defineIndex].type == FLOAT) defineValueEnd--; // Remove number postfix
int valueLen = defineValueEnd - defineValueStart + 1;
if (valueLen > 255) valueLen = 255;
if (valueLen > 0) MemoryCopy(defines[defineIndex].value, linePtr + defineValueStart, valueLen);
// Extracting description
if (linePtr[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);
}
defineIndex++;
}
defineCount = defineIndex;
free(defineLines);
// Functions info data
funcs = (FunctionInfo *)calloc(MAX_FUNCS_TO_PARSE, sizeof(FunctionInfo));
@ -486,6 +608,7 @@ int main(int argc, char* argv[])
// structs[] -> We have all the structs 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
// Process input file to output
if (outFileName[0] == '\0') MemoryCopy(outFileName, "raylib_api.txt\0", 15);
@ -759,6 +882,25 @@ static char *EscapeBackslashes(char *text)
return buffer;
}
// Get string of define type
static const char *StrDefineType(DefineType type)
{
switch (type)
{
case UNKNOWN: return "UNKNOWN";
case GUARD: return "GUARD";
case MACRO: return "MACRO";
case INT: return "INT";
case LONG: return "LONG";
case FLOAT: return "FLOAT";
case DOUBLE: return "DOUBLE";
case CHAR: return "CHAR";
case STRING: return "STRING";
case COLOR: return "COLOR";
}
return "";
}
/*
// Replace text string
// REQUIRES: strlen(), strstr(), strncpy(), strcpy() -> TODO: Replace by custom implementations!
@ -836,7 +978,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 + 3);
for (int e = 0; e < enums[i].valueCount; e++) fprintf(outFile, " Value[%s]: %i\n", enums[i].valueName[e], enums[i].valueInteger[e]);
}
@ -851,6 +993,16 @@ static void ExportParsedData(const char *fileName, int format)
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");
}
fprintf(outFile, "\nDefines found: %i\n\n", defineCount);
for (int i = 0; i < defineCount; i++)
{
fprintf(outFile, "Define %03i: %s\n", i + 1, defines[i].name);
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);
}
} break;
case LUA:
{
@ -906,6 +1058,26 @@ static void ExportParsedData(const char *fileName, int format)
}
fprintf(outFile, " },\n");
// Print defines info
fprintf(outFile, " defines = {\n");
for (int i = 0; i < defineCount; i++)
{
fprintf(outFile, " {\n");
fprintf(outFile, " name = \"%s\",\n", defines[i].name);
fprintf(outFile, " type = \"%s\",\n", StrDefineType(defines[i].type));
if (defines[i].type == INT || defines[i].type == LONG || defines[i].type == FLOAT || defines[i].type == DOUBLE || defines[i].type == STRING) {
fprintf(outFile, " value = %s,\n", defines[i].value);
} else {
fprintf(outFile, " value = \"%s\",\n", defines[i].value);
}
fprintf(outFile, " description = \"%s\"\n", defines[i].desc + 3);
fprintf(outFile, " }");
if (i < defineCount - 1) fprintf(outFile, ",\n");
else fprintf(outFile, "\n");
}
fprintf(outFile, " },\n");
// Print functions info
fprintf(outFile, " functions = {\n");
for (int i = 0; i < funcCount; i++)
@ -989,6 +1161,28 @@ static void ExportParsedData(const char *fileName, int format)
}
fprintf(outFile, " ],\n");
// Print defines info
fprintf(outFile, " \"defines\": [\n");
for (int i = 0; i < defineCount; i++)
{
fprintf(outFile, " {\n");
fprintf(outFile, " \"name\": \"%s\",\n", defines[i].name);
fprintf(outFile, " \"type\": \"%s\",\n", StrDefineType(defines[i].type));
if (defines[i].isHex) { // INT or LONG
fprintf(outFile, " \"value\": %ld,\n", strtol(defines[i].value, NULL, 16));
} else if (defines[i].type == INT || defines[i].type == LONG || defines[i].type == FLOAT || defines[i].type == DOUBLE || defines[i].type == STRING) {
fprintf(outFile, " \"value\": %s,\n", defines[i].value);
} else {
fprintf(outFile, " \"value\": \"%s\",\n", defines[i].value);
}
fprintf(outFile, " \"description\": \"%s\"\n", defines[i].desc + 3);
fprintf(outFile, " }");
if (i < defineCount - 1) fprintf(outFile, ",\n");
else fprintf(outFile, "\n");
}
fprintf(outFile, " ],\n");
// Print functions info
fprintf(outFile, " \"functions\": [\n");
for (int i = 0; i < funcCount; i++)
@ -1077,6 +1271,14 @@ static void ExportParsedData(const char *fileName, int format)
}
fprintf(outFile, " </Enums>\n");
// Print defines info
fprintf(outFile, " <Defines count=\"%i\">\n", defineCount);
for (int i = 0; i < defineCount; i++)
{
fprintf(outFile, " <Define name=\"%s\" type=\"%s\" value=\"%s\" desc=\"%s\" />\n", defines[i].name, StrDefineType(defines[i].type), defines[i].value, defines[i].desc);
}
fprintf(outFile, " </Defines>\n");
// Print functions info
fprintf(outFile, " <Functions count=\"%i\">\n", funcCount);
for (int i = 0; i < funcCount; i++)

正在加载...
取消
保存