This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 84c66505aa1632a7f3c33ac8762ea68cc1459a07
Author: xuxingliang <[email protected]>
AuthorDate: Wed Oct 9 11:51:43 2024 +0800

    tools/gdb: add function to convert C enum to python Enum class
    
    Usage:
    (gdb) py NX_INITSTATE = utils.enum("enum nx_initstate_e")
    (gdb) py print(list(NX_INITSTATE))
    [<NX_INITSTATE_E.POWERUP: 0>, <NX_INITSTATE_E.BOOT: 1>, 
<NX_INITSTATE_E.TASKLISTS: 2>, <NX_INITSTATE_E.MEMORY: 3>, 
<NX_INITSTATE_E.HARDWARE: 4>, <NX_INITSTATE_E.OSREADY: 5>, 
<NX_INITSTATE_E.IDLELOOP: 6>, <NX_INITSTATE_E.PANIC: 7>]
    (gdb) py print(NX_INITSTATE.POWERUP)
    NX_INITSTATE_E.POWERUP
    (gdb) py print(NX_INITSTATE.POWERUP.value)
    0
    (gdb) py print(NX_INITSTATE(1))
    
    Signed-off-by: xuxingliang <[email protected]>
---
 tools/gdb/nuttxgdb/utils.py | 47 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/tools/gdb/nuttxgdb/utils.py b/tools/gdb/nuttxgdb/utils.py
index 357454efaa..3a97a23330 100644
--- a/tools/gdb/nuttxgdb/utils.py
+++ b/tools/gdb/nuttxgdb/utils.py
@@ -26,6 +26,7 @@ import json
 import os
 import re
 import shlex
+from enum import Enum
 from typing import List, Tuple, Union
 
 import gdb
@@ -711,6 +712,52 @@ def jsonify(obj, indent=None):
     return json.dumps(obj, default=dumper, indent=indent)
 
 
+def enum(t: Union[str, gdb.Type], name=None):
+    """Create python Enum class from C enum values
+    Usage:
+
+    in C:
+    enum color_e {
+        RED = 1,
+        GREEN = 2,
+    };
+
+    in python:
+    COLOR = utils.enum("enum color_e", "COLOR")
+    print(COLOR.GREEN.value) # --> 2
+    RED = COLOR(1)
+    """
+    if type(t) is str:
+        t = lookup_type(t) or lookup_type("enum " + t)
+
+    if t and t.code == gdb.TYPE_CODE_TYPEDEF:
+        t = t.strip_typedefs()
+
+    if not t or t.code != gdb.TYPE_CODE_ENUM:
+        raise gdb.error(f"{t} is not an enum type")
+
+    def commonprefix(m):
+        "Given a list of pathnames, returns the longest common leading 
component"
+        if not m:
+            return ""
+        s1 = min(m)
+        s2 = max(m)
+        for i, c in enumerate(s1):
+            if c != s2[i]:
+                return s1[:i]
+        return s1
+
+    # Remove the common prefix from names. This is a convention in python.
+    # E.g. COLOR.RED, COLOR.GREEN instead of COLOR.COLOR_RED, COLOR.COLOR_GREEN
+
+    prefix = commonprefix([f.name for f in t.fields()])
+
+    names = {f.name[len(prefix) :]: f.enumval for f in t.fields()}
+
+    name = name or prefix[:-1] if prefix[-1] == "_" else prefix
+    return Enum(name, names)
+
+
 class ArrayIterator:
     """An iterator for gdb array or pointer."""
 

Reply via email to