From 468126196aba8aa60289393d5c0e5c8b3b2efcfb Mon Sep 17 00:00:00 2001
From: louie <lshprung@yahoo.com>
Date: Sun, 20 Dec 2020 14:30:06 -0800
Subject: Built framework for config auto-generation

---
 draw.c     |   5 +-
 draw.o     | Bin 0 -> 19712 bytes
 entry.o    | Bin 0 -> 5000 bytes
 group.o    | Bin 0 -> 8216 bytes
 read_cfg.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 read_cfg.h |   4 ++
 read_cfg.o | Bin 0 -> 20400 bytes
 tml        | Bin 0 -> 46960 bytes
 8 files changed, 153 insertions(+), 11 deletions(-)
 create mode 100644 draw.o
 create mode 100644 entry.o
 create mode 100644 group.o
 create mode 100644 read_cfg.o
 create mode 100755 tml

diff --git a/draw.c b/draw.c
index 7afcd94..7e58d23 100644
--- a/draw.c
+++ b/draw.c
@@ -29,7 +29,6 @@ void switch_col();
 void trav_col(int new_i);
 int locateChar(char input);
 char *get_launch();
-char *compat_convert(char *path, int mode);
 #if defined _WIN32 || defined _WIN64
 void win_launch();
 #endif
@@ -57,7 +56,11 @@ int main(int argc, char **argv){
 
 	//if a config path was given as an argument, set it accordingly
 	if(argc > 2 && (!strcmp(argv[1], "-c") || !strcmp(argv[1], "--cfg_path"))) strcpy(cfg_path, argv[2]);
+#if defined _WIN32 || defined _WIN64
+	else strcpy(cfg_path, find_config_win());
+#else
 	else strcpy(cfg_path, find_config());
+#endif
 
 	//Fill Groups
 	cfg_interp(cfg_path); //read the contents of the cfg file
diff --git a/draw.o b/draw.o
new file mode 100644
index 0000000..5aee7fc
Binary files /dev/null and b/draw.o differ
diff --git a/entry.o b/entry.o
new file mode 100644
index 0000000..7c77f09
Binary files /dev/null and b/entry.o differ
diff --git a/group.o b/group.o
new file mode 100644
index 0000000..e8f6ea5
Binary files /dev/null and b/group.o differ
diff --git a/read_cfg.c b/read_cfg.c
index 6c37fe3..9235108 100644
--- a/read_cfg.c
+++ b/read_cfg.c
@@ -5,6 +5,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
 #include "entry.h"
 #include "group.h"
@@ -13,7 +15,11 @@
 #define OPTION_CNT 13
 
 //public
+#if defined _WIN32 || defined _WIN64
+char *find_config_win();
+#else
 char *find_config();
+#endif
 void cfg_interp(char *path);
 int get_compmode();
 bool get_sort();
@@ -21,6 +27,7 @@ bool get_case_sensitivity();
 void refer_to_doc();
 
 //private
+void mkconfig_wizard(char *path);
 void check_line(char *buffer, char **options, int ln);
 int check_option(char *arg, char **options);
 void handle_fname(char *path, char *group, bool recurs, bool force, char *name, int ln);
@@ -47,6 +54,33 @@ char sep = '\\';
 char sep = '/';
 #endif
 
+#if defined _WIN32 || defined _WIN64
+char *find_config_win(){
+	char *appdata = getenv("APPDATA");
+	char *path = malloc(sizeof(char) * BUF_LEN);
+	int check_count = 1;
+	char choices[check_count][BUF_LEN];
+	int i;
+
+	sprintf(choices[0], "%s%ctml%cconfig", appdata, sep, sep);
+
+	for(i = 0; i < check_count; i++){
+		path = choices[i];
+		printf("Checking for config at %s: ", choices[i]);
+		if(access(path, R_OK) == 0){
+			printf("Using config \"%s\"\n\n", path);
+			return path;
+		}
+		else printf("File does not exist\n");
+	}
+
+	//TODO no config exists, ask user if they want to autogenerate one
+	mkconfig_wizard(choices[0]);
+	path = choices[0];
+	return path;
+}
+
+#else
 char *find_config(){
 	char *home = getenv("HOME");
 	char *path = malloc(sizeof(char) * BUF_LEN);
@@ -57,8 +91,6 @@ char *find_config(){
 	sprintf(choices[0], "%s%c.config%ctml%cconfig", home, sep, sep, sep);
 	sprintf(choices[1], "%s%c.tml%cconfig", home, sep, sep);
 
-	//TODO where do we want the Windows config to be?
-
 	for(i = 0; i < check_count; i++){
 		path = choices[i];
 		printf("Checking for config at %s: ", choices[i]);
@@ -69,8 +101,12 @@ char *find_config(){
 		else printf("File does not exist\n");
 	}
 
-	return "config";
+	//TODO no config exists, ask user if they want to autogenerate one
+	mkconfig_wizard(choices[0]);
+	path = choices[0];
+	return path;
 }
+#endif
 
 void cfg_interp(char *path){
 	FILE *fp;
@@ -83,13 +119,7 @@ void cfg_interp(char *path){
 	int j;
 
 	fp = fopen(path, "r");
-	//assert(fp != NULL);
-	if(fp == NULL){
-		printf("config does not exist in current directory. ");
-		refer_to_doc();
-		exit(0);
-	}
-	else if(!strcmp(path, "config")) printf("Using config in current directory\n");
+	assert(fp != NULL);
 
 	//build the options array
 	char **options = malloc(sizeof(char *) * OPTION_CNT);
@@ -148,6 +178,111 @@ void refer_to_doc(){
 	return;
 }
 
+void mkconfig_wizard(char *path){
+	char input;
+	FILE *fp;
+
+#if defined _WIN32 || defined _WIN64
+	char *home = getenv("USERPROFILE");
+	char *appdata = getenv("APPDATA");
+#else
+	char *home = getenv("HOME");
+#endif
+
+	printf("\nNo configuration file found. Auto-generate one now at \"%s\"? [Y/n] ", path);
+	fflush(stdout);
+	scanf("%c", &input);
+
+	if(input == 'n'){
+		printf("Configuration will not be auto-generated\n");
+		refer_to_doc();
+		exit(0);
+		
+	}
+
+	printf("Generating configuration file at \"%s\"...\n", path);
+
+	//ensure directories have been created
+#if defined _WIN32 || defined _WIN64
+	if(appdata == NULL){
+		printf("Failed: \%APPDATA\% is NULL\n");
+		exit(1);
+	}
+
+	if(home == NULL){
+		printf("Failed: \%USERPROFILE\% is NULL\n");
+		exit(1);
+	}
+
+	sprintf(path, "%s%ctml%c", appdata, sep, sep);
+	mkdir(path);
+
+	sprintf(path, "%s%ctml%cconfig", appdata, sep, sep);
+#else
+	if(home == NULL){
+		printf("Failed: HOME is NULL\n");
+		exit(1);
+	}
+
+	sprintf(path, "%s%c.config%c", home, sep, sep);
+	mkdir(path, 0755);
+
+	sprintf(path, "%s%c.config%ctml%c", home, sep, sep, sep);
+	mkdir(path, 0755);
+
+	sprintf(path, "%s%c.config%ctml%cconfig", home, sep, sep, sep);
+#endif
+
+	//open file for writing, make sure non-NULL
+	fp = fopen(path, "w");
+	if(fp == NULL){
+		printf("Failed: \"%s\" could not be open for writing\n", path);
+		exit(1);
+	}
+
+	//write to file (in Windows, launch an application with the default launcher by invoking "start")
+	//FIXME at the moment, this WILL NOT WORK. I need to add an option to set launcher without quotes
+#if defined _WIN32 || defined _WIN64
+	fprintf(fp, "# This file was auto-generated by tml. See docs/tml-config.md or tml-config(5) for documentation\n"
+	"# Please note that the launcher \"start\" is a built-in Windows command to launch a file with the default application\n\n"
+	"# Recursively add files from %s%cMusic%c to Music group\n"
+	"addGroup Music\n"
+	"setLauncher Music start\n"
+	"addR %s%cMusic%c* Music\n\n"
+	"# Recursively add files from %s%cPictures%c to Pictures group\n"
+	"addGroup Pictures\n"
+	"setLauncher Pictures start\n"
+	"addR %s%cPictures%c* Pictures\n\n"
+	"# Recursively add files from %s%cVideos%c to Videos group\n"
+	"addGroup Videos\n"
+	"setLauncher Videos start\n"
+	"addR %s%cVideos%c* Videos", home, sep, sep, home, sep, sep, home, sep, sep, home, sep, sep, home, sep, sep, home, sep, sep);
+#else
+	fprintf(fp, "# This file was auto-generated by tml. See docs/tml-config.md or tml-config(5) for documentation\n"
+	"# The default launcher is set to \"xdg-open\" which will open files based on the relevant default application set through xdg\n\n"
+	"# Recursively add files from %s%cMusic%c to Music group\n"
+	"addGroup Music\n"
+	"setLauncher Music xdg-open\n"
+	"addR %s%cMusic%c* Music\n\n"
+	"# Recursively add files from %s%cPictures%c to Pictures group\n"
+	"addGroup Pictures\n"
+	"setLauncher Pictures xdg-open\n"
+	"addR %s%cPictures%c* Pictures\n\n"
+	"# Recursively add files from %s%cVideos%c to Videos group\n"
+	"addGroup Videos\n"
+	"setLauncher Videos xdg-open\n"
+	"addR %s%cVideos%c* Videos", home, sep, sep, home, sep, sep, home, sep, sep, home, sep, sep, home, sep, sep, home, sep, sep);
+#endif
+
+	fclose(fp);
+	printf("done\nIt is highly recommended to further tweak the configuration file! [press any key to continue]");
+	fflush(stdout);
+	fflush(stdin);
+	getchar();
+
+	return;
+}
+
 //TODO add support for "addR" recursive adding (still needs work...)
 //TODO add support for "alias" option
 //TODO add support for "hide" option
diff --git a/read_cfg.h b/read_cfg.h
index e6583de..b8edd64 100644
--- a/read_cfg.h
+++ b/read_cfg.h
@@ -1,7 +1,11 @@
 #ifndef READ_CFG_H
 #define READ_CFG_H
 
+#if defined _WIN32 || defined _WIN64
+char *find_config_win();
+#else
 char *find_config();
+#endif
 
 void cfg_interp();
 
diff --git a/read_cfg.o b/read_cfg.o
new file mode 100644
index 0000000..3efc7b8
Binary files /dev/null and b/read_cfg.o differ
diff --git a/tml b/tml
new file mode 100755
index 0000000..e13f80b
Binary files /dev/null and b/tml differ
-- 
cgit