summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRob Loach <[email protected]>2021-06-06 04:21:56 -0400
committerGitHub <[email protected]>2021-06-06 10:21:56 +0200
commit32f3f53718a5f8fb30c38a05dbd72760a17faabc (patch)
tree6a10828db62d250df5ffe225d58cb819f4fab171
parent246798a0ba12abe4c418c613bfcf7700d637d71b (diff)
downloadraylib-32f3f53718a5f8fb30c38a05dbd72760a17faabc.tar.gz
raylib-32f3f53718a5f8fb30c38a05dbd72760a17faabc.zip
parser: Add JSON support with --json (#1812)
-rw-r--r--parser/README.md7
-rw-r--r--parser/raylib_parser.c173
2 files changed, 155 insertions, 25 deletions
diff --git a/parser/README.md b/parser/README.md
index a21d6787..6deaff69 100644
--- a/parser/README.md
+++ b/parser/README.md
@@ -9,6 +9,13 @@ All data is separated into parts, usually as strings. The following types are us
Check `raylib_parser.c` for details about those structs.
+## Command Line Arguments
+
+The parser can take a few options...
+
+- `--help` Displays help information about the parser
+- `--json` Outputs the header information in JSON format
+
## Constraints
This parser is specifically designed to work with raylib.h, so, it has some constraints:
diff --git a/parser/raylib_parser.c b/parser/raylib_parser.c
index 141901f5..e60f7de8 100644
--- a/parser/raylib_parser.c
+++ b/parser/raylib_parser.c
@@ -66,6 +66,8 @@
#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)
+enum OutputFormat { PlainText, JSON }; // Which format the header information should be in
+
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
@@ -107,10 +109,24 @@ char **GetTextLines(const char *buffer, int length, int *linesCount);
void GetDataTypeAndName(const char *typeName, int typeNameLen, char *type, char *name);
bool IsTextEqual(const char *text1, const char *text2, unsigned int count);
void MemoryCopy(void *dest, const void *src, unsigned int count);
+char* CharReplace(char* text, char search, char replace);
// Main entry point
-int main()
+int main(int argc, char* argv[])
{
+ // Help
+ if (IsTextEqual(argv[1], "--help", 6)) {
+ printf("Usage:\n");
+ printf(" raylib_parser [--json]\n");
+ return 0;
+ }
+
+ // Allow changing the output format.
+ int outputFormat = 0;
+ if (IsTextEqual(argv[1], "--json", 6)) {
+ outputFormat = JSON;
+ }
+
int length = 0;
char *buffer = LoadFileText("../src/raylib.h", &length);
@@ -466,32 +482,130 @@ int main()
// funcs[] -> We have all the functions decomposed into pieces for further analysis
// Print structs info
- printf("\nStructures found: %i\n\n", structCount);
- for (int i = 0; i < structCount; i++)
+ switch (outputFormat)
{
- printf("Struct %02i: %s (%i fields)\n", i + 1, structs[i].name, structs[i].fieldCount);
- //printf("Description: %s\n", structs[i].desc);
- for (int f = 0; f < structs[i].fieldCount; f++) printf(" Fields %i: %s %s %s\n", f + 1, structs[i].fieldType[f], structs[i].fieldName[f], structs[i].fieldDesc[f]);
- }
+ case PlainText: {
+ printf("\nStructures found: %i\n\n", structCount);
+ for (int i = 0; i < structCount; i++)
+ {
+ printf("Struct %02i: %s (%i fields)\n", i + 1, structs[i].name, structs[i].fieldCount);
+ //printf("Description: %s\n", structs[i].desc);
+ for (int f = 0; f < structs[i].fieldCount; f++) printf(" Fields %i: %s %s %s\n", f + 1, structs[i].fieldType[f], structs[i].fieldName[f], structs[i].fieldDesc[f]);
+ }
- // Print enums info
- printf("\nEnums found: %i\n\n", enumCount);
- for (int i = 0; i < enumCount; i++)
- {
- printf("Enum %02i: %s (%i values)\n", i + 1, enums[i].name, enums[i].valueCount);
- //printf("Description: %s\n", enums[i].desc);
- for (int e = 0; e < enums[i].valueCount; e++) printf(" Value %s: %i\n", enums[i].valueName[e], enums[i].valueInteger[e]);
- }
-
- // Print function info
- printf("\nFunctions found: %i\n\n", funcCount);
- for (int i = 0; i < funcCount; i++)
- {
- printf("Function %03i: %s() (%i input parameters)\n", i + 1, funcs[i].name, funcs[i].paramCount);
- printf(" Description: %s\n", funcs[i].desc);
- printf(" Return type: %s\n", funcs[i].retType);
- for (int p = 0; p < funcs[i].paramCount; p++) printf(" Param %i: %s (type: %s)\n", p + 1, funcs[i].paramName[p], funcs[i].paramType[p]);
- if (funcs[i].paramCount == 0) printf(" No input parameters\n");
+ // Print enums info
+ printf("\nEnums found: %i\n\n", enumCount);
+ for (int i = 0; i < enumCount; i++)
+ {
+ printf("Enum %02i: %s (%i values)\n", i + 1, enums[i].name, enums[i].valueCount);
+ //printf("Description: %s\n", enums[i].desc);
+ for (int e = 0; e < enums[i].valueCount; e++) printf(" Value %s: %i\n", enums[i].valueName[e], enums[i].valueInteger[e]);
+ }
+
+ // Print function info
+ printf("\nFunctions found: %i\n\n", funcCount);
+ for (int i = 0; i < funcCount; i++)
+ {
+ printf("Function %03i: %s() (%i input parameters)\n", i + 1, funcs[i].name, funcs[i].paramCount);
+ printf(" Description: %s\n", funcs[i].desc);
+ printf(" Return type: %s\n", funcs[i].retType);
+ for (int p = 0; p < funcs[i].paramCount; p++) printf(" Param %i: %s (type: %s)\n", p + 1, funcs[i].paramName[p], funcs[i].paramType[p]);
+ if (funcs[i].paramCount == 0) printf(" No input parameters\n");
+ }
+ } break;
+ case JSON: {
+ printf("{\n");
+ printf(" \"structs\": [\n");
+ for (int i = 0; i < structCount; i++)
+ {
+ printf(" {\n");
+ printf(" \"name\": \"%s\",\n", structs[i].name);
+ printf(" \"description\": \"%s\",\n", structs[i].desc);
+ printf(" \"fields\": [\n");
+ for (int f = 0; f < structs[i].fieldCount; f++)
+ {
+ printf(" {\n");
+ printf(" \"name\": \"%s\",\n", structs[i].fieldName[f]),
+ printf(" \"type\": \"%s\",\n", structs[i].fieldType[f]),
+ printf(" \"description\": \"%s\"\n", structs[i].fieldDesc[f] + 3),
+ printf(" }");
+ if (f < structs[i].fieldCount - 1)
+ printf(",\n");
+ else
+ printf("\n");
+ }
+ printf(" ]\n");
+ printf(" }");
+ if (i < structCount - 1)
+ printf(",\n");
+ else
+ printf("\n");
+ }
+ printf(" ],\n");
+
+ // Print enums info
+ printf(" \"enums\": [\n");
+ for (int i = 0; i < enumCount; i++)
+ {
+ printf(" {\n");
+ printf(" \"name\": \"%s\",\n", enums[i].name);
+ printf(" \"description\": \"%s\",\n", enums[i].desc + 3);
+ printf(" \"values\": [\n");
+ for (int e = 0; e < enums[i].valueCount; e++)
+ {
+ printf(" {\n");
+ printf(" \"name\": \"%s\",\n", enums[i].valueName[e]),
+ printf(" \"value\": %i,\n", enums[i].valueInteger[e]),
+ printf(" \"description\": \"%s\"\n", enums[i].valueDesc[e] + 3),
+ printf(" }");
+ if (e < enums[i].valueCount - 1)
+ printf(",\n");
+ else
+ printf("\n");
+ }
+ printf(" ]\n");
+ printf(" }");
+ if (i < enumCount - 1)
+ printf(",\n");
+ else
+ printf("\n");
+ }
+ printf(" ],\n");
+
+ // Print function info
+ printf(" \"functions\": [\n");
+ for (int i = 0; i < funcCount; i++)
+ {
+ printf(" {\n");
+ printf(" \"name\": \"%s\",\n", funcs[i].name);
+ printf(" \"description\": \"%s\",\n", CharReplace(funcs[i].desc, '\\', ' ') + 3);
+ printf(" \"returnType\": \"%s\"", funcs[i].retType);
+
+ if (funcs[i].paramCount == 0)
+ printf("\n");
+ else
+ {
+ printf(",\n \"params\": {\n");
+ for (int p = 0; p < funcs[i].paramCount; p++)
+ {
+ printf(" \"%s\": \"%s\"", funcs[i].paramName[p], funcs[i].paramType[p]);
+ if (p < funcs[i].paramCount - 1)
+ printf(",\n");
+ else
+ printf("\n");
+ }
+ printf(" }\n");
+ }
+ printf(" }");
+
+ if (i < funcCount - 1)
+ printf(",\n");
+ else
+ printf("\n");
+ }
+ printf(" ]\n");
+ printf("}\n");
+ } break;
}
free(funcs);
@@ -631,6 +745,15 @@ bool IsTextEqual(const char *text1, const char *text2, unsigned int count)
return result;
}
+// Search and replace a character within a string.
+char* CharReplace(char* text, char search, char replace)
+{
+ for (int i = 0; text[i] != '\0'; i++)
+ if (text[i] == search)
+ text[i] = replace;
+ return text;
+}
+
/*
// Replace text string
// REQUIRES: strlen(), strstr(), strncpy(), strcpy() -> TODO: Replace by custom implementations!