ohmu
·
2026-10-15
1#include "common/printing.h"
2#include "common/jsonconfig.h"
3#include "common/percent.h"
4#include "common/size.h"
5#include "common/strutil.h"
6#include "detection/memory/memory.h"
7#include "modules/memory/memory.h"
8
9bool ffPrintMemory(FFMemoryOptions* options) {
10 FFMemoryResult storage = {};
11 const char* error = ffDetectMemory(&storage);
12
13 if (error) {
14 ffPrintError(FF_MODULE_GET_DISPLAY_NAME(Memory), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
15 return false;
16 }
17
18 FF_STRBUF_AUTO_DESTROY usedPretty = ffStrbufCreate();
19 ffSizeAppendNum(storage.bytesUsed, &usedPretty);
20
21 FF_STRBUF_AUTO_DESTROY totalPretty = ffStrbufCreate();
22 ffSizeAppendNum(storage.bytesTotal, &totalPretty);
23
24 double percentage = storage.bytesTotal == 0
25 ? 0
26 : (double) storage.bytesUsed / (double) storage.bytesTotal * 100.0;
27
28 FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type;
29 if (options->moduleArgs.outputFormat.length == 0) {
30 ffPrintLogoAndKey(FF_MODULE_GET_DISPLAY_NAME(Memory), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
31 if (storage.bytesTotal == 0) {
32 puts("Disabled");
33 } else {
34 FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate();
35
36 if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) {
37 ffPercentAppendBar(&str, percentage, options->percent, &options->moduleArgs);
38 ffStrbufAppendC(&str, ' ');
39 }
40
41 if (!(percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) {
42 ffStrbufAppendF(&str, "%s / %s ", usedPretty.chars, totalPretty.chars);
43 }
44
45 if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) {
46 ffPercentAppendNum(&str, percentage, options->percent, str.length > 0, &options->moduleArgs);
47 }
48
49 ffStrbufTrimRight(&str, ' ');
50 ffStrbufPutTo(&str, stdout);
51 }
52 } else {
53 FF_STRBUF_AUTO_DESTROY percentageNum = ffStrbufCreate();
54 if (percentType & FF_PERCENTAGE_TYPE_NUM_BIT) {
55 ffPercentAppendNum(&percentageNum, percentage, options->percent, false, &options->moduleArgs);
56 }
57 FF_STRBUF_AUTO_DESTROY percentageBar = ffStrbufCreate();
58 if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) {
59 ffPercentAppendBar(&percentageBar, percentage, options->percent, &options->moduleArgs);
60 }
61
62 FF_PRINT_FORMAT_CHECKED(FF_MODULE_GET_DISPLAY_NAME(Memory), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, ((FFformatarg[]) {
63 FF_ARG(usedPretty, "used"),
64 FF_ARG(totalPretty, "total"),
65 FF_ARG(percentageNum, "percentage"),
66 FF_ARG(percentageBar, "percentage-bar"),
67 }));
68 }
69
70 return true;
71}
72
73void ffParseMemoryJsonObject(FFMemoryOptions* options, yyjson_val* module) {
74 yyjson_val *key, *val;
75 size_t idx, max;
76 yyjson_obj_foreach (module, idx, max, key, val) {
77 if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs)) {
78 continue;
79 }
80
81 if (ffPercentParseJsonObject(key, val, &options->percent)) {
82 continue;
83 }
84
85 ffPrintError(FF_MODULE_GET_DISPLAY_NAME(Memory), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", unsafe_yyjson_get_str(key));
86 }
87}
88
89[[gnu::cold]]
90void ffGenerateMemoryJsonConfig(FFMemoryOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) {
91 ffJsonConfigGenerateModuleArgsConfig(doc, module, &options->moduleArgs);
92
93 ffPercentGenerateJsonConfig(doc, module, options->percent);
94}
95
96bool ffGenerateMemoryJsonResult([[maybe_unused]] FFMemoryOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) {
97 FFMemoryResult storage = {};
98 const char* error = ffDetectMemory(&storage);
99
100 if (error) {
101 yyjson_mut_obj_add_str(doc, module, "error", error);
102 return false;
103 }
104
105 yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
106 yyjson_mut_obj_add_uint(doc, obj, "total", storage.bytesTotal);
107 yyjson_mut_obj_add_uint(doc, obj, "used", storage.bytesUsed);
108
109 return true;
110}
111
112void ffInitMemoryOptions(FFMemoryOptions* options) {
113 ffOptionInitModuleArg(&options->moduleArgs, "");
114 options->percent = (FFPercentageModuleConfig) { 50, 80, 0 };
115}
116
117void ffDestroyMemoryOptions(FFMemoryOptions* options) {
118 ffOptionDestroyModuleArg(&options->moduleArgs);
119}
120
121FFModuleBaseInfo ffMemoryModuleInfo = {
122 .name = "Memory",
123 .description = "Print system memory usage information",
124 .displayName = {
125 .en = "Memory",
126 .ar = "الذاكرة",
127 .cs = "Paměť",
128 .de = "Speicher",
129 .es = "Memoria",
130 .fi = "Keskusmuisti",
131 .fr = "Mémoire",
132 .gl = "Memoria",
133 .he = "זיכרון",
134 .id = "Memori",
135 .it = "Memoria",
136 .ja = "メモリ",
137 .ko = "메모리",
138 .pl = "Pamięć",
139 .pt = "Memória",
140 .ru = "Память",
141 .tr = "Bellek",
142 .uk = "Пам'ять",
143 .vi = "Bộ nhớ",
144 .zh_CN = "内存",
145 .zh_TW = "記憶體",
146 },
147 .initOptions = (void*) ffInitMemoryOptions,
148 .destroyOptions = (void*) ffDestroyMemoryOptions,
149 .parseJsonObject = (void*) ffParseMemoryJsonObject,
150 .printModule = (void*) ffPrintMemory,
151 .generateJsonResult = (void*) ffGenerateMemoryJsonResult,
152 .generateJsonConfig = (void*) ffGenerateMemoryJsonConfig,
153 .formatArgs = FF_FORMAT_ARG_LIST(((FFModuleFormatArg[]) {
154 { "Used size", "used" },
155 { "Total size", "total" },
156 { "Percentage used (num)", "percentage" },
157 { "Percentage used (bar)", "percentage-bar" },
158 })),
159 .defaultOrder = 39,
160};