From d6231bab89d634da5564491196b7c478db038505 Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Sat, 4 Mar 2006 18:16:49 +0000 Subject: Initial import. --- Settings.c | 217 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 Settings.c (limited to 'Settings.c') diff --git a/Settings.c b/Settings.c new file mode 100644 index 00000000..1661f7fa --- /dev/null +++ b/Settings.c @@ -0,0 +1,217 @@ +/* +htop - Settings.c +(C) 2004,2005 Hisham H. Muhammad +Released under the GNU GPL, see the COPYING file +in the source distribution for its full text. +*/ + +#include "Settings.h" +#include "String.h" +#include "ProcessList.h" +#include "Header.h" + +#include "debug.h" + +#define DEFAULT_DELAY 15 + +/*{ + +typedef struct Settings_ { + char* userSettings; + ProcessList* pl; + Header* header; + int colorScheme; + bool changed; + int delay; +} Settings; + +}*/ + +Settings* Settings_new(ProcessList* pl, Header* header) { + Settings* this = malloc(sizeof(Settings)); + this->pl = pl; + this->header = header; + char* home; + home = getenv("HOME_ETC"); + if (!home) home = getenv("HOME"); + if (!home) home = ""; + this->userSettings = String_cat(home, "/.htoprc"); + this->colorScheme = 0; + this->changed = false; + this->delay = DEFAULT_DELAY; + bool ok = Settings_read(this, this->userSettings); + if (!ok) { + this->changed = true; + // TODO: how to get SYSCONFDIR correctly through Autoconf? + char* systemSettings = String_cat(SYSCONFDIR, "/htoprc"); + ok = Settings_read(this, systemSettings); + free(systemSettings); + if (!ok) { + Header_defaultMeters(this->header); + pl->hideKernelThreads = true; + pl->highlightMegabytes = true; + } + } + return this; +} + +void Settings_delete(Settings* this) { + free(this->userSettings); + free(this); +} + +/* private */ +void Settings_readMeters(Settings* this, char* line, HeaderSide side) { + char* trim = String_trim(line); + char** ids = String_split(trim, ' '); + free(trim); + int i; + for (i = 0; ids[i] != NULL; i++) { + Header_createMeter(this->header, ids[i], side); + } + String_freeArray(ids); +} + +/* private */ +void Settings_readMeterModes(Settings* this, char* line, HeaderSide side) { + char* trim = String_trim(line); + char** ids = String_split(trim, ' '); + free(trim); + int i; + for (i = 0; ids[i] != NULL; i++) { + int mode = atoi(ids[i]); + Header_setMode(this->header, i, mode, side); + } + String_freeArray(ids); +} + +bool Settings_read(Settings* this, char* fileName) { + // TODO: implement File object and make + // file I/O object-oriented. + FILE* fd; + fd = fopen(fileName, "r"); + if (fd == NULL) { + return false; + } + const int maxLine = 512; + char buffer[maxLine]; + bool readMeters = false; + while (!feof(fd)) { + buffer[0] = '\0'; + fgets(buffer, maxLine, fd); + char** option = String_split(buffer, '='); + if (String_eq(option[0], "fields")) { + char* trim = String_trim(option[1]); + char** ids = String_split(trim, ' '); + free(trim); + int i, j; + for (j = 0, i = 0; i < LAST_PROCESSFIELD && ids[i] != NULL; i++) { + // This "+1" is for compatibility with the older enum format. + int id = atoi(ids[i]) + 1; + if (id > 0 && id < LAST_PROCESSFIELD) { + this->pl->fields[j] = id; + j++; + } + } + this->pl->fields[j] = (ProcessField) NULL; + String_freeArray(ids); + } else if (String_eq(option[0], "sort_key")) { + // This "+1" is for compatibility with the older enum format. + this->pl->sortKey = atoi(option[1]) + 1; + } else if (String_eq(option[0], "sort_direction")) { + this->pl->direction = atoi(option[1]); + } else if (String_eq(option[0], "tree_view")) { + this->pl->treeView = atoi(option[1]); + } else if (String_eq(option[0], "hide_threads")) { + this->pl->hideThreads = atoi(option[1]); + } else if (String_eq(option[0], "hide_kernel_threads")) { + this->pl->hideKernelThreads = atoi(option[1]); + } else if (String_eq(option[0], "hide_userland_threads")) { + this->pl->hideUserlandThreads = atoi(option[1]); + } else if (String_eq(option[0], "shadow_other_users")) { + this->pl->shadowOtherUsers = atoi(option[1]); + } else if (String_eq(option[0], "highlight_base_name")) { + this->pl->highlightBaseName = atoi(option[1]); + } else if (String_eq(option[0], "highlight_megabytes")) { + this->pl->highlightMegabytes = atoi(option[1]); + } else if (String_eq(option[0], "header_margin")) { + this->header->margin = atoi(option[1]); + } else if (String_eq(option[0], "delay")) { + this->delay = atoi(option[1]); + } else if (String_eq(option[0], "color_scheme")) { + this->colorScheme = atoi(option[1]); + if (this->colorScheme < 0) this->colorScheme = 0; + if (this->colorScheme > 5) this->colorScheme = 5; + } else if (String_eq(option[0], "left_meters")) { + Settings_readMeters(this, option[1], LEFT_HEADER); + readMeters = true; + } else if (String_eq(option[0], "right_meters")) { + Settings_readMeters(this, option[1], RIGHT_HEADER); + readMeters = true; + } else if (String_eq(option[0], "left_meter_modes")) { + Settings_readMeterModes(this, option[1], LEFT_HEADER); + readMeters = true; + } else if (String_eq(option[0], "right_meter_modes")) { + Settings_readMeterModes(this, option[1], RIGHT_HEADER); + readMeters = true; + } + String_freeArray(option); + } + fclose(fd); + if (!readMeters) { + Header_defaultMeters(this->header); + } + return true; +} + +bool Settings_write(Settings* this) { + // TODO: implement File object and make + // file I/O object-oriented. + FILE* fd; + fd = fopen(this->userSettings, "w"); + if (fd == NULL) { + return false; + } + fprintf(fd, "# Beware! This file is rewritten every time htop exits.\n"); + fprintf(fd, "# The parser is also very primitive, and not human-friendly.\n"); + fprintf(fd, "# (I know, it's in the todo list).\n"); + fprintf(fd, "fields="); + for (int i = 0; this->pl->fields[i]; i++) { + // This "-1" is for compatibility with the older enum format. + fprintf(fd, "%d ", (int) this->pl->fields[i]-1); + } + fprintf(fd, "\n"); + // This "-1" is for compatibility with the older enum format. + fprintf(fd, "sort_key=%d\n", (int) this->pl->sortKey-1); + fprintf(fd, "sort_direction=%d\n", (int) this->pl->direction); + fprintf(fd, "hide_threads=%d\n", (int) this->pl->hideThreads); + fprintf(fd, "hide_kernel_threads=%d\n", (int) this->pl->hideKernelThreads); + fprintf(fd, "hide_userland_threads=%d\n", (int) this->pl->hideUserlandThreads); + fprintf(fd, "shadow_other_users=%d\n", (int) this->pl->shadowOtherUsers); + fprintf(fd, "highlight_base_name=%d\n", (int) this->pl->highlightBaseName); + fprintf(fd, "highlight_megabytes=%d\n", (int) this->pl->highlightMegabytes); + fprintf(fd, "tree_view=%d\n", (int) this->pl->treeView); + fprintf(fd, "header_margin=%d\n", (int) this->header->margin); + fprintf(fd, "color_scheme=%d\n", (int) this->colorScheme); + fprintf(fd, "delay=%d\n", (int) this->delay); + fprintf(fd, "left_meters="); + for (int i = 0; i < Header_size(this->header, LEFT_HEADER); i++) { + fprintf(fd, "%s ", Header_readMeterName(this->header, i, LEFT_HEADER)); + } + fprintf(fd, "\n"); + fprintf(fd, "left_meter_modes="); + for (int i = 0; i < Header_size(this->header, LEFT_HEADER); i++) + fprintf(fd, "%d ", Header_readMeterMode(this->header, i, LEFT_HEADER)); + fprintf(fd, "\n"); + fprintf(fd, "right_meters="); + for (int i = 0; i < Header_size(this->header, RIGHT_HEADER); i++) + fprintf(fd, "%s ", Header_readMeterName(this->header, i, RIGHT_HEADER)); + fprintf(fd, "\n"); + fprintf(fd, "right_meter_modes="); + for (int i = 0; i < Header_size(this->header, RIGHT_HEADER); i++) + fprintf(fd, "%d ", Header_readMeterMode(this->header, i, RIGHT_HEADER)); + fprintf(fd, "\n"); + + fclose(fd); + return true; +} -- cgit v1.2.3