Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const c_flags = [_][]const u8{
};

const src_files = [_][]const u8{
"src/utils.c",
"src/main.c",
"src/search.c",
"src/config.c",
Expand Down Expand Up @@ -203,6 +204,15 @@ pub fn build(b: *std.Build) !void {
const include_paths = try getIncludePaths(b);
exe.root_module.addCMacro("GIT_VERSION", b.fmt("\"{s}\"", .{version}));
if (valgrind) exe.root_module.addCMacro("WITH_VALGRIND", "1");

const prefix = b.install_prefix;
const sysconfdir = if (std.mem.eql(u8, prefix, "/usr"))
"/etc"
else
b.fmt("{s}/etc", .{prefix});

exe.root_module.addCMacro("SYSCONFDIR", b.fmt("\"{s}\"", .{sysconfdir}));

addSystemLibraryPaths(exe.root_module, io);
addCIncludePaths(exe.root_module, include_paths);

Expand Down Expand Up @@ -247,8 +257,12 @@ pub fn build(b: *std.Build) !void {
"tests/all_test.c",
"tests/structures_test.c",
"tests/theme_test.c",
"tests/config_test.c",
"tests/utils_test.c",
"src/structures.c",
"src/theme.c",
"src/utils.c",
"src/config.c",
}, test_flags);
addCSourceFiles(unit_test.root_module, &[_][]const u8{
"subprojects/unity/src/unity.c",
Expand Down
11 changes: 10 additions & 1 deletion src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,18 @@ static struct cag_option options[] = {
.access_name = "config",
.value_name = "FILE",
.description = "Path to a theme configuration file (TOML)"},
};
{.identifier = 's',
.access_letters = "s",
.access_name = "sway-config",
.value_name = "FILE",
.description = "Path to sway config. Defaults to None. When None, sway "
"path resolution is followed."}};

static void init_args(cli_args *args) {
args->help = false;
args->version = false;
args->config = NULL;
args->sway_config = NULL;
}

bool parse_cli(int argc, char **argv, cli_args *args) {
Expand All @@ -51,6 +57,9 @@ bool parse_cli(int argc, char **argv, cli_args *args) {
case 'c':
args->config = (char *)cag_option_get_value(&context);
break;
case 's':
args->sway_config = (char *)cag_option_get_value(&context);
break;
case '?':
cag_option_print_error(&context, stderr);
return false;
Expand Down
1 change: 1 addition & 0 deletions src/cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ typedef struct {
bool help;
bool version;
char *config;
char *sway_config;
} cli_args;

/**
Expand Down
59 changes: 54 additions & 5 deletions src/config.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "config.h"
#include "asprintf.h"
#include "structures.h"
#include "utils.h"
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
Expand Down Expand Up @@ -61,15 +62,63 @@ config_error_t config_read_file(const char *filepath, stringlist_t *out) {
return CONFIG_SUCCESS;
}

char *config_get_sway_filepath(void) {
const char *home = getenv("HOME");
if (!home)
// NOTE: Copied (with modifications) from
// https://github.com/swaywm/sway/blob/f1b40bc288f3be3bcc6a3c71f28ca9bb2529e70b/sway/config.c
static char *config_path(const char *prefix, const char *config_folder) {
if (!prefix || !prefix[0] || !config_folder || !config_folder[0]) {
return NULL;

}
char *path = NULL;
if (asprintf(&path, "%s/.config/sway/config", home) == -1)
// NOTE: Different here.
if (asprintf(&path, "%s/%s/config", prefix, config_folder) < 0)
return NULL;
return path;
}

char *config_get_sway_filepath(void) {
char *path = NULL;
const char *home = getenv("HOME");
const char *config_home = getenv("XDG_CONFIG_HOME");
char *config_home_fallback = NULL;
if (config_home == NULL || config_home[0] == '\0') {
if (!home)
return NULL;
if (asprintf(&config_home_fallback, "%s/.config/", home) == -1)
return NULL;
config_home = config_home_fallback;
}
// NOTE: Copied (with modifications) from
// https://github.com/swaywm/sway/blob/f1b40bc288f3be3bcc6a3c71f28ca9bb2529e70b/sway/config.c
struct config_path {
const char *prefix;
const char *config_folder;
};

struct config_path config_paths[] = {
{.prefix = home, .config_folder = ".sway"},
{.prefix = config_home, .config_folder = "sway"},
{.prefix = home, .config_folder = ".i3"},
{.prefix = config_home, .config_folder = "i3"},
// NOTE: Different from original
{.prefix = SYSCONFDIR, .config_folder = "sway"},
// NOTE: Different from original
{.prefix = SYSCONFDIR, .config_folder = "i3"}};

size_t num_config_paths = sizeof(config_paths) / sizeof(config_paths[0]);
for (size_t i = 0; i < num_config_paths; i++) {
path =
config_path(config_paths[i].prefix, config_paths[i].config_folder);
if (!path) {
continue;
}
if (file_exists(path)) {
break;
}
free(path);
path = NULL;
}

free(config_home_fallback);
return path;
}

Expand Down
6 changes: 6 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@

#ifndef CONFIG_H
#define CONFIG_H

#ifndef SYSCONFDIR
#define SYSCONFDIR "/usr/local/etc"
#endif


#include <stddef.h>
#include "structures.h"

Expand Down
8 changes: 6 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,12 @@ int main(int argc, char *argv[]) {

return ThemeError;
}

char *filepath = config_get_sway_filepath();
char *filepath;
if (args.sway_config) {
filepath = args.sway_config;
} else {
filepath = config_get_sway_filepath();
}
if (!filepath) {
if (fprintf(stderr, "failed to determine sway config path\n"))
return IOError;
Expand Down
27 changes: 1 addition & 26 deletions src/theme.c
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
#include "theme.h"
#include "asprintf.h"
#include "tomlc17.h"
#include "utils.h"
#include <errno.h>
#include <libgen.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

static theme_error_t create_file(const char *filepath, bool create_dir);
static bool file_exists(const char *filepath);
static void color_init_with_defaults(theme_color_t *color);
static theme_color_t color_new_with_defaults(void);
static void font_init_with_defaults(theme_font_t *font);
Expand All @@ -33,10 +31,6 @@ static theme_error_t theme_toml_parse_bottom(const toml_result_t *toml,
theme_layer_t *layer);
static void theme_layer_merge(theme_layer_t *dest, const theme_layer_t *src);

static bool file_exists(const char *filepath) {
return (bool)(access(filepath, F_OK) == 0);
}

void parse_hex_color(const char *hex_str, theme_color_t *c) {
if (hex_str == NULL || c == NULL)
return;
Expand Down Expand Up @@ -169,25 +163,6 @@ static void font_init_with_defaults(theme_font_t *font) {
.r = 130, .g = 130, .b = 130, .a = 255, .has_alpha = true};
}

static char *get_app_prefix(void) {
char exe_buf[PATH_MAX + 1];
ssize_t len = readlink("/proc/self/exe", exe_buf, PATH_MAX);
if (len == -1)
return NULL;

exe_buf[len] = '\0';

char *last_slash = strrchr(exe_buf, '/');
if (last_slash)
*last_slash = '\0';

last_slash = strrchr(exe_buf, '/');
if (last_slash)
*last_slash = '\0';

return strdup(exe_buf);
}

static char *resolve_default_font_path(void) {
char *prefix = get_app_prefix();
if (!prefix)
Expand Down
28 changes: 28 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "utils.h"
#include <limits.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>

bool file_exists(const char *filepath) {
return (bool)(access(filepath, F_OK) == 0);
}

char *get_app_prefix(void) {
char exe_buf[PATH_MAX + 1];
ssize_t len = readlink("/proc/self/exe", exe_buf, PATH_MAX);
if (len == -1)
return NULL;

exe_buf[len] = '\0';

char *last_slash = strrchr(exe_buf, '/');
if (last_slash)
*last_slash = '\0';

last_slash = strrchr(exe_buf, '/');
if (last_slash)
*last_slash = '\0';

return strdup(exe_buf);
}
9 changes: 9 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef UTILS_H
#define UTILS_H

#include <stdbool.h>

bool file_exists(const char *filepath);
char *get_app_prefix(void);
#endif

46 changes: 44 additions & 2 deletions tests/all_test.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,29 @@
#include "unity.h"
#include <stdlib.h>
#include <string.h>

void setUp(void) {}
void tearDown(void) {}
static char *saved_home;
static char *saved_xdg;

void setUp(void) {
char *h = getenv("HOME");
saved_home = h ? strdup(h) : NULL;
char *x = getenv("XDG_CONFIG_HOME");
saved_xdg = x ? strdup(x) : NULL;
}

void tearDown(void) {
if (saved_home) {
setenv("HOME", saved_home, 1);
free(saved_home);
} else
unsetenv("HOME");
if (saved_xdg) {
setenv("XDG_CONFIG_HOME", saved_xdg, 1);
free(saved_xdg);
} else
unsetenv("XDG_CONFIG_HOME");
}

extern void test_in_intlist(void);
extern void test_get_segments(void);
Expand All @@ -25,6 +47,16 @@ extern void test_section_overrides_global(void);
extern void test_global_alpha_propagates_to_sections(void);
extern void test_section_alpha_propagates_to_body(void);

extern void test_file_exists_for_existing_file(void);
extern void test_file_exists_for_missing_file(void);
extern void test_sway_filepath_home_sway_dir(void);
extern void test_sway_filepath_xdg_config_home_sway(void);
extern void test_sway_filepath_home_sway_beats_xdg(void);
extern void test_sway_filepath_falls_back_to_i3(void);
extern void test_sway_filepath_none_exist_returns_null(void);
extern void test_sway_filepath_no_home_no_xdg_returns_null(void);
extern void test_sway_filepath_xdg_config_home_i3(void);

int main(void) {
UNITY_BEGIN();

Expand All @@ -50,5 +82,15 @@ int main(void) {
RUN_TEST(test_global_alpha_propagates_to_sections);
RUN_TEST(test_section_alpha_propagates_to_body);

RUN_TEST(test_file_exists_for_existing_file);
RUN_TEST(test_file_exists_for_missing_file);
RUN_TEST(test_sway_filepath_home_sway_dir);
RUN_TEST(test_sway_filepath_xdg_config_home_sway);
RUN_TEST(test_sway_filepath_home_sway_beats_xdg);
RUN_TEST(test_sway_filepath_falls_back_to_i3);
RUN_TEST(test_sway_filepath_none_exist_returns_null);
RUN_TEST(test_sway_filepath_no_home_no_xdg_returns_null);
RUN_TEST(test_sway_filepath_xdg_config_home_i3);

return UNITY_END();
}
Loading
Loading