From 3d1703f16faf5bd3c73976909e1b6e03061a7f72 Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Thu, 17 Dec 2020 20:09:55 -0300 Subject: [PATCH] Invert Process_compare resolution so that superclass matches run first * This removes duplicated code that adjusts the sort direction from every OS-specific folder. * Most fields in a regular htop screen are OS-independent, so trying Process_compare first and only falling back to the OS-specific compareByKey function if it's an OS-specific field makes sense. * This will allow us to override the sortKey in a global way without having to edit each OS-specific file. --- Process.c | 2 +- Process.h | 7 +++++-- darwin/DarwinProcess.c | 21 +++++++-------------- dragonflybsd/DragonFlyBSDProcess.c | 21 +++++++-------------- dragonflybsd/DragonFlyBSDProcess.h | 2 +- freebsd/FreeBSDProcess.c | 21 +++++++-------------- linux/LinuxProcess.c | 23 ++++++++--------------- openbsd/OpenBSDProcess.c | 21 +++++++-------------- solaris/SolarisProcess.c | 21 +++++++-------------- solaris/SolarisProcess.h | 2 +- 10 files changed, 51 insertions(+), 90 deletions(-) diff --git a/Process.c b/Process.c index c5ce737d..89fc8da4 100644 --- a/Process.c +++ b/Process.c @@ -555,6 +555,6 @@ long Process_compare(const void* v1, const void* v2) { case USER: return SPACESHIP_NULLSTR(p1->user, p2->user); default: - return SPACESHIP_NUMBER(p1->pid, p2->pid); + return Process_compareByKey(p1, p2, key); } } diff --git a/Process.h b/Process.h index 1f118e70..9e800891 100644 --- a/Process.h +++ b/Process.h @@ -129,17 +129,20 @@ extern char Process_pidFormat[20]; typedef Process*(*Process_New)(const struct Settings_*); typedef void (*Process_WriteField)(const Process*, RichString*, ProcessField); +typedef long (*Process_CompareByKey)(const Process*, const Process*, ProcessField); typedef const char* (*Process_GetCommandStr)(const Process*); typedef struct ProcessClass_ { const ObjectClass super; const Process_WriteField writeField; + const Process_CompareByKey compareByKey; const Process_GetCommandStr getCommandStr; } ProcessClass; -#define As_Process(this_) ((const ProcessClass*)((this_)->super.klass)) +#define As_Process(this_) ((const ProcessClass*)((this_)->super.klass)) -#define Process_getCommand(this_) (As_Process(this_)->getCommandStr ? As_Process(this_)->getCommandStr((const Process*)(this_)) : ((const Process*)(this_))->comm) +#define Process_getCommand(this_) (As_Process(this_)->getCommandStr ? As_Process(this_)->getCommandStr((const Process*)(this_)) : ((const Process*)(this_))->comm) +#define Process_compareByKey(p1_, p2_, key_) (As_Process(p1_)->compareByKey ? (As_Process(p1_)->compareByKey(p1_, p2_, key_)) : SPACESHIP_NUMBER(p1->pid, p2->pid)) static inline pid_t Process_getParentPid(const Process* this) { return this->tgid == this->pid ? this->ppid : this->tgid; diff --git a/darwin/DarwinProcess.c b/darwin/DarwinProcess.c index d8d7ab7b..38e2a234 100644 --- a/darwin/DarwinProcess.c +++ b/darwin/DarwinProcess.c @@ -83,24 +83,16 @@ static void DarwinProcess_writeField(const Process* this, RichString* str, Proce RichString_appendWide(str, attr, buffer); } -static long DarwinProcess_compare(const void* v1, const void* v2) { - const DarwinProcess *p1, *p2; - const Settings *settings = ((const Process*)v1)->settings; +static long DarwinProcess_compareByKey(const Process* v1, const Process* v2, ProcessField key) { + const DarwinProcess* p1 = (const DarwinProcess*)v1; + const DarwinProcess* p2 = (const DarwinProcess*)v2; - if (settings->direction == 1) { - p1 = (const DarwinProcess*)v1; - p2 = (const DarwinProcess*)v2; - } else { - p2 = (const DarwinProcess*)v1; - p1 = (const DarwinProcess*)v2; - } - - switch ((int) settings->sortKey) { + switch ((int) key) { // add Platform-specific fields here case TRANSLATED: return SPACESHIP_NUMBER(p1->translated, p2->translated); default: - return Process_compare(v1, v2); + return SPACESHIP_NUMBER(v1->pid, v2->pid); } } @@ -409,7 +401,8 @@ const ProcessClass DarwinProcess_class = { .extends = Class(Process), .display = Process_display, .delete = Process_delete, - .compare = DarwinProcess_compare + .compare = Process_compare }, .writeField = DarwinProcess_writeField, + .compareByKey = DarwinProcess_compareByKey, }; diff --git a/dragonflybsd/DragonFlyBSDProcess.c b/dragonflybsd/DragonFlyBSDProcess.c index 4ea66870..1f08530f 100644 --- a/dragonflybsd/DragonFlyBSDProcess.c +++ b/dragonflybsd/DragonFlyBSDProcess.c @@ -23,9 +23,10 @@ const ProcessClass DragonFlyBSDProcess_class = { .extends = Class(Process), .display = Process_display, .delete = Process_delete, - .compare = DragonFlyBSDProcess_compare + .compare = Process_compare }, .writeField = DragonFlyBSDProcess_writeField, + .compareByKey = DragonFlyBSDProcess_compareByKey }; ProcessFieldData Process_fields[] = { @@ -108,26 +109,18 @@ void DragonFlyBSDProcess_writeField(const Process* this, RichString* str, Proces RichString_appendWide(str, attr, buffer); } -long DragonFlyBSDProcess_compare(const void* v1, const void* v2) { - const DragonFlyBSDProcess *p1, *p2; - const Settings *settings = ((const Process*)v1)->settings; +long DragonFlyBSDProcess_compareByKey(const Process* v1, const Process* v2, ProcessField key) { + const DragonFlyBSDProcess* p1 = (const DragonFlyBSDProcess*)v1; + const DragonFlyBSDProcess* p2 = (const DragonFlyBSDProcess*)v2; - if (settings->direction == 1) { - p1 = (const DragonFlyBSDProcess*)v1; - p2 = (const DragonFlyBSDProcess*)v2; - } else { - p2 = (const DragonFlyBSDProcess*)v1; - p1 = (const DragonFlyBSDProcess*)v2; - } - - switch ((int) settings->sortKey) { + switch ((int) key) { // add Platform-specific fields here case JID: return SPACESHIP_NUMBER(p1->jid, p2->jid); case JAIL: return SPACESHIP_NULLSTR(p1->jname, p2->jname); default: - return Process_compare(v1, v2); + return SPACESHIP_NULLSTR(v1->pid, v2->pid); } } diff --git a/dragonflybsd/DragonFlyBSDProcess.h b/dragonflybsd/DragonFlyBSDProcess.h index 1befd946..0bb173ec 100644 --- a/dragonflybsd/DragonFlyBSDProcess.h +++ b/dragonflybsd/DragonFlyBSDProcess.h @@ -39,7 +39,7 @@ void Process_delete(Object* cast); void DragonFlyBSDProcess_writeField(const Process* this, RichString* str, ProcessField field); -long DragonFlyBSDProcess_compare(const void* v1, const void* v2); +long DragonFlyBSDProcess_compareByKey(const Process* v1, const Process* v2, ProcessField key); bool Process_isThread(const Process* this); diff --git a/freebsd/FreeBSDProcess.c b/freebsd/FreeBSDProcess.c index 1c670ae3..cebf6908 100644 --- a/freebsd/FreeBSDProcess.c +++ b/freebsd/FreeBSDProcess.c @@ -108,19 +108,11 @@ static void FreeBSDProcess_writeField(const Process* this, RichString* str, Proc RichString_appendWide(str, attr, buffer); } -static long FreeBSDProcess_compare(const void* v1, const void* v2) { - const FreeBSDProcess *p1, *p2; - const Settings *settings = ((const Process*)v1)->settings; +static long FreeBSDProcess_compareByKey(const Process* v1, const Process* v2, ProcessField key) { + const FreeBSDProcess* p1 = (const FreeBSDProcess*)v1; + const FreeBSDProcess* p2 = (const FreeBSDProcess*)v2; - if (settings->direction == 1) { - p1 = (const FreeBSDProcess*)v1; - p2 = (const FreeBSDProcess*)v2; - } else { - p2 = (const FreeBSDProcess*)v1; - p1 = (const FreeBSDProcess*)v2; - } - - switch ((int) settings->sortKey) { + switch ((int) key) { // add FreeBSD-specific fields here case JID: return SPACESHIP_NUMBER(p1->jid, p2->jid); @@ -129,7 +121,7 @@ static long FreeBSDProcess_compare(const void* v1, const void* v2) { case TTY_NR: return SPACESHIP_NULLSTR(p1->ttyPath, p2->ttyPath); default: - return Process_compare(v1, v2); + return SPACESHIP_NUMBER(v1->pid, v2->pid); } } @@ -148,7 +140,8 @@ const ProcessClass FreeBSDProcess_class = { .extends = Class(Process), .display = Process_display, .delete = Process_delete, - .compare = FreeBSDProcess_compare + .compare = Process_compare }, .writeField = FreeBSDProcess_writeField, + .compareByKey = FreeBSDProcess_compareByKey }; diff --git a/linux/LinuxProcess.c b/linux/LinuxProcess.c index 8cd9f492..9e184b64 100644 --- a/linux/LinuxProcess.c +++ b/linux/LinuxProcess.c @@ -767,19 +767,11 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces RichString_appendWide(str, attr, buffer); } -static long LinuxProcess_compare(const void* v1, const void* v2) { - const LinuxProcess *p1, *p2; - const Settings *settings = ((const Process*)v1)->settings; +static long LinuxProcess_compareByKey(const Process* v1, const Process* v2, ProcessField key) { + const LinuxProcess* p1 = (const LinuxProcess*)v1; + const LinuxProcess* p2 = (const LinuxProcess*)v2; - if (settings->direction == 1) { - p1 = (const LinuxProcess*)v1; - p2 = (const LinuxProcess*)v2; - } else { - p2 = (const LinuxProcess*)v1; - p1 = (const LinuxProcess*)v2; - } - - switch ((int)settings->sortKey) { + switch ((int) key) { case M_DRS: return SPACESHIP_NUMBER(p2->m_drs, p1->m_drs); case M_DT: @@ -865,7 +857,7 @@ static long LinuxProcess_compare(const void* v1, const void* v2) { case CWD: return SPACESHIP_NULLSTR(p1->cwd, p2->cwd); default: - return Process_compare(v1, v2); + return SPACESHIP_NUMBER(v1->pid, v2->pid); } } @@ -878,8 +870,9 @@ const ProcessClass LinuxProcess_class = { .extends = Class(Process), .display = Process_display, .delete = Process_delete, - .compare = LinuxProcess_compare + .compare = Process_compare }, .writeField = LinuxProcess_writeField, - .getCommandStr = LinuxProcess_getCommandStr + .getCommandStr = LinuxProcess_getCommandStr, + .compareByKey = LinuxProcess_compareByKey }; diff --git a/openbsd/OpenBSDProcess.c b/openbsd/OpenBSDProcess.c index 9aab53e5..532093f1 100644 --- a/openbsd/OpenBSDProcess.c +++ b/openbsd/OpenBSDProcess.c @@ -212,25 +212,17 @@ static void OpenBSDProcess_writeField(const Process* this, RichString* str, Proc RichString_appendWide(str, attr, buffer); } -static long OpenBSDProcess_compare(const void* v1, const void* v2) { - const OpenBSDProcess *p1, *p2; - const Settings *settings = ((const Process*)v1)->settings; - - if (settings->direction == 1) { - p1 = (const OpenBSDProcess*)v1; - p2 = (const OpenBSDProcess*)v2; - } else { - p2 = (const OpenBSDProcess*)v1; - p1 = (const OpenBSDProcess*)v2; - } +static long OpenBSDProcess_compareByKey(const Process* v1, const Process* v2, ProcessField key) { + const OpenBSDProcess* p1 = (const OpenBSDProcess*)v1; + const OpenBSDProcess* p2 = (const OpenBSDProcess*)v2; // remove if actually used (void)p1; (void)p2; - switch (settings->sortKey) { + switch ((int) key) { // add OpenBSD-specific fields here default: - return Process_compare(v1, v2); + return SPACESHIP_NUMBER(v1->pid, v2->pid); } } @@ -239,9 +231,10 @@ const ProcessClass OpenBSDProcess_class = { .extends = Class(Process), .display = Process_display, .delete = Process_delete, - .compare = OpenBSDProcess_compare + .compare = Process_compare }, .writeField = OpenBSDProcess_writeField, + .compareByKey = OpenBSDProcess_compareByKey }; bool Process_isThread(const Process* this) { diff --git a/solaris/SolarisProcess.c b/solaris/SolarisProcess.c index e69809c2..e6c49936 100644 --- a/solaris/SolarisProcess.c +++ b/solaris/SolarisProcess.c @@ -23,9 +23,10 @@ const ProcessClass SolarisProcess_class = { .extends = Class(Process), .display = Process_display, .delete = Process_delete, - .compare = SolarisProcess_compare + .compare = Process_compare }, .writeField = SolarisProcess_writeField, + .compareByKey = SolarisProcess_compareByKey }; ProcessFieldData Process_fields[] = { @@ -117,19 +118,11 @@ void SolarisProcess_writeField(const Process* this, RichString* str, ProcessFiel RichString_appendWide(str, attr, buffer); } -long SolarisProcess_compare(const void* v1, const void* v2) { - const SolarisProcess *p1, *p2; - const Settings* settings = ((const Process*)v1)->settings; +long SolarisProcess_compareByKey(const void* v1, const void* v2, ProcessField key) { + const SolarisProcess* p1 = (const SolarisProcess*)v1; + const SolarisProcess* p2 = (const SolarisProcess*)v2; - if (settings->direction == 1) { - p1 = (const SolarisProcess*)v1; - p2 = (const SolarisProcess*)v2; - } else { - p2 = (const SolarisProcess*)v1; - p1 = (const SolarisProcess*)v2; - } - - switch ((int) settings->sortKey) { + switch ((int) key) { case ZONEID: return SPACESHIP_NUMBER(p1->zoneid, p2->zoneid); case PROJID: @@ -149,7 +142,7 @@ long SolarisProcess_compare(const void* v1, const void* v2) { case LWPID: return SPACESHIP_NUMBER(p1->lwpid, p2->lwpid); default: - return Process_compare(v1, v2); + return SPACESHIP_NUMBER(v1->pid, v2->pid); } } diff --git a/solaris/SolarisProcess.h b/solaris/SolarisProcess.h index 4756634d..12e6c99f 100644 --- a/solaris/SolarisProcess.h +++ b/solaris/SolarisProcess.h @@ -56,7 +56,7 @@ void Process_delete(Object* cast); void SolarisProcess_writeField(const Process* this, RichString* str, ProcessField field); -long SolarisProcess_compare(const void* v1, const void* v2); +long SolarisProcess_compareByKey(const Process* v1, const Process* v2, ProcessField field); bool Process_isThread(const Process* this);