From aa318674e8e790eda7deefc021bb8e4c6877d59d Mon Sep 17 00:00:00 2001
From: lazaray <104470294+lazaray@users.noreply.github.com>
Date: Fri, 6 May 2022 20:23:07 +0200
Subject: [PATCH] Add support for calculated defines to parser (#2463)
* Add support for calculated defines to parser
* Regenerate parser output
---
parser/raylib_api.json | 4 +-
parser/raylib_api.lua | 4 +-
parser/raylib_api.txt | 4 +-
parser/raylib_api.xml | 4 +-
parser/raylib_parser.c | 159 ++++++++++++++++++++++++++++++++++++++---
5 files changed, 156 insertions(+), 19 deletions(-)
diff --git a/parser/raylib_api.json b/parser/raylib_api.json
index 5006e206..5a6cffe5 100644
--- a/parser/raylib_api.json
+++ b/parser/raylib_api.json
@@ -26,13 +26,13 @@
},
{
"name": "DEG2RAD",
- "type": "UNKNOWN",
+ "type": "FLOAT_MATH",
"value": "(PI/180.0f)",
"description": ""
},
{
"name": "RAD2DEG",
- "type": "UNKNOWN",
+ "type": "FLOAT_MATH",
"value": "(180.0f/PI)",
"description": ""
},
diff --git a/parser/raylib_api.lua b/parser/raylib_api.lua
index 2cbd388f..d4fb9a4d 100644
--- a/parser/raylib_api.lua
+++ b/parser/raylib_api.lua
@@ -26,13 +26,13 @@ return {
},
{
name = "DEG2RAD",
- type = "UNKNOWN",
+ type = "FLOAT_MATH",
value = "(PI/180.0f)",
description = ""
},
{
name = "RAD2DEG",
- type = "UNKNOWN",
+ type = "FLOAT_MATH",
value = "(180.0f/PI)",
description = ""
},
diff --git a/parser/raylib_api.txt b/parser/raylib_api.txt
index 10b9727c..18ef8aff 100644
--- a/parser/raylib_api.txt
+++ b/parser/raylib_api.txt
@@ -23,12 +23,12 @@ Define 004: PI
Description:
Define 005: DEG2RAD
Name: DEG2RAD
- Type: UNKNOWN
+ Type: FLOAT_MATH
Value: (PI/180.0f)
Description:
Define 006: RAD2DEG
Name: RAD2DEG
- Type: UNKNOWN
+ Type: FLOAT_MATH
Value: (180.0f/PI)
Description:
Define 007: RL_MALLOC(sz)
diff --git a/parser/raylib_api.xml b/parser/raylib_api.xml
index 917d26f5..c2bb720a 100644
--- a/parser/raylib_api.xml
+++ b/parser/raylib_api.xml
@@ -5,8 +5,8 @@
-
-
+
+
diff --git a/parser/raylib_parser.c b/parser/raylib_parser.c
index 55d2d648..00751747 100644
--- a/parser/raylib_parser.c
+++ b/parser/raylib_parser.c
@@ -84,7 +84,22 @@
//----------------------------------------------------------------------------------
// Type of parsed define
-typedef enum { UNKNOWN = 0, MACRO, GUARD, INT, LONG, FLOAT, DOUBLE, CHAR, STRING, COLOR } DefineType;
+typedef enum {
+ UNKNOWN = 0,
+ MACRO,
+ GUARD,
+ INT,
+ INT_MATH,
+ LONG,
+ LONG_MATH,
+ FLOAT,
+ FLOAT_MATH,
+ DOUBLE,
+ DOUBLE_MATH,
+ CHAR,
+ STRING,
+ COLOR
+} DefineType;
// Define info data
typedef struct DefineInfo {
@@ -459,6 +474,124 @@ int main(int argc, char* argv[])
MemoryCopy(defines[defineIndex].desc, &linePtr[commentStart], commentLen);
}
+ // Parse defines of type UNKNOWN to find calculated numbers
+ if (defines[defineIndex].type == UNKNOWN)
+ {
+ DefineType largestType = UNKNOWN;
+ bool isMath = true;
+ char *valuePtr = defines[defineIndex].value;
+
+ for (int c = 0; c < TextLength(valuePtr); c++)
+ {
+ char ch = valuePtr[c];
+
+ // Skip operators and whitespace
+ if ((ch == '(') ||
+ (ch == ')') ||
+ (ch == '+') ||
+ (ch == '-') ||
+ (ch == '*') ||
+ (ch == '/') ||
+ (ch == ' ') ||
+ (ch == '\t')) continue;
+
+ // Read number operand
+ else if (isdigit(ch))
+ {
+ bool isNumber = true, isFloat = false;
+ while (!((ch == '(') ||
+ (ch == ')') ||
+ (ch == '*') ||
+ (ch == '/') ||
+ (ch == ' ') ||
+ (ch == '\t') ||
+ (ch == '\0')))
+ {
+ if (ch == '.') isFloat = true;
+ if (!(isdigit(ch) ||
+ ((ch >= 'a') && (ch <= 'f')) ||
+ ((ch >= 'A') && (ch <= 'F')) ||
+ (ch == 'x') ||
+ (ch == 'L') ||
+ (ch == '.') ||
+ (ch == '+') ||
+ (ch == '-')))
+ {
+ isNumber = false;
+ break;
+ }
+ c++;
+ ch = valuePtr[c];
+ }
+ if (isNumber)
+ {
+ // Found a valid number -> update largestType
+ DefineType numberType;
+ if (isFloat) numberType = valuePtr[c - 1] == 'f' ? FLOAT_MATH : DOUBLE_MATH;
+ else numberType = valuePtr[c - 1] == 'L' ? LONG_MATH : INT_MATH;
+
+ if (numberType > largestType) largestType = numberType;
+ }
+ else
+ {
+ isMath = false;
+ break;
+ }
+ }
+
+ // Read string operand
+ else
+ {
+ int operandStart = c;
+ while (!((ch == '\0') ||
+ (ch == ' ') ||
+ (ch == '(') ||
+ (ch == ')') ||
+ (ch == '+') ||
+ (ch == '-') ||
+ (ch == '*') ||
+ (ch == '/')))
+ {
+ c++;
+ ch = valuePtr[c];
+ }
+ int operandEnd = c;
+ int operandLength = operandEnd - operandStart;
+
+ // Search previous defines for operand
+ bool foundOperand = false;
+ for (int previousDefineIndex = 0; previousDefineIndex < defineIndex; previousDefineIndex++)
+ {
+ if (IsTextEqual(defines[previousDefineIndex].name, &valuePtr[operandStart], operandLength))
+ {
+ if ((defines[previousDefineIndex].type >= INT) && (defines[previousDefineIndex].type <= DOUBLE_MATH))
+ {
+ // Found operand and it's a number -> update largestType
+ if (defines[previousDefineIndex].type > largestType) largestType = defines[previousDefineIndex].type;
+ foundOperand = true;
+ }
+ break;
+ }
+ }
+ if (!foundOperand)
+ {
+ isMath = false;
+ break;
+ }
+ }
+ }
+
+ if (isMath)
+ {
+ // Define is a calculated number -> update type
+ if (largestType == INT) largestType = INT_MATH;
+ else if (largestType == LONG) largestType = LONG_MATH;
+ else if (largestType == FLOAT) largestType = FLOAT_MATH;
+ else if (largestType == DOUBLE) largestType = DOUBLE_MATH;
+ defines[defineIndex].type = largestType;
+ }
+ }
+
defineIndex++;
}
defineCount = defineIndex;
@@ -1251,16 +1384,20 @@ 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";
+ case UNKNOWN: return "UNKNOWN";
+ case GUARD: return "GUARD";
+ case MACRO: return "MACRO";
+ case INT: return "INT";
+ case INT_MATH: return "INT_MATH";
+ case LONG: return "LONG";
+ case LONG_MATH: return "LONG_MATH";
+ case FLOAT: return "FLOAT";
+ case FLOAT_MATH: return "FLOAT_MATH";
+ case DOUBLE: return "DOUBLE";
+ case DOUBLE_MATH: return "DOUBLE_MATH";
+ case CHAR: return "CHAR";
+ case STRING: return "STRING";
+ case COLOR: return "COLOR";
}
return "";
}