From 15b1543e20271cbf24c6e2870f24d581510393d8 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 13 Nov 2020 15:54:38 +0300 Subject: [PATCH] Implement OS detection in Emscripten. --- tdutils/td/utils/port/uname.cpp | 98 ++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/tdutils/td/utils/port/uname.cpp b/tdutils/td/utils/port/uname.cpp index ee0fde119..c3694e74d 100644 --- a/tdutils/td/utils/port/uname.cpp +++ b/tdutils/td/utils/port/uname.cpp @@ -20,6 +20,10 @@ #if TD_ANDROID #include +#elif TD_EMSCRIPTEN +#include + +#include #else #if TD_DARWIN #include @@ -90,6 +94,98 @@ Slice get_operating_system_version() { if (length > 0) { return "Android " + string(version, length); } +#elif TD_EMSCRIPTEN + // clang-format off + char *os_name_js = (char*)EM_ASM_INT(({ + function detectOsName() { + if (typeof process === 'object' && typeof process.platform === 'string') { // Node.js + switch (process.platform) { + case 'aix': + return 'IBM AIX'; + case 'android': + return 'Android'; + case 'darwin': + return 'macOS'; + case 'freebsd': + return 'FreeBSD'; + case 'linux': + return 'Linux'; + case 'openbsd': + return 'OpenBSD'; + case 'sunos': + return 'SunOS'; + case 'win32': + return 'Windows'; + case 'darwin': + return 'macOS'; + default: + return 'Node.js'; + } + } + + var userAgent = 'Unknown'; + if (typeof window === 'object') { // Web + userAgent = window.navigator.userAgent; + } else if (typeof importScripts === 'function') { // Web Worker + userAgent = navigator.userAgent; + } + + var match = /(Mac OS|Mac OS X|MacPPC|MacIntel|Mac_PowerPC|Macintosh) ([._0-9]+)/.exec(userAgent); + if (match !== null) { + return 'macOS ' + match[2].replace('_', '.'); + } + + match = /Android [._0-9]+/.exec(userAgent); + if (match !== null) { + return match[0].replace('_', '.'); + } + + if (/(iPhone|iPad|iPod)/.test(userAgent)) { + match = /OS ([._0-9]+)/.exec(userAgent); + if (match !== null) { + return 'iOS ' + match[1].replace('_', '.'); + } + return 'iOS'; + } + + var clientStrings = [ + {s:'Windows 10', r:/(Windows 10.0|Windows NT 10.0)/}, + {s:'Windows 8.1', r:/(Windows 8.1|Windows NT 6.3)/}, + {s:'Windows 8', r:/(Windows 8|Windows NT 6.2)/}, + {s:'Windows 7', r:/(Windows 7|Windows NT 6.1)/}, + {s:'Windows Vista', r:/Windows NT 6.0/}, + {s:'Windows Server 2003', r:/Windows NT 5.2/}, + {s:'Windows XP', r:/(Windows XP|Windows NT 5.1)/}, + {s:'Windows', r:/Windows/}, + {s:'Android', r:/Android/}, + {s:'FreeBSD', r:/FreeBSD/}, + {s:'OpenBSD', r:/OpenBSD/}, + {s:'Chrome OS', r:/CrOS/}, + {s:'Linux', r:/(Linux|X11)/}, + {s:'macOS', r:/(Mac OS|MacPPC|MacIntel|Mac_PowerPC|Macintosh)/}, + {s:'QNX', r:/QNX/}, + {s:'BeOS', r:/BeOS/} + ]; + for (var id in clientStrings) { + var cs = clientStrings[id]; + if (cs.r.test(userAgent)) { + return cs.s; + } + } + return 'Emscripten'; + } + + var os_name = detectOsName(); + var length = lengthBytesUTF8(os_name) + 1; + var result = _malloc(length); + stringToUTF8(os_name, result, length); + return result; + })); + // clang-format on + string os_name(os_name_js); + std::free(os_name_js); + + return os_name; #else #if TD_LINUX auto os_name = read_os_name("/etc/os-release", "PRETTY_NAME=\"", "\"\n"); @@ -124,8 +220,6 @@ Slice get_operating_system_version() { return "NetBSD"; #elif TD_CYGWIN return "Cygwin"; -#elif TD_EMSCRIPTEN - return "Emscripten"; #else return "Unix"; #endif