{"id":20041497,"url":"https://github.com/kcxt/WheresThatDefine","last_synced_at":"2025-05-05T08:32:17.649Z","repository":{"id":43661196,"uuid":"419872002","full_name":"kcxt/WheresThatDefine","owner":"kcxt","description":"A poorly named reverse C pre-processor","archived":false,"fork":false,"pushed_at":"2023-06-05T18:31:04.000Z","size":21,"stargazers_count":5,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-08T10:40:48.426Z","etag":null,"topics":["bitmask","c-headers","embedded","embedded-c","embedded-linux","embedded-registers","register-macros"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kcxt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-10-21T20:46:17.000Z","updated_at":"2022-03-28T01:42:37.000Z","dependencies_parsed_at":"2024-11-13T10:46:57.985Z","dependency_job_id":"df22a811-1ad8-404c-a992-0f1be89f0df5","html_url":"https://github.com/kcxt/WheresThatDefine","commit_stats":null,"previous_names":["kcxt/wheresthatdefine"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kcxt%2FWheresThatDefine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kcxt%2FWheresThatDefine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kcxt%2FWheresThatDefine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kcxt%2FWheresThatDefine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kcxt","download_url":"https://codeload.github.com/kcxt/WheresThatDefine/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252466803,"owners_count":21752438,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bitmask","c-headers","embedded","embedded-c","embedded-linux","embedded-registers","register-macros"],"created_at":"2024-11-13T10:46:48.215Z","updated_at":"2025-05-05T08:32:17.352Z","avatar_url":"https://github.com/kcxt.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Where's That Define\n\nWTD is a python tool for replacing values with the C preprocessor macro which defined them. An example of this is when trying to understand a driver by dumping every read() and write(), you end up with a big list of values like the following:\n\n```\n[  162.326260] qcom,qpnp-smb2: smblib_read(addr = 0x1307, val=0x01)\n[  162.326289] qcom,qpnp-smb2: smblib_read(addr = 0x1308, val=0x08)\n[  162.326373] qcom,qpnp-smb2: smblib_read(addr = 0x1307, val=0x01)\n[  162.326539] qcom,qpnp-smb2: smblib_read(addr = 0x1070, val=0x79)\n[  162.326582] qcom,qpnp-smb2: smblib_read(addr = 0x1061, val=0x4e)\n[  162.326623] qcom,qpnp-smb2: smblib_read(addr = 0x1607, val=0x13)\n[  162.326666] qcom,qpnp-smb2: smblib_read(addr = 0x1007, val=0x80)\n[  162.326702] qcom,qpnp-smb2: smblib_read(addr = 0x1365, val=0xf7)\n```\n\nWouldn't it be so much better if it could look like this instead?\n```\n[ 7291.659328] qcom,qpnp-smb2: smblib_read(addr = APSD_STATUS_REG, val = APSD_DTC_STATUS_DONE_BIT)\n[ 7291.659358] qcom,qpnp-smb2: smblib_read(addr = APSD_RESULT_STATUS_REG, val = DCP_CHARGER_BIT|APSD_RESULT_STATUS_MASK=0x8)\n[ 7291.659457] qcom,qpnp-smb2: smblib_read(addr = APSD_STATUS_REG, val = APSD_DTC_STATUS_DONE_BIT)\n[ 7291.659610] qcom,qpnp-smb2: smblib_read(addr = FLOAT_VOLTAGE_CFG_REG, val = FLOAT_VOLTAGE_SETTING_MASK=0x79)\n[ 7291.659652] qcom,qpnp-smb2: smblib_read(addr = FAST_CHARGE_CURRENT_CFG_REG, val = FAST_CHARGE_CURRENT_SETTING_MASK=0x4e)\n[ 7291.659694] qcom,qpnp-smb2: smblib_read(addr = ICL_STATUS_REG, val = INPUT_CURRENT_LIMIT_MASK=0x13)\n[ 7291.659739] qcom,qpnp-smb2: smblib_read(addr = BATTERY_CHARGER_STATUS_2_REG, val = 0x00)\n[ 7291.659776] qcom,qpnp-smb2: smblib_read(addr = USBIN_LOAD_CFG_REG, val = USBIN_OV_CH_LOAD_OPTION_BIT|ICL_OVERRIDE_AFTER_APSD_BIT)\n[ 7291.659807] qcom,qpnp-smb2: smblib_read(addr = USBIN_CURRENT_LIMIT_CFG_REG, val = USBIN_CURRENT_LIMIT_MASK=0x3c)\n[ 7291.661133] qcom,qpnp-smb2: smblib_read(addr = USB_INT_RT_STS, val = USBIN_PLUGIN_RT_STS_BIT)\n```\n\nWell with the power of WTD and Regex, it can!\n\nYes that's right, this is a header file parser using regex.\n\n## Usage\n\nBefore using WTD, some manual processing of `#define`s is required, WTD can parse macros in the following formats:\n\n```c\n// The literal 3735941133 in hex\n#define SOME_MACRO 0xdeadf00d\n```\n```c\n// The literal 1234\n#define SOME_MACRO 1234\n```\n```c\n// Bit 2\n#define SOME_MACRO BIT(2)\n```\n```c\n// Bitmask from bit 2 to bit 0\n#define SOME_MACRO GENMASK(2, 0)\n```\n\nThe header parser uses context to relate a bunch of bit / mask macros to a particular register, as such the ordering matters. The symbol tree will attribute all BIT() and GENMASK() macros to whatever the last literal value register was.\nFor example:\n```h\n#define BATTERY_CHARGER_STATUS_5_REG\t\t\t0x100B\n#define VALID_INPUT_POWER_SOURCE_BIT\t\t\tBIT(7)\n#define DISABLE_CHARGING_BIT\t\t\t\tBIT(6)\n#define FORCE_ZERO_CHARGE_CURRENT_BIT\t\t\tBIT(5)\n#define CHARGING_ENABLE_BIT\t\t\t\tBIT(4)\n#define TAPER_BIT\t\t\t\t\tBIT(3)\n#define ENABLE_CHG_SENSORS_BIT\t\t\t\tBIT(2)\n#define ENABLE_TAPER_SENSOR_BIT\t\t\t\tBIT(1)\n#define TAPER_REGION_BIT\t\t\t\tBIT(0)\n```\nproduces the following tree:\n\n```py\nBATTERY_CHARGER_STATUS_5_REG: {\n    'value': 4107,\n    'bits':\n    [\n        {'name': 'VALID_INPUT_POWER_SOURCE_BIT', 'bit': 7},\n        {'name': 'DISABLE_CHARGING_BIT', 'bit': 6},\n        {'name': 'FORCE_ZERO_CHARGE_CURRENT_BIT', 'bit': 5},\n        {'name': 'CHARGING_ENABLE_BIT', 'bit': 4},\n        {'name': 'TAPER_BIT', 'bit': 3},\n        {'name': 'ENABLE_CHG_SENSORS_BIT', 'bit': 2},\n        {'name': 'ENABLE_TAPER_SENSOR_BIT', 'bit': 1},\n        {'name': 'TAPER_REGION_BIT', 'bit': 0}\n    ],\n    'masks': []}\n```\n\nSome semi-manual preprocessing may be required before using this tool, personally I've found the multi-cursor feature in vscode to be very useful, as well as regex-based find and replace. You could also do this with sed / grep or whatever your preferred method is.\n\nThe logfile must log register read/writes in the format\n```c\naddr = 0x123, val = 0x123\n```\nAlternatively hack your format into `process_logs()`.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkcxt%2FWheresThatDefine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkcxt%2FWheresThatDefine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkcxt%2FWheresThatDefine/lists"}