From 7352b2619117d1bc45ba6a57a89ee1568d64e3ae Mon Sep 17 00:00:00 2001
From: nakst <>
Date: Fri, 18 Feb 2022 13:07:52 +0000
Subject: [PATCH] header generator: merge enums and inttypes

---
 desktop/icons.header    |   2 +-
 desktop/os.header       |  24 +++---
 util/header_generator.c | 171 +++++++++++++---------------------------
 util/render_svg.c       |   2 +-
 4 files changed, 69 insertions(+), 130 deletions(-)

diff --git a/desktop/icons.header b/desktop/icons.header
index d7ceb48..e96d1b6 100644
--- a/desktop/icons.header
+++ b/desktop/icons.header
@@ -1,4 +1,4 @@
-enum EsStandardIcon { // Taken from the elementary icon pack, see res/Icons for license.
+inttype EsStandardIcon enum none { // Taken from the elementary icon pack, see res/Icons for license.
 	ES_ICON_NONE
 	ES_ICON_ACTION_UNAVAILABLE_SYMBOLIC
 	ES_ICON_ADDRESS_BOOK_NEW
diff --git a/desktop/os.header b/desktop/os.header
index 89bbb7d..54897e1 100644
--- a/desktop/os.header
+++ b/desktop/os.header
@@ -890,7 +890,7 @@ inttype EsAnnouncementFlags uint64_t none {
 
 include desktop/icons.header
 
-enum EsFatalError {
+inttype EsFatalError enum none {
 	ES_FATAL_ERROR_ABORT
 	ES_FATAL_ERROR_INCORRECT_FILE_ACCESS
 	ES_FATAL_ERROR_INCORRECT_NODE_TYPE
@@ -905,7 +905,7 @@ enum EsFatalError {
 	ES_FATAL_ERROR_COUNT
 }
 
-private enum EsSyscallType {
+private inttype EsSyscallType enum none {
 	// Memory.
 
 	ES_SYSCALL_MEMORY_ALLOCATE
@@ -1014,7 +1014,7 @@ private enum EsSyscallType {
 	ES_SYSCALL_COUNT
 }
 
-enum EsMessageType {
+inttype EsMessageType enum none {
 	ES_MSG_INVALID				= 0x0000
 		
 	// Window manager messages (don't rearrange; see SendMessageToWindow in kernel/window_manager.cpp):
@@ -1173,7 +1173,7 @@ enum EsMessageType {
 	ES_MSG_USER_END				= 0xBFFF
 }
 
-enum EsCursorStyle {
+inttype EsCursorStyle enum none {
 	ES_CURSOR_NORMAL 
 	ES_CURSOR_TEXT 
 	ES_CURSOR_RESIZE_VERTICAL 
@@ -1206,7 +1206,7 @@ enum EsCursorStyle {
 	ES_CURSOR_COUNT
 }
 
-enum EsWindowStyle {
+inttype EsWindowStyle enum none {
 	ES_WINDOW_NORMAL
 	ES_WINDOW_CONTAINER
 	ES_WINDOW_MENU
@@ -1215,13 +1215,13 @@ enum EsWindowStyle {
 	ES_WINDOW_INSPECTOR
 }
 
-enum EsCheckState {
+inttype EsCheckState enum none {
 	ES_CHECK_UNCHECKED = 0
 	ES_CHECK_CHECKED = 1
 	ES_CHECK_INDETERMINATE = 2
 }
 
-enum EsTransitionType {
+inttype EsTransitionType enum none {
 	ES_TRANSITION_NONE
 	ES_TRANSITION_SLIDE_UP
 	ES_TRANSITION_SLIDE_DOWN
@@ -1245,17 +1245,17 @@ enum EsTransitionType {
 	ES_TRANSITION_SLIDE_DOWN_UNDER
 }
 
-enum EsMemoryProtection {
+inttype EsMemoryProtection enum none {
 	ES_MEMORY_PROTECTION_READ_ONLY
 	ES_MEMORY_PROTECTION_READ_WRITE
 	ES_MEMORY_PROTECTION_EXECUTABLE
 }
 
-enum EsClipboard {
+inttype EsClipboard enum none {
 	ES_CLIPBOARD_PRIMARY
 }
 
-enum EsDeviceType {
+inttype EsDeviceType enum none {
 	ES_DEVICE_OTHER
 	ES_DEVICE_CONTROLLER
 	ES_DEVICE_FILE_SYSTEM
@@ -1271,13 +1271,13 @@ enum EsDeviceType {
 	ES_DEVICE_CLOCK
 }
 
-enum EsClipboardFormat {
+inttype EsClipboardFormat enum none {
 	ES_CLIPBOARD_FORMAT_INVALID
 	ES_CLIPBOARD_FORMAT_TEXT
 	ES_CLIPBOARD_FORMAT_PATH_LIST
 }
 
-enum EsDeviceControlType {
+inttype EsDeviceControlType enum none {
 	ES_DEVICE_CONTROL_BLOCK_GET_INFORMATION = 0x1001
 	ES_DEVICE_CONTROL_BLOCK_READ            = 0x1002
 	ES_DEVICE_CONTROL_BLOCK_WRITE           = 0x1003
diff --git a/util/header_generator.c b/util/header_generator.c
index b88abfb..2ca622a 100644
--- a/util/header_generator.c
+++ b/util/header_generator.c
@@ -1,5 +1,3 @@
-// TODO Merge enums and inttypes.
-
 const char **apiTableEntries;
 
 File output, outputAPIArray, outputSyscallArray, outputDependencies, outputEnumStringsArray;
@@ -48,7 +46,6 @@ typedef struct Token {
 #define ENTRY_ROOT (0)
 #define ENTRY_DEFINE (1)
 #define ENTRY_INTTYPE (2)
-#define ENTRY_ENUM (3)
 #define ENTRY_STRUCT (4)
 #define ENTRY_UNION (5)
 #define ENTRY_FUNCTION (6)
@@ -348,8 +345,8 @@ void ParseAnnotationsUntilSemicolon(Entry *entry) {
 	}
 }
 
-Entry ParseEnum(bool allowImplicitValue) {
-	Entry entry = { .type = ENTRY_ENUM };
+Entry ParseIntType() {
+	Entry entry = { .type = ENTRY_INTTYPE };
 	Token token = NextToken();
 
 	while (true) {
@@ -369,8 +366,6 @@ Entry ParseEnum(bool allowImplicitValue) {
 			while (isspace(*define.define.value)) define.define.value++;
 			position += length;
 			token = NextToken();
-		} else if (!allowImplicitValue) {
-			assert(false);
 		}
 
 		arrput(entry.children, define);
@@ -415,14 +410,6 @@ void ParseFile(Entry *root, const char *name) {
 			currentLine = oldCurrentLine;
 			buffer[position + length] = a;
 			position += length;
-		} else if (token.type == TOKEN_ENUM) {
-			Token name = NextToken();
-			assert(name.type == TOKEN_IDENTIFIER);
-			assert(NextToken().type == TOKEN_LEFT_BRACE);
-			Entry entry = ParseEnum(true);
-			entry.isPrivate = isPrivate;
-			entry.name = TokenToString(name);
-			arrput(root->children, entry);
 		} else if (token.type == TOKEN_STRUCT) {
 			Token structName = NextToken();
 			assert(structName.type == TOKEN_IDENTIFIER);
@@ -436,13 +423,12 @@ void ParseFile(Entry *root, const char *name) {
 			Token bitsetName = NextToken();
 			assert(bitsetName.type == TOKEN_IDENTIFIER);
 			Token storageType = NextToken();
-			assert(storageType.type == TOKEN_IDENTIFIER);
+			assert(storageType.type == TOKEN_IDENTIFIER || storageType.type == TOKEN_ENUM);
 			Token parent = NextToken();
 			assert(parent.type == TOKEN_IDENTIFIER);
 			assert(NextToken().type == TOKEN_LEFT_BRACE);
-			Entry entry = ParseEnum(false);
+			Entry entry = ParseIntType();
 			entry.isPrivate = isPrivate;
-			entry.type = ENTRY_INTTYPE;
 			entry.name = TokenToString(bitsetName);
 			entry.inttype.storageType = TokenToString(storageType);
 			entry.inttype.parent = TokenToString(parent);
@@ -698,46 +684,48 @@ void OutputC(Entry *root) {
 			OutputCRecord(entry, 0);
 			FilePrintFormat(output, "#ifdef %s_MEMBER_FUNCTIONS\n\t%s_MEMBER_FUNCTIONS\n#endif\n", entry->name, entry->name);
 			FilePrintFormat(output, "} %s;\n\n", entry->name);
-		} else if (entry->type == ENTRY_ENUM) {
-			bool isSyscallType = 0 == strcmp(entry->name, "EsSyscallType");
-			FilePrintFormat(output, "typedef enum %s {\n", entry->name);
+		} else if (entry->type == ENTRY_INTTYPE) {
+			if (0 == strcmp(entry->inttype.storageType, "enum")) {
+				bool isSyscallType = 0 == strcmp(entry->name, "EsSyscallType");
+				FilePrintFormat(output, "typedef enum %s {\n", entry->name);
 
-			if (outputEnumStringsArray.ready) {
-				FilePrintFormat(outputEnumStringsArray, "static const EnumString enumStrings_%s[] = {\n", entry->name);
-			}
-
-			for (int i = 0; i < arrlen(entry->children); i++) {
-				if (entry->children[i].define.value) {
-					FilePrintFormat(output, "\t%s = %s,\n", entry->children[i].name, entry->children[i].define.value);
-				} else {
-					FilePrintFormat(output, "\t%s,\n", entry->children[i].name);
+				if (outputEnumStringsArray.ready) {
+					FilePrintFormat(outputEnumStringsArray, "static const EnumString enumStrings_%s[] = {\n", entry->name);
 				}
 
-				if (isSyscallType && outputSyscallArray.ready) {
-					FilePrintFormat(outputSyscallArray, "Do%s,\n", entry->children[i].name);
+				for (int i = 0; i < arrlen(entry->children); i++) {
+					if (entry->children[i].define.value) {
+						FilePrintFormat(output, "\t%s = %s,\n", entry->children[i].name, entry->children[i].define.value);
+					} else {
+						FilePrintFormat(output, "\t%s,\n", entry->children[i].name);
+					}
+
+					if (isSyscallType && outputSyscallArray.ready) {
+						FilePrintFormat(outputSyscallArray, "Do%s,\n", entry->children[i].name);
+					}
+
+					if (outputEnumStringsArray.ready) {
+						FilePrintFormat(outputEnumStringsArray, "\t{ \"%s\", %s },\n", entry->children[i].name, 
+								entry->children[i].define.value ?: "-1");
+					}
 				}
 
 				if (outputEnumStringsArray.ready) {
-					FilePrintFormat(outputEnumStringsArray, "\t{ \"%s\", %s },\n", entry->children[i].name, 
-							entry->children[i].define.value ?: "-1");
+					FilePrintFormat(outputEnumStringsArray, "\t{ nullptr, -1 },\n};\n\n");
 				}
-			}
 
-			if (outputEnumStringsArray.ready) {
-				FilePrintFormat(outputEnumStringsArray, "\t{ nullptr, -1 },\n};\n\n");
-			}
+				FilePrintFormat(output, "} %s;\n\n", entry->name);
+			} else {
+				FilePrintFormat(output, "typedef %s %s;\n", entry->inttype.parent ? entry->inttype.parent : entry->inttype.storageType, entry->name);
 
-			FilePrintFormat(output, "} %s;\n\n", entry->name);
-		} else if (entry->type == ENTRY_INTTYPE) {
-			FilePrintFormat(output, "typedef %s %s;\n", entry->inttype.parent ? entry->inttype.parent : entry->inttype.storageType, entry->name);
-
-			for (int i = 0; i < arrlen(entry->children); i++) {
-				if (0 == memcmp(entry->children[i].define.value, "bit ", 4)) {
-					FilePrintFormat(output, "#define %s ((%s) 1 << %s)\n", 
-							entry->children[i].name, entry->name, entry->children[i].define.value + 4);
-				} else {
-					FilePrintFormat(output, "#define %s ((%s) (%s))\n", 
-							entry->children[i].name, entry->name, entry->children[i].define.value);
+				for (int i = 0; i < arrlen(entry->children); i++) {
+					if (0 == memcmp(entry->children[i].define.value, "bit ", 4)) {
+						FilePrintFormat(output, "#define %s ((%s) 1 << %s)\n", 
+								entry->children[i].name, entry->name, entry->children[i].define.value + 4);
+					} else {
+						FilePrintFormat(output, "#define %s ((%s) (%s))\n", 
+								entry->children[i].name, entry->name, entry->children[i].define.value);
+					}
 				}
 			}
 		} else if (entry->type == ENTRY_API_TYPE) {
@@ -922,15 +910,6 @@ void OutputOdinFunction(Entry *entry, Entry *root) {
 			} else if (0 == strcmp(initialValue, "FLAGS_DEFAULT")) {
 				initialValue = "{}";
 			} else {
-				for (int i = 0; i < arrlen(root->children); i++) {
-					Entry *entry = root->children + i;
-
-					if (entry->type == ENTRY_ENUM && 0 == strcmp(variable->variable.type, entry->name)) {
-						needLeadingDot = true;
-						break;
-					}
-				}
-
 				for (int i = 0; i < arrlen(root->children); i++) {
 					Entry *entry = root->children + i;
 
@@ -1013,7 +992,6 @@ void OutputOdin(Entry *root) {
 			const char *name = TrimPrefix(entry->name);
 			const char *value = OdinReplaceTypes(entry->define.value, false);
 
-			const char *enumPrefix = NULL;
 			char e[64];
 			int ep = 0;
 
@@ -1027,44 +1005,23 @@ void OutputOdin(Entry *root) {
 				}
 			}
 
-			for (int i = 0; i < arrlen(root->children); i++) {
-				if (root->children[i].type == ENTRY_ENUM) {
-					for (int j = 0; j < arrlen(root->children[i].children); j++) {
-						const char *enumName = TrimPrefix(root->children[i].children[j].name);
-
-						if (0 == strcmp(enumName, e)) {
-							enumPrefix = TrimPrefix(root->children[i].name);
-							value = enumName;
-							goto gotEnumPrefix;
-						}
-					}
-				}
-			}
-
-			gotEnumPrefix:;
-			FilePrintFormat(output, "%s :: %s%s%s;\n", name, enumPrefix ? enumPrefix : "", enumPrefix ? "." : "", value);
+			FilePrintFormat(output, "%s :: %s;\n", name, value);
 		} else if (entry->type == ENTRY_STRUCT) {
 			FilePrintFormat(output, "%s :: struct {\n", TrimPrefix(entry->name));
 			OutputOdinRecord(entry, 0);
-			FilePrintFormat(output, "}\n");
-		} else if (entry->type == ENTRY_ENUM) {
-			FilePrintFormat(output, "%s :: enum i32 {\n", TrimPrefix(entry->name));
-
-			for (int i = 0; i < arrlen(entry->children); i++) {
-				if (entry->children[i].define.value) {
-					FilePrintFormat(output, "\t%s = %s,\n", TrimPrefix(entry->children[i].name), entry->children[i].define.value);
-				} else {
-					FilePrintFormat(output, "\t%s,\n", TrimPrefix(entry->children[i].name));
-				}
-			}
-
 			FilePrintFormat(output, "}\n");
 		} else if (entry->type == ENTRY_INTTYPE) {
+			uint32_t autoIndex = 0;
+
 			FilePrintFormat(output, "%s :: %s;\n", TrimPrefix(entry->name), 
-					entry->inttype.parent ? TrimPrefix(entry->inttype.parent) : entry->inttype.storageType);
+					entry->inttype.parent ? TrimPrefix(entry->inttype.parent) 
+					: 0 == strcmp(entry->inttype.storageType, "enum") ? "i32" : entry->inttype.storageType);
 
 			for (int i = 0; i < arrlen(entry->children); i++) {
-				if (0 == memcmp(entry->children[i].define.value, "bit ", 4)) {
+				if (!entry->children[i].define.value) {
+					FilePrintFormat(output, "%s :: %d;\n", 
+							TrimPrefix(entry->children[i].name), autoIndex++);
+				} else if (0 == memcmp(entry->children[i].define.value, "bit ", 4)) {
 					FilePrintFormat(output, "%s :: 1 << %s;\n", 
 							TrimPrefix(entry->children[i].name), entry->children[i].define.value + 4);
 				} else {
@@ -1278,18 +1235,6 @@ void OutputZig(Entry *root) {
 		} else if (entry->type == ENTRY_STRUCT) {
 			FilePrintFormat(output, "pub const %s = extern struct {\n", TrimPrefix(entry->name));
 			OutputZigRecord(entry, 0, false);
-			FilePrintFormat(output, "};\n");
-		} else if (entry->type == ENTRY_ENUM) {
-			FilePrintFormat(output, "pub const %s = extern enum {\n", TrimPrefix(entry->name));
-
-			for (int i = 0; i < arrlen(entry->children); i++) {
-				if (entry->children[i].define.value) {
-					FilePrintFormat(output, "    %s = %s,\n", TrimPrefix(entry->children[i].name), ZigRemoveTabs(entry->children[i].define.value));
-				} else {
-					FilePrintFormat(output, "    %s,\n", TrimPrefix(entry->children[i].name));
-				}
-			}
-
 			FilePrintFormat(output, "};\n");
 		} else if (entry->type == ENTRY_API_TYPE) {
 			bool hasParent = 0 != strcmp(entry->apiType.parent, "none");
@@ -1299,14 +1244,20 @@ void OutputZig(Entry *root) {
 		} else if (entry->type == ENTRY_TYPE_NAME) {
 			FilePrintFormat(output, "pub const %s = %s;\n", TrimPrefix(entry->name), TrimPrefix(ZigReplaceTypes(entry->oldTypeName, true)));
 		} else if (entry->type == ENTRY_INTTYPE) {
+			uint32_t autoIndex = 0;
+
 			FilePrintFormat(output, "pub const %s = %s;\n", TrimPrefix(entry->name), 
-					TrimPrefix(ZigReplaceTypes(entry->inttype.storageType, true)));
+					0 == strcmp(entry->inttype.storageType, "enum") ? "i32" 
+					: TrimPrefix(ZigReplaceTypes(entry->inttype.storageType, true)));
 
 			for (int i = 0; i < arrlen(entry->children); i++) {
-				if (0 == memcmp(entry->children[i].define.value, "bit ", 4)) {
+				if (!entry->children[i].define.value) {
+					FilePrintFormat(output, "pub const %s = %d;\n", 
+							TrimPrefix(entry->children[i].name), autoIndex++);
+				} else if (0 == memcmp(entry->children[i].define.value, "bit ", 4)) {
 					FilePrintFormat(output, "pub const %s = 1 << %s;\n", 
 							TrimPrefix(entry->children[i].name), entry->children[i].define.value + 4);
-				} else {
+				} else if (entry->children[i].define.value) {
 					FilePrintFormat(output, "pub const %s = %s;\n", 
 							TrimPrefix(entry->children[i].name), entry->children[i].define.value);
 				}
@@ -1471,9 +1422,6 @@ void OutputScript(Entry *root) {
 									if (ScriptWriteBasicType(root->children[k].variable.type)) {
 										foundType = true;
 									}
-								} else if (root->children[k].type == ENTRY_ENUM) {
-									FilePrintFormat(output, "%s", root->children[k].name);
-									foundType = true;
 								} else if (root->children[k].type == ENTRY_STRUCT) {
 									FilePrintFormat(output, "%s", root->children[k].name);
 									foundType = true;
@@ -1576,9 +1524,6 @@ void OutputScript(Entry *root) {
 								if (ScriptWriteBasicType(root->children[k].variable.type)) {
 									foundType = true;
 								}
-							} else if (root->children[k].type == ENTRY_ENUM) {
-								FilePrintFormat(output, "%s", root->children[k].name);
-								foundType = true;
 							} else if (root->children[k].type == ENTRY_STRUCT) {
 								FilePrintFormat(output, "%s", root->children[k].name);
 								foundType = true;
@@ -1674,10 +1619,6 @@ void OutputScript(Entry *root) {
 							FilePrintFormat(output, "%s", root->children[k].name);
 							foundType = true;
 							break;
-						} else if (root->children[k].type == ENTRY_ENUM && e.variable.pointer == 0) {
-							FilePrintFormat(output, "%s", root->children[k].name);
-							foundType = true;
-							break;
 						} else if (root->children[k].type == ENTRY_STRUCT && e.variable.pointer == 0) {
 							FilePrintFormat(output, "%s", root->children[k].name);
 							foundType = true;
@@ -1761,8 +1702,6 @@ int AnalysisResolve(Entry *root, Entry e, Entry **unresolved, Entry *resolved, E
 
 		if (root->children[k].type == ENTRY_TYPE_NAME && e.variable.pointer == 0) {
 			return 1;
-		} else if (root->children[k].type == ENTRY_ENUM && e.variable.pointer == 0) {
-			return 1;
 		} else if (root->children[k].type == ENTRY_INTTYPE && e.variable.pointer == 0) {
 			return 1;
 		} else if (root->children[k].type == ENTRY_API_TYPE && e.variable.pointer == 1) {
diff --git a/util/render_svg.c b/util/render_svg.c
index e342b87..6c9d171 100644
--- a/util/render_svg.c
+++ b/util/render_svg.c
@@ -164,7 +164,7 @@ void GenerateMainIconPack() {
 
 	{
 		FILE *f = fopen("desktop/icons.header", "wb");
-		fprintf(f, "%s", "enum EsStandardIcon { // Taken from the elementary icon pack, see res/Icons for license.\n\tES_ICON_NONE\n");
+		fprintf(f, "%s", "inttype EsStandardIcon enum none { // Taken from the elementary icon pack, see res/Icons for license.\n\tES_ICON_NONE\n");
 		fclose(f);
 	}