From e8e586ce7ce8f589eb8d095e82bb1001f5c19caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 13 Nov 2022 00:04:34 +0800 Subject: [PATCH] Windows / macOS: simplify code 1. simplify resource management by using C++ RAII like GCC attribute extension `cleanup` 2. simplify HEKY reading Actually `__attribute__((__cleanup__(cleanupFn)))` is supported on all major C compiler ( gcc, clang and icc ) except MSVC I only used it on Windows and macOS for now. Let's see if the project author like it. --- src/common/networking_windows.c | 4 +- src/common/processing_windows.c | 41 ++++++++++--------- src/detection/battery/battery_apple.c | 3 +- src/detection/cpu/cpu_apple.c | 3 +- src/detection/font/font_windows.cpp | 4 +- src/detection/gpu/gpu_apple.c | 3 +- src/detection/packages/packages_apple.c | 10 ++--- .../terminalfont/terminalfont_apple.m | 4 +- .../terminalfont/terminalfont_windows.c | 41 ++++++++----------- src/detection/wmtheme/wmtheme_windows.c | 25 ++++++----- src/util/FFlist.h | 4 ++ src/util/FFstrbuf.h | 5 +++ 12 files changed, 72 insertions(+), 75 deletions(-) diff --git a/src/common/networking_windows.c b/src/common/networking_windows.c index dd32fac16..5814acc16 100644 --- a/src/common/networking_windows.c +++ b/src/common/networking_windows.c @@ -75,7 +75,7 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con } } - FFstrbuf command; + FF_STRBUF_AUTO_DESTROY command; ffStrbufInitA(&command, 64); ffStrbufAppendS(&command, "GET "); ffStrbufAppendS(&command, path); @@ -87,7 +87,6 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con BOOL result = ConnectEx(state->sockfd, addr->ai_addr, (int)addr->ai_addrlen, command.chars, command.length, NULL, &state->overlapped); freeaddrinfo(addr); - ffStrbufDestroy(&command); if(!result && WSAGetLastError() != WSA_IO_PENDING) { @@ -95,7 +94,6 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con return false; } - ffStrbufDestroy(&command); return true; } diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c index cd091ac6c..30e515734 100644 --- a/src/common/processing_windows.c +++ b/src/common/processing_windows.c @@ -27,28 +27,31 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) .hStdOutput = hChildStdoutWrite, }; - FFstrbuf cmdline; - ffStrbufInitF(&cmdline, "\"%s\"", argv[0]); - for(char* const* parg = &argv[1]; *parg; ++parg) + BOOL success; + { - ffStrbufAppendC(&cmdline, ' '); - ffStrbufAppendS(&cmdline, *parg); + FF_STRBUF_AUTO_DESTROY cmdline; + ffStrbufInitF(&cmdline, "\"%s\"", argv[0]); + for(char* const* parg = &argv[1]; *parg; ++parg) + { + ffStrbufAppendC(&cmdline, ' '); + ffStrbufAppendS(&cmdline, *parg); + } + + success = CreateProcessA( + NULL, // application name + cmdline.chars, // command line + NULL, // process security attributes + NULL, // primary thread security attributes + TRUE, // handles are inherited + 0, // creation flags + NULL, // use parent's environment + NULL, // use parent's current directory + &siStartInfo, // STARTUPINFO pointer + &piProcInfo // receives PROCESS_INFORMATION + ); } - BOOL success = CreateProcessA( - NULL, // application name - cmdline.chars, // command line - NULL, // process security attributes - NULL, // primary thread security attributes - TRUE, // handles are inherited - 0, // creation flags - NULL, // use parent's environment - NULL, // use parent's current directory - &siStartInfo, // STARTUPINFO pointer - &piProcInfo); // receives PROCESS_INFORMATION - - ffStrbufDestroy(&cmdline); - CloseHandle(hChildStdoutWrite); if(!success) { diff --git a/src/detection/battery/battery_apple.c b/src/detection/battery/battery_apple.c index 88499aaa7..7244a89a1 100644 --- a/src/detection/battery/battery_apple.c +++ b/src/detection/battery/battery_apple.c @@ -7,7 +7,7 @@ static double detectBatteryTemp() { - FFlist temps; + FF_LIST_AUTO_DESTROY temps; ffListInit(&temps, sizeof(FFTempValue)); ffDetectCoreTemps(FF_TEMP_BATTERY, &temps); @@ -25,7 +25,6 @@ static double detectBatteryTemp() ffStrbufDestroy(&tempValue->deviceClass); } result /= temps.length; - ffListDestroy(&temps); return result; } diff --git a/src/detection/cpu/cpu_apple.c b/src/detection/cpu/cpu_apple.c index dc0c1a3eb..5f1b35494 100644 --- a/src/detection/cpu/cpu_apple.c +++ b/src/detection/cpu/cpu_apple.c @@ -15,7 +15,7 @@ static double getFrequency(const char* propName) static double detectCpuTemp(const FFstrbuf* cpuName) { - FFlist temps; + FF_LIST_AUTO_DESTROY temps; ffListInit(&temps, sizeof(FFTempValue)); if(ffStrbufStartsWithS(cpuName, "Apple M1")) @@ -38,7 +38,6 @@ static double detectCpuTemp(const FFstrbuf* cpuName) ffStrbufDestroy(&tempValue->deviceClass); } result /= temps.length; - ffListDestroy(&temps); return result; } diff --git a/src/detection/font/font_windows.cpp b/src/detection/font/font_windows.cpp index 3d883bd58..fd400fb71 100644 --- a/src/detection/font/font_windows.cpp +++ b/src/detection/font/font_windows.cpp @@ -18,7 +18,7 @@ void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result) if(FFWmiRecord record = query.next()) { - FFstrbuf fontName; + FF_STRBUF_AUTO_DESTROY fontName; ffStrbufInit(&fontName); record.getString(L"IconTitleFaceName", &fontName); @@ -26,8 +26,6 @@ void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result) record.getUnsigned(L"IconTitleSize", &fontSize); ffStrbufAppendF(&result->fonts[0], "%*s (%upt)", fontName.length, fontName.chars, (unsigned)fontSize); - - ffStrbufDestroy(&fontName); } else ffStrbufInitS(&result->error, "No WMI result returned"); diff --git a/src/detection/gpu/gpu_apple.c b/src/detection/gpu/gpu_apple.c index bad6747d3..52292d83e 100644 --- a/src/detection/gpu/gpu_apple.c +++ b/src/detection/gpu/gpu_apple.c @@ -8,7 +8,7 @@ static double detectGpuTemp(const FFstrbuf* gpuName) { - FFlist temps; + FF_LIST_AUTO_DESTROY temps; ffListInit(&temps, sizeof(FFTempValue)); if(ffStrbufStartsWithS(gpuName, "Apple M1")) @@ -35,7 +35,6 @@ static double detectGpuTemp(const FFstrbuf* gpuName) ffStrbufDestroy(&tempValue->deviceClass); } result /= temps.length; - ffListDestroy(&temps); return result; } diff --git a/src/detection/packages/packages_apple.c b/src/detection/packages/packages_apple.c index 3966240fd..e1323e1e5 100644 --- a/src/detection/packages/packages_apple.c +++ b/src/detection/packages/packages_apple.c @@ -27,7 +27,7 @@ static uint32_t getNumElements(const char* dirname, unsigned char type) static uint32_t countBrewPackages(const char* dirname) { - FFstrbuf baseDir; + FF_STRBUF_AUTO_DESTROY baseDir; ffStrbufInitS(&baseDir, dirname); uint32_t result = 0; @@ -41,7 +41,6 @@ static uint32_t countBrewPackages(const char* dirname) result += getNumElements(baseDir.chars, DT_DIR); ffStrbufSubstrBefore(&baseDir, baseDirLength); - ffStrbufDestroy(&baseDir); return result; } @@ -59,14 +58,11 @@ static uint32_t getBrewPackages() static uint32_t countMacPortsPackages(const char* dirname) { - FFstrbuf baseDir; + FF_STRBUF_AUTO_DESTROY baseDir; ffStrbufInitS(&baseDir, dirname); ffStrbufAppendS(&baseDir, "/var/macports/software"); - uint32_t result = getNumElements(baseDir.chars, DT_DIR); - - ffStrbufDestroy(&baseDir); - return result; + return getNumElements(baseDir.chars, DT_DIR); } static uint32_t getMacPortsPackages() diff --git a/src/detection/terminalfont/terminalfont_apple.m b/src/detection/terminalfont/terminalfont_apple.m index 72e4c09cc..1ee387aa2 100644 --- a/src/detection/terminalfont/terminalfont_apple.m +++ b/src/detection/terminalfont/terminalfont_apple.m @@ -46,19 +46,17 @@ static void detectIterm2(const FFinstance* instance, FFTerminalFontResult* termi static void detectAppleTerminal(FFTerminalFontResult* terminalFont) { - FFstrbuf font; + FF_STRBUF_AUTO_DESTROY font; ffStrbufInit(&font); ffOsascript("tell application \"Terminal\" to font name of window frontmost & \" \" & font size of window frontmost", &font); if(font.length == 0) { ffStrbufAppendS(&terminalFont->error, "executing osascript failed"); - ffStrbufDestroy(&font); return; } ffFontInitWithSpace(&terminalFont->font, font.chars); - ffStrbufDestroy(&font); } static void detectWarpTerminal(const FFinstance* instance, FFTerminalFontResult* terminalFont) diff --git a/src/detection/terminalfont/terminalfont_windows.c b/src/detection/terminalfont/terminalfont_windows.c index 7e1d5c8cb..e6ea456be 100644 --- a/src/detection/terminalfont/terminalfont_windows.c +++ b/src/detection/terminalfont/terminalfont_windows.c @@ -8,10 +8,10 @@ static void detectMintty(const FFinstance* instance, FFTerminalFontResult* terminalFont) { - FFstrbuf fontName; + FF_STRBUF_AUTO_DESTROY fontName; ffStrbufInit(&fontName); - FFstrbuf fontSize; + FF_STRBUF_AUTO_DESTROY fontSize; ffStrbufInit(&fontSize); ffParsePropFileHomeValues(instance, ".minttyrc", 2, (FFpropquery[]) { @@ -24,9 +24,12 @@ static void detectMintty(const FFinstance* instance, FFTerminalFontResult* termi ffStrbufAppendC(&fontSize, '9'); ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars); +} - ffStrbufDestroy(&fontName); - ffStrbufDestroy(&fontSize); +static inline void wrapRegCloseKey(HKEY* phKey) +{ + if(*phKey) + RegCloseKey(*phKey); } static void detectConhost(const FFinstance* instance, FFTerminalFontResult* terminalFont) @@ -35,7 +38,7 @@ static void detectConhost(const FFinstance* instance, FFTerminalFontResult* term //Current font of conhost doesn't seem to be detectable, we detect default font instead - HKEY hKey; + HKEY __attribute__((__cleanup__(wrapRegCloseKey))) hKey = NULL; if(RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ, &hKey) != ERROR_SUCCESS) { ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW() failed"); @@ -44,34 +47,26 @@ static void detectConhost(const FFinstance* instance, FFTerminalFontResult* term DWORD bufSize; - wchar_t fontNameW[64]; - bufSize = sizeof(fontNameW); - if(RegQueryValueExW(hKey, L"FaceName", NULL, NULL, (LPBYTE)fontNameW, &bufSize) != ERROR_SUCCESS) + char fontName[128]; + bufSize = sizeof(fontName); + if(RegGetValueA(hKey, NULL, "FaceName", RRF_RT_REG_SZ, NULL, fontName, &bufSize) != ERROR_SUCCESS) { - ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW(FaceName) failed"); - goto exit; + ffStrbufAppendS(&terminalFont->error, "RegGetValueA(FaceName) failed"); + return; } - fontNameW[bufSize] = '\0'; - - char fontNameA[128]; - int fontNameALen = WideCharToMultiByte(CP_UTF8, 0, fontNameW, (int)(bufSize / 2), fontNameA, sizeof(fontNameA), NULL, NULL); - fontNameA[fontNameALen] = '\0'; uint32_t fontSizeNum = 0; bufSize = sizeof(fontSizeNum); - if(RegQueryValueExW(hKey, L"fontSize", NULL, NULL, (LPBYTE)&fontSizeNum, &bufSize) != ERROR_SUCCESS) + if(RegGetValueW(hKey, NULL, L"FontSize", RRF_RT_DWORD, NULL, &fontSizeNum, &bufSize) != ERROR_SUCCESS) { - ffStrbufAppendS(&terminalFont->error, "RegOpenKeyExW(fontSize) failed"); - goto exit; + ffStrbufAppendS(&terminalFont->error, "RegGetValueW(FontSize) failed"); + return; } char fontSize[16]; - snprintf(fontSize, sizeof(fontSize), "%u", (fontSizeNum >> 16)); + _ultoa((unsigned long)(fontSizeNum >> 16), fontSize, 10); - ffFontInitValues(&terminalFont->font, fontNameA, fontSize); - -exit: - RegCloseKey(hKey); + ffFontInitValues(&terminalFont->font, fontName, fontSize); } static void detectConEmu(const FFinstance* instance, FFTerminalFontResult* terminalFont) diff --git a/src/detection/wmtheme/wmtheme_windows.c b/src/detection/wmtheme/wmtheme_windows.c index 7611f05da..308893e1f 100644 --- a/src/detection/wmtheme/wmtheme_windows.c +++ b/src/detection/wmtheme/wmtheme_windows.c @@ -4,38 +4,41 @@ #define WIN32_LEAN_AND_MEAN 1 #include +static inline void wrapRegCloseKey(HKEY* phKey) +{ + if(*phKey) + RegCloseKey(*phKey); +} + bool ffDetectWmTheme(FFinstance* instance, FFstrbuf* themeOrError) { FF_UNUSED(instance); - HKEY hKey; + HKEY __attribute__((__cleanup__(wrapRegCloseKey))) hKey = NULL; if(RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &hKey) != ERROR_SUCCESS) { ffStrbufAppendS(themeOrError, "RegOpenKeyExW() failed"); return false; } - bool result = true; int SystemUsesLightTheme = 1; DWORD bufSize = sizeof(SystemUsesLightTheme); - if(RegQueryValueExW(hKey, L"SystemUsesLightTheme", NULL, NULL, (LPBYTE)&SystemUsesLightTheme, &bufSize) != ERROR_SUCCESS) + if(RegGetValueW(hKey, NULL, L"SystemUsesLightTheme", RRF_RT_DWORD, NULL, &SystemUsesLightTheme, &bufSize) != ERROR_SUCCESS) { - ffStrbufAppendS(themeOrError, "RegOpenKeyExW(SystemUsesLightTheme) failed"); - goto exit; + ffStrbufAppendS(themeOrError, "RegGetValueW(SystemUsesLightTheme) failed"); + return false; } int AppsUsesLightTheme = 1; bufSize = sizeof(AppsUsesLightTheme); - if(RegQueryValueExW(hKey, L"AppsUseLightTheme", NULL, NULL, (LPBYTE)&AppsUsesLightTheme, &bufSize) != ERROR_SUCCESS) + if(RegGetValueW(hKey, NULL, L"AppsUseLightTheme", RRF_RT_DWORD, NULL, &AppsUsesLightTheme, &bufSize) != ERROR_SUCCESS) { - ffStrbufAppendS(themeOrError, "RegOpenKeyExW(AppsUseLightTheme) failed"); - goto exit; + ffStrbufAppendS(themeOrError, "RegGetValueW(AppsUseLightTheme) failed"); + return false; } ffStrbufAppendF(themeOrError, "System - %s, Apps - %s", SystemUsesLightTheme ? "Light" : "Dark", AppsUsesLightTheme ? "Light" : "Dark"); -exit: - RegCloseKey(hKey); - return result; + return true; } diff --git a/src/util/FFlist.h b/src/util/FFlist.h index d9d516792..fd7a0f5ca 100644 --- a/src/util/FFlist.h +++ b/src/util/FFlist.h @@ -45,4 +45,8 @@ static inline void ffListSort(FFlist* list, int(*compar)(const void*, const void qsort(list->data, list->length, list->elementSize, compar); } +#if defined(_WIN32) || defined(__APPLE__) + #define FF_LIST_AUTO_DESTROY FFlist __attribute__((__cleanup__(ffListDestroy))) +#endif + #endif diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index 736e1d26d..80503e55d 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -301,4 +301,9 @@ static inline FF_C_NODISCARD bool ffStrbufEndsWithIgnCase(const FFstrbuf* strbuf { return ffStrbufEndsWithIgnCaseNS(strbuf, end->length, end->chars); } + +#if defined(_WIN32) || defined(__APPLE__) + #define FF_STRBUF_AUTO_DESTROY FFstrbuf __attribute__((__cleanup__(ffStrbufDestroy))) +#endif + #endif