| 1 | ! Configuration directory management module |
| 2 | ! Handles ~/.config/fac/ directory creation and path resolution |
| 3 | |
| 4 | module config_module |
| 5 | use iso_fortran_env, only: int32 |
| 6 | implicit none |
| 7 | private |
| 8 | |
| 9 | public :: get_config_dir, ensure_config_dir |
| 10 | |
| 11 | integer, parameter :: MAX_PATH_LEN = 512 |
| 12 | |
| 13 | contains |
| 14 | |
| 15 | !> Get configuration directory path |
| 16 | !> Returns ~/.config/fac/ or ~/.fac/ as fallback |
| 17 | subroutine get_config_dir(config_path) |
| 18 | character(len=:), allocatable, intent(out) :: config_path |
| 19 | character(len=MAX_PATH_LEN) :: home_dir, xdg_config_home |
| 20 | integer :: unit, ios |
| 21 | |
| 22 | ! Try XDG_CONFIG_HOME environment variable |
| 23 | call get_environment_variable('XDG_CONFIG_HOME', xdg_config_home) |
| 24 | |
| 25 | if (len_trim(xdg_config_home) > 0) then |
| 26 | ! XDG_CONFIG_HOME is set |
| 27 | config_path = trim(xdg_config_home) // '/fac' |
| 28 | else |
| 29 | ! Fall back to ~/.config/fac |
| 30 | call get_home_directory(home_dir) |
| 31 | |
| 32 | ! Check if ~/.config exists |
| 33 | call execute_command_line('test -d "' // trim(home_dir) // & |
| 34 | '/.config" && echo "1" > /tmp/.fac_xdg_check || echo "0" > /tmp/.fac_xdg_check', & |
| 35 | wait=.true.) |
| 36 | |
| 37 | open(newunit=unit, file='/tmp/.fac_xdg_check', status='old', iostat=ios) |
| 38 | if (ios == 0) then |
| 39 | read(unit, '(A)', iostat=ios) xdg_config_home |
| 40 | close(unit) |
| 41 | call execute_command_line('rm -f /tmp/.fac_xdg_check', wait=.true.) |
| 42 | |
| 43 | if (trim(xdg_config_home) == '1') then |
| 44 | config_path = trim(home_dir) // '/.config/fac' |
| 45 | else |
| 46 | ! Fallback to ~/.fac |
| 47 | config_path = trim(home_dir) // '/.fac' |
| 48 | end if |
| 49 | else |
| 50 | ! Error checking, use fallback |
| 51 | config_path = trim(home_dir) // '/.fac' |
| 52 | end if |
| 53 | end if |
| 54 | end subroutine get_config_dir |
| 55 | |
| 56 | !> Ensure configuration directory exists (create if needed) |
| 57 | subroutine ensure_config_dir(success) |
| 58 | logical, intent(out) :: success |
| 59 | character(len=:), allocatable :: config_path |
| 60 | integer :: exit_status |
| 61 | |
| 62 | success = .false. |
| 63 | call get_config_dir(config_path) |
| 64 | |
| 65 | ! Create directory if it doesn't exist |
| 66 | call execute_command_line('mkdir -p "' // trim(config_path) // '"', & |
| 67 | wait=.true., exitstat=exit_status) |
| 68 | |
| 69 | success = (exit_status == 0) |
| 70 | end subroutine ensure_config_dir |
| 71 | |
| 72 | !> Get user's home directory |
| 73 | subroutine get_home_directory(home_dir) |
| 74 | character(len=*), intent(out) :: home_dir |
| 75 | integer :: unit, ios |
| 76 | |
| 77 | ! Try HOME environment variable first |
| 78 | call get_environment_variable('HOME', home_dir) |
| 79 | |
| 80 | if (len_trim(home_dir) == 0) then |
| 81 | ! Fallback: use shell expansion |
| 82 | call execute_command_line('echo $HOME > /tmp/.fac_home', wait=.true.) |
| 83 | open(newunit=unit, file='/tmp/.fac_home', status='old', iostat=ios) |
| 84 | if (ios == 0) then |
| 85 | read(unit, '(A)', iostat=ios) home_dir |
| 86 | close(unit) |
| 87 | call execute_command_line('rm -f /tmp/.fac_home', wait=.true.) |
| 88 | else |
| 89 | ! Last resort fallback |
| 90 | home_dir = '~' |
| 91 | end if |
| 92 | end if |
| 93 | end subroutine get_home_directory |
| 94 | |
| 95 | end module config_module |
| 96 |