From f73d13c410f9161b98e72bc333f3a9e73c90d416 Mon Sep 17 00:00:00 2001 From: Robert Burnett Date: Sun, 28 Jun 2026 14:29:38 -0500 Subject: [PATCH] Add S-Expression output to rlparser.c --- tools/rlparser/Makefile | 4 +- tools/rlparser/rlparser.c | 133 +++++++++++++++++++++++++++++++++++++- 2 files changed, 133 insertions(+), 4 deletions(-) diff --git a/tools/rlparser/Makefile b/tools/rlparser/Makefile index a645f7f41..a79900691 100644 --- a/tools/rlparser/Makefile +++ b/tools/rlparser/Makefile @@ -79,6 +79,7 @@ raylib_api: ../../src/raylib.h rlparser FORMAT=JSON EXTENSION=json $(MAKE) raylib_api.json FORMAT=XML EXTENSION=xml $(MAKE) raylib_api.xml FORMAT=LUA EXTENSION=lua $(MAKE) raylib_api.lua + FORMAT=SEXPR EXTENSION=sexpr $(MAKE) raylib_api.sexpr # rlparser execution: [raylib.h] parse, generating some output files raylib_api.$(EXTENSION): ../../src/raylib.h rlparser @@ -112,7 +113,8 @@ all: rlparser FORMAT=JSON EXTENSION=json $(MAKE) parse FORMAT=XML EXTENSION=xml $(MAKE) parse FORMAT=LUA EXTENSION=lua $(MAKE) parse + FORMAT=SEXPR EXTENSION=sexpr $(MAKE) parse # Clean rlparser and generated output files clean: - rm -f rlparser *.json *.txt *.xml *.lua + rm -f rlparser *.json *.txt *.xml *.lua *.sexpr diff --git a/tools/rlparser/rlparser.c b/tools/rlparser/rlparser.c index dc2afe114..83c8964bd 100644 --- a/tools/rlparser/rlparser.c +++ b/tools/rlparser/rlparser.c @@ -146,7 +146,7 @@ typedef struct FunctionInfo { } FunctionInfo; // Output format for parsed data -typedef enum { DEFAULT = 0, JSON, XML, LUA, CODE } OutputFormat; +typedef enum { DEFAULT = 0, JSON, XML, LUA, SEXPR, CODE } OutputFormat; //---------------------------------------------------------------------------------- // Global Variables Definition @@ -1062,6 +1062,7 @@ int main(int argc, char *argv[]) else if (outputFormat == JSON) printf("\nOutput format: JSON\n\n"); else if (outputFormat == XML) printf("\nOutput format: XML\n\n"); else if (outputFormat == LUA) printf("\nOutput format: LUA\n\n"); + else if (outputFormat == SEXPR) printf("\nOutput format: SEXPR\n\n"); else if (outputFormat == CODE) printf("\nOutput format: CODE\n\n"); ExportParsedData(outFileName, outputFormat); @@ -1098,10 +1099,10 @@ static void ShowCommandLineInfo(void) printf(" -i, --input : Define input header file to parse.\n"); printf(" NOTE: If not specified, defaults to: raylib.h\n\n"); printf(" -o, --output : Define output file and format.\n"); - printf(" Supported extensions: .txt, .json, .xml, .lua, .h\n"); + printf(" Supported extensions: .txt, .json, .xml, .lua, .sexpr, .h\n"); printf(" NOTE: If not specified, defaults to: raylib_api.txt\n\n"); printf(" -f, --format : Define output format for parser data.\n"); - printf(" Supported types: DEFAULT, JSON, XML, LUA, CODE\n\n"); + printf(" Supported types: DEFAULT, JSON, XML, LUA, SEXPR, CODE\n\n"); printf(" -d, --define : Define functions specifiers (i.e. RLAPI for raylib.h, RMAPI for raymath.h, etc.)\n"); printf(" NOTE: If no specifier defined, defaults to: RLAPI\n\n"); printf(" -t, --truncate : Define string to truncate input after (i.e. \"RLGL IMPLEMENTATION\" for rlgl.h)\n"); @@ -1154,6 +1155,7 @@ static void ProcessCommandLine(int argc, char *argv[]) else if (IsTextEqual(argv[i + 1], "JSON\0", 5)) outputFormat = JSON; else if (IsTextEqual(argv[i + 1], "XML\0", 4)) outputFormat = XML; else if (IsTextEqual(argv[i + 1], "LUA\0", 4)) outputFormat = LUA; + else if (IsTextEqual(argv[i + 1], "SEXPR\0", 4)) outputFormat = SEXPR; else if (IsTextEqual(argv[i + 1], "CODE\0", 5)) outputFormat = CODE; } else printf("WARNING: No format parameters provided\n"); @@ -2007,6 +2009,131 @@ static void ExportParsedData(const char *fileName, int format) fprintf(outFile, " }\n"); fprintf(outFile, "}\n"); } break; + case SEXPR: + { + fprintf(outFile, "("); + + // Print defines info + fprintf(outFile, "(defines\n"); + for (int i = 0; i < defineCount; i++) + { + if(i != 0) 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\"))", defines[i].desc); + } + fprintf(outFile, ")\n\n"); + + // Print structs info + fprintf(outFile, " (structs\n"); + for (int i = 0; i < structCount; i++) + { + if(i != 0) fprintf(outFile, "\n\n"); + fprintf(outFile, " ((name \"%s\")\n", structs[i].name); + fprintf(outFile, " (description \"%s\")\n", EscapeBackslashes(structs[i].desc)); + fprintf(outFile, " (fields "); + for (int f = 0; f < structs[i].fieldCount; f++) + { + fprintf(outFile, "\n ((type \"%s\")\n", structs[i].fieldType[f]); + fprintf(outFile, " (name \"%s\")\n", structs[i].fieldName[f]); + fprintf(outFile, " (description \"%s\"))", EscapeBackslashes(structs[i].fieldDesc[f])); + } + fprintf(outFile, "))"); + } + fprintf(outFile, ")\n\n"); + + // Print aliases info + fprintf(outFile, " (aliases\n"); + for (int i = 0; i < aliasCount; i++) + { + if(i != 0) fprintf(outFile, "\n\n"); + fprintf(outFile, " ((type \"%s\")\n", aliases[i].type); + fprintf(outFile, " (name \"%s\")\n", aliases[i].name); + fprintf(outFile, " (description \"%s\"))", aliases[i].desc); + } + fprintf(outFile, ")\n\n"); + + // Print enums info + fprintf(outFile, " (enums\n"); + for (int i = 0; i < enumCount; i++) + { + if(i != 0) fprintf(outFile, "\n\n"); + fprintf(outFile, " ((name \"%s\")\n", enums[i].name); + fprintf(outFile, " (description \"%s\")\n", EscapeBackslashes(enums[i].desc)); + fprintf(outFile, " (values\n"); + for (int e = 0; e < enums[i].valueCount; e++) + { + if(e != 0) fprintf(outFile, "\n\n"); + fprintf(outFile, " ((name \"%s\")\n", enums[i].valueName[e]); + fprintf(outFile, " (value %i)\n", enums[i].valueInteger[e]); + fprintf(outFile, " (description \"%s\"))", EscapeBackslashes(enums[i].valueDesc[e])); + } + fprintf(outFile, "))"); + } + fprintf(outFile, ")\n\n"); + + // Print callbacks info + fprintf(outFile, " (callbacks\n"); + for (int i = 0; i < callbackCount; i++) + { + if(i != 0) fprintf(outFile, "\n\n"); + fprintf(outFile, " ((name \"%s\")\n", callbacks[i].name); + fprintf(outFile, " (description \"%s\")\n", EscapeBackslashes(callbacks[i].desc)); + fprintf(outFile, " (return-type \"%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++) + { + if(p != 0) fprintf(outFile, "\n"); + fprintf(outFile, " ((type \"%s\") (name \"%s\"))", callbacks[i].paramType[p], callbacks[i].paramName[p]); + } + fprintf(outFile, ")"); + } + fprintf(outFile, ")"); + } + fprintf(outFile, ")\n\n"); + + // Print functions info + fprintf(outFile, " (functions\n"); + for (int i = 0; i < funcCount; i++) + { + if(i != 0) fprintf(outFile, "\n\n"); + fprintf(outFile, " ((name \"%s\")\n", funcs[i].name); + fprintf(outFile, " (description \"%s\")\n", EscapeBackslashes(funcs[i].desc)); + fprintf(outFile, " (return-type \"%s\")", funcs[i].retType); + + if (funcs[i].paramCount == 0) fprintf(outFile, ""); + else + { + fprintf(outFile, "\n (params\n"); + for (int p = 0; p < funcs[i].paramCount; p++) + { + if(p != 0) fprintf(outFile, "\n"); + fprintf(outFile, " ((type \"%s\") (name \"%s\"))", funcs[i].paramType[p], funcs[i].paramName[p]); + } + fprintf(outFile, ")"); + } + fprintf(outFile, ")"); + } + fprintf(outFile, ")"); + fprintf(outFile, ")\n"); + } break; + case CODE: default: break; }