aboutsummaryrefslogtreecommitdiff
path: root/contrib/enumutils_describe.py
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2018-10-26 14:43:22 +0200
committerShauren <shauren.trinity@gmail.com>2021-11-15 21:34:03 +0100
commitc977087d589e8b1696eccb0730284f056c731b04 (patch)
tree72889b0ef8323a61beeddf6a846c3d97ee1846e1 /contrib/enumutils_describe.py
parentdf2f6ad219a18576617e4fc3f4cd60b530ac9d9a (diff)
Core/Misc: Partial merge of 3.3.5-dbedit:
- Added SmartEnum.h for enum iteration, stringification, and more, courtesy of krabicezpapundeklu/smart_enum - Moved a bunch of enums in SharedDefines.h to the new system - Miscellaneous utility methods ported Core/Util: Redesign SmartEnum to properly work for large enums (>64 entries) and play nice with IDEs (PR #22768) (cherry picked from commit 338e8ba0fea8b4b15120c96fff15a6c4b1a52593) (cherry picked from commit f7ca0877a3736000a6e3b4ed09ac5f08b4d8e3f0) (cherry picked from commit 207093475a177e9fd29696e80fdd06a11324782d) (cherry picked from commit ee68cf33921944fd3f8c188044906998cf10ff2a) (cherry picked from commit c16d461e16f0704bb11040faff30953d33ba2188) (cherry picked from commit f6b0d99e2c0bc22b44d6f3cfdae50cbba7d51de8) (cherry picked from commit bc1f456125c1b6c90617a514152d69c40ce64886)
Diffstat (limited to 'contrib/enumutils_describe.py')
-rw-r--r--contrib/enumutils_describe.py154
1 files changed, 154 insertions, 0 deletions
diff --git a/contrib/enumutils_describe.py b/contrib/enumutils_describe.py
new file mode 100644
index 00000000000..6da72d25198
--- /dev/null
+++ b/contrib/enumutils_describe.py
@@ -0,0 +1,154 @@
+from re import compile, MULTILINE
+from os import walk, getcwd
+
+notice = ('''/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+''')
+
+if not getcwd().endswith('src'):
+ print('Run this from the src directory!')
+ print('(Invoke as \'python ../contrib/enumutils_describe.py\')')
+ exit(1)
+
+EnumPattern = compile(r'//\s*EnumUtils: DESCRIBE THIS\s+enum\s+([0-9A-Za-z]+)[^\n]*\s*{([^}]+)};')
+EnumValuesPattern = compile(r'\s+.+?(,|$)[^\n]*')
+EnumValueNamePattern = compile(r'^\s*([a-zA-Z0-9_]+)', flags=MULTILINE)
+EnumValueSkipLinePattern = compile(r'^\s*//')
+EnumValueCommentPattern = compile(r'//,?[ \t]*([^\n]+)$')
+CommentMatchFormat = compile(r'^(((TITLE +(.+?))|(DESCRIPTION +(.+?))) *){1,2}$')
+CommentSkipFormat = compile(r'^SKIP *$')
+
+def strescape(str):
+ res = ''
+ for char in str:
+ if char in ('\\', '"') or not (32 <= ord(char) < 127):
+ res += ('\\%03o' % ord(char))
+ else:
+ res += char
+ return '"' + res + '"'
+
+def processFile(path, filename):
+ input = open('%s/%s.h' % (path, filename),'r')
+ if input is None:
+ print('Failed to open %s.h' % filename)
+ return
+
+ file = input.read()
+
+ enums = []
+ for enum in EnumPattern.finditer(file):
+ name = enum.group(1)
+ values = []
+ for value in EnumValuesPattern.finditer(enum.group(2)):
+ valueData = value.group(0)
+
+ valueNameMatch = EnumValueNamePattern.search(valueData)
+ if valueNameMatch is None:
+ if EnumValueSkipLinePattern.search(valueData) is None:
+ print('Name of value not found: %s' % repr(valueData))
+ continue
+ valueName = valueNameMatch.group(1)
+
+ valueCommentMatch = EnumValueCommentPattern.search(valueData)
+ valueComment = None
+ if valueCommentMatch:
+ valueComment = valueCommentMatch.group(1)
+
+ valueTitle = None
+ valueDescription = None
+
+ if valueComment is not None:
+ if CommentSkipFormat.match(valueComment) is not None:
+ continue
+ commentMatch = CommentMatchFormat.match(valueComment)
+ if commentMatch is not None:
+ valueTitle = commentMatch.group(4)
+ valueDescription = commentMatch.group(6)
+ else:
+ valueDescription = valueComment
+
+ if valueTitle is None:
+ valueTitle = valueName
+ if valueDescription is None:
+ valueDescription = ''
+
+ values.append((valueName, valueTitle, valueDescription))
+
+ enums.append((name, values))
+ print('%s.h: Enum %s parsed with %d values' % (filename, name, len(values)))
+
+ if not enums:
+ return
+
+ print('Done parsing %s.h (in %s)\n' % (filename, path))
+ output = open('%s/enuminfo_%s.cpp' % (path, filename), 'w')
+ if output is None:
+ print('Failed to create enuminfo_%s.cpp' % filename)
+ return
+
+ # write output file
+ output.write(notice)
+ output.write('#include "%s.h"\n' % filename)
+ output.write('#include "Define.h"\n')
+ output.write('#include "SmartEnum.h"\n')
+ output.write('#include <stdexcept>\n')
+ output.write('\n')
+ output.write('namespace Trinity\n')
+ output.write('{\n')
+ output.write('namespace Impl\n')
+ output.write('{\n')
+ for name, values in enums:
+ tag = ('data for enum \'%s\' in \'%s.h\' auto-generated' % (name, filename))
+ output.write('\n')
+ output.write('/*' + ('*'*(len(tag)+2)) + '*\\\n')
+ output.write('|* ' + tag + ' *|\n')
+ output.write('\\*' + ('*'*(len(tag)+2)) + '*/\n')
+ output.write('template <>\n')
+ output.write('TC_API_EXPORT EnumText EnumUtils<%s>::ToString(%s value)\n' % (name, name))
+ output.write('{\n')
+ output.write(' switch (value)\n')
+ output.write(' {\n')
+ for label, title, description in values:
+ output.write(' case %s: return { %s, %s, %s };\n' % (label, strescape(label), strescape(title), strescape(description)))
+ output.write(' default: throw std::out_of_range("value");\n')
+ output.write(' }\n')
+ output.write('}\n')
+ output.write('\n')
+ output.write('template <>\n');
+ output.write('TC_API_EXPORT size_t EnumUtils<%s>::Count() { return %d; }\n' % (name, len(values)))
+ output.write('\n')
+ output.write('template <>\n');
+ output.write('TC_API_EXPORT %s EnumUtils<%s>::FromIndex(size_t index)\n' % (name, name))
+ output.write('{\n')
+ output.write(' switch (index)\n')
+ output.write(' {\n')
+ for i in range(len(values)):
+ output.write(' case %d: return %s;\n' % (i, values[i][0]))
+ output.write(' default: throw std::out_of_range("index");\n')
+ output.write(' }\n')
+ output.write('}\n')
+
+ output.write('}\n')
+ output.write('}\n')
+
+FilenamePattern = compile(r'^(.+)\.h$')
+for root, dirs, files in walk('.'):
+ for n in files:
+ nameMatch = FilenamePattern.match(n)
+ if nameMatch is not None:
+ processFile(root, nameMatch.group(1))