@@ -553,89 +553,125 @@ static void apply_option(options_t* opts, parsed_option_t* option)
553
553
}
554
554
}
555
555
556
+ #ifdef _WIN32
557
+ # define rsh_tgetenv (name ) _wgetenv(name)
558
+ #else
559
+ # define rsh_tgetenv (name ) getenv(name)
560
+ #endif
561
+ #define COUNTOF (array ) (sizeof(array) / sizeof(*array))
562
+ enum ConfigLookupFlags
563
+ {
564
+ ConfFlagNeedSplit = 8 ,
565
+ ConfFlagNoVars = 16
566
+ };
567
+
556
568
/**
557
- * Search for config file.
569
+ * Check if a config file, specified by path subparts, is a regular file.
570
+ * On success the resulting path is stored as rhash_data.config_file.
558
571
*
559
- * @return the relative path to config file
572
+ * @param path_parts subparts of the path
573
+ * @param flags check flags
574
+ * @return 1 if the file is regular, 0 otherwise
560
575
*/
561
- static const char * find_conf_file ( void )
576
+ static int try_config ( ctpath_t path_parts [], unsigned flags )
562
577
{
563
- #ifndef SYSCONFDIR
564
- # define SYSCONFDIR "/etc"
578
+ const size_t parts_count = flags & 3 ;
579
+ tpath_t allocated = NULL ;
580
+ ctpath_t path = NULL ;
581
+ size_t i ;
582
+ for (i = 0 ; i < parts_count ; i ++ ) {
583
+ ctpath_t sub_path = path_parts [i ];
584
+ if (sub_path [0 ] == RSH_T ('$' ) && !(flags & ConfFlagNoVars )) {
585
+ sub_path = rsh_tgetenv (sub_path + 1 );
586
+ if (!sub_path || !sub_path [0 ]) {
587
+ free (allocated );
588
+ return 0 ;
589
+ }
590
+ #ifndef _WIN32
591
+ /* check if the variable should be splitted */
592
+ if (flags == (2 | ConfFlagNeedSplit ) && i == 0 ) {
593
+ tpath_t next ;
594
+ ctpath_t parts [2 ];
595
+ parts [1 ] = path_parts [1 ];
596
+ sub_path = allocated = strdup (sub_path );
597
+ do {
598
+ next = strchr (sub_path , ':' );
599
+ if (next )
600
+ * (next ++ ) = '\0' ;
601
+ if (sub_path [0 ]) {
602
+ parts [0 ] = sub_path ;
603
+ if (try_config (parts , COUNTOF (parts ) | ConfFlagNoVars )) {
604
+ free (allocated );
605
+ return 1 ;
606
+ }
607
+ }
608
+ sub_path = next ;
609
+ } while (sub_path );
610
+ free (allocated );
611
+ return 0 ;
612
+ }
565
613
#endif
566
- #define CONFIG_FILENAME "rhashrc"
567
-
568
- char * dir1 ;
569
- char * path ;
570
-
571
- #ifndef _WIN32 /* Linux/Unix part */
572
- /* first check for $XDG_CONFIG_HOME/rhash/rhashrc file */
573
- if ( (dir1 = getenv ("XDG_CONFIG_HOME" )) ) {
574
- dir1 = make_path (dir1 , "rhash" , 0 );
575
- path = make_path (dir1 , CONFIG_FILENAME , 0 );
576
- free (dir1 );
577
- if (is_regular_file (path )) {
578
- rsh_vector_add_ptr (opt .mem , path );
579
- return (conf_opt .config_file = path );
580
614
}
581
- free (path );
582
- }
583
- /* then check for $HOME/.rhashrc file */
584
- if ( (dir1 = getenv ("HOME" )) ) {
585
- path = make_path (dir1 , ".rhashrc" , 0 );
586
- if (is_regular_file (path )) {
587
- rsh_vector_add_ptr (opt .mem , path );
588
- return (conf_opt .config_file = path );
615
+ if (path ) {
616
+ tpath_t old_allocated = allocated ;
617
+ path = allocated = make_tpath (path , sub_path );
618
+ free (old_allocated );
619
+ } else {
620
+ path = sub_path ;
589
621
}
590
- free (path );
591
622
}
592
- /* then check for global config */
593
- path = SYSCONFDIR "/" CONFIG_FILENAME ;
594
- if (is_regular_file (path )) {
595
- return (conf_opt .config_file = path );
623
+ assert (!rhash_data .config_file .real_path );
624
+ {
625
+ unsigned init_flags = FileInitRunFstat | (!allocated ? FileInitReusePath : 0 );
626
+ int res = file_init (& rhash_data .config_file , path , init_flags );
627
+ free (allocated );
628
+ if (res == 0 && FILE_ISREG (& rhash_data .config_file ))
629
+ return 1 ;
630
+ file_cleanup (& rhash_data .config_file );
631
+ return 0 ;
596
632
}
633
+ }
634
+
635
+ /**
636
+ * Search for config file.
637
+ *
638
+ * @return 1 if config file is found, 0 otherwise
639
+ */
640
+ static int find_conf_file (void )
641
+ {
642
+ #ifndef SYSCONFDIR
643
+ # define SYSCONFDIR "/etc"
644
+ #endif
645
+
646
+ #ifndef _WIN32
647
+ /* Linux/Unix part */
648
+ static ctpath_t xdg_conf_home [2 ] = { "$XDG_CONFIG_HOME" , "rhash/rhashrc" };
649
+ static ctpath_t xdg_conf_default [2 ] = { "$HOME" , ".config/rhash/rhashrc" };
650
+ static ctpath_t xdg_conf_dirs [2 ] = { "$XDG_CONFIG_DIRS" , "rhash/rhashrc" };
651
+ static ctpath_t home_conf [2 ] = { "$HOME" , ".rhashrc" };
652
+ static ctpath_t sysconf_dir [1 ] = { SYSCONFDIR "/rhashrc" };
653
+
654
+ return (try_config (xdg_conf_home , COUNTOF (xdg_conf_home )) ||
655
+ try_config (xdg_conf_default , COUNTOF (xdg_conf_default )) ||
656
+ try_config (xdg_conf_dirs , COUNTOF (xdg_conf_dirs ) | ConfFlagNeedSplit ) ||
657
+ try_config (home_conf , COUNTOF (home_conf )) ||
658
+ try_config (sysconf_dir , COUNTOF (sysconf_dir )));
597
659
598
660
#else /* _WIN32 */
599
- wchar_t * program_dir = get_program_dir ();
600
-
601
- /* first check for the %APPDATA%\RHash\rhashrc config */
602
- if ( (dir1 = getenv ("APPDATA" )) ) {
603
- dir1 = make_path (dir1 , "RHash" , 0 );
604
- path = make_path (dir1 , CONFIG_FILENAME , 0 );
605
- free (dir1 );
606
- if (is_regular_file (path )) {
607
- rsh_vector_add_ptr (opt .mem , path );
608
- return (conf_opt .config_file = path );
609
- }
610
- free (path );
611
- }
612
661
613
- /* then check for %HOMEDRIVE%%HOMEPATH%\rhashrc */
614
- /* note that %USERPROFILE% is generally not a user home dir */
615
- if ( (dir1 = getenv ("HOMEDRIVE" )) && (path = getenv ("HOMEPATH" ))) {
616
- dir1 = make_path (dir1 , path , 0 );
617
- path = make_path (dir1 , CONFIG_FILENAME , 0 );
618
- free (dir1 );
619
- if (is_regular_file (path )) {
620
- rsh_vector_add_ptr (opt .mem , path );
621
- return (conf_opt .config_file = path );
622
- }
623
- free (path );
624
- }
662
+ static ctpath_t app_data [2 ] = { L"$APPDATA" , L"RHash\\rhashrc" };
663
+ static ctpath_t home_conf [3 ] = { L"$HOMEDRIVE" , L"$HOMEPATH" , L"rhashrc" };
625
664
626
- /* check for ${PROGRAM_DIR}\rhashrc */
627
- if (program_dir && program_dir [0 ] && (dir1 = convert_wcs_to_str (program_dir , ConvertToPrimaryEncoding ))) {
628
- path = make_path (dir1 , CONFIG_FILENAME , 0 );
629
- free (dir1 );
630
- if (is_regular_file (path )) {
631
- rsh_vector_add_ptr (opt .mem , path );
632
- return (conf_opt .config_file = path );
633
- }
634
- free (path );
665
+ if (try_config (app_data , COUNTOF (app_data )) || try_config (home_conf , COUNTOF (home_conf ))) {
666
+ return 1 ;
667
+ } else {
668
+ tpath_t prog_dir [2 ];
669
+ prog_dir [0 ] = get_program_dir ();
670
+ prog_dir [1 ] = L"rhashrc" ;
671
+ return try_config ((ctpath_t * )prog_dir , COUNTOF (prog_dir ));
635
672
}
636
- #endif /* _WIN32 */
637
673
638
- return ( conf_opt . config_file = NULL ); /* config file not found */
674
+ #endif /* _WIN32 */
639
675
}
640
676
641
677
/**
@@ -647,20 +683,19 @@ static int read_config(void)
647
683
{
648
684
#define LINE_BUF_SIZE 2048
649
685
char buf [LINE_BUF_SIZE ];
650
- file_t file ;
651
686
FILE * fd ;
652
687
parsed_option_t option ;
653
688
int res ;
654
689
655
- /* initialize conf_opt and opt structures */
690
+ /* initialize conf_opt */
656
691
memset (& conf_opt , 0 , sizeof (opt ));
657
692
conf_opt .find_max_depth = -1 ;
658
693
659
694
if (!find_conf_file ()) return 0 ;
695
+ assert (!!rhash_data .config_file .real_path );
696
+ assert (FILE_ISREG (& rhash_data .config_file ));
660
697
661
- file_init_by_print_path (& file , 0 , conf_opt .config_file , 0 );
662
- fd = file_fopen (& file , FOpenRead );
663
- file_cleanup (& file );
698
+ fd = file_fopen (& rhash_data .config_file , FOpenRead );
664
699
if (!fd ) return -1 ;
665
700
666
701
while (fgets (buf , LINE_BUF_SIZE , fd )) {
@@ -675,7 +710,7 @@ static int read_config(void)
675
710
/* search for '=' */
676
711
index = strcspn (line , "=" );
677
712
if (line [index ] == 0 ) {
678
- log_warning (_ ("%s: can't parse line \"%s\"\n" ), conf_opt .config_file , line );
713
+ log_warning (_ ("%s: can't parse line \"%s\"\n" ), file_get_print_path ( & rhash_data .config_file , FPathUtf8 | FPathNotNull ) , line );
679
714
continue ;
680
715
}
681
716
line [index ] = 0 ;
@@ -688,7 +723,7 @@ static int read_config(void)
688
723
}
689
724
690
725
if (!t -> type ) {
691
- log_warning (_ ("%s: unknown option \"%s\"\n" ), conf_opt .config_file , line );
726
+ log_warning (_ ("%s: unknown option \"%s\"\n" ), file_get_print_path ( & rhash_data .config_file , FPathUtf8 | FPathNotNull ) , line );
692
727
continue ;
693
728
}
694
729
@@ -713,7 +748,8 @@ static int read_config(void)
713
748
res = fclose (fd );
714
749
715
750
#ifdef _WIN32
716
- if ( (opt .flags & OPT_ENCODING ) == 0 ) opt .flags |= (conf_opt .flags & OPT_ENCODING );
751
+ if ( (opt .flags & OPT_ENCODING ) == 0 )
752
+ opt .flags |= (conf_opt .flags & OPT_ENCODING );
717
753
#endif
718
754
return (res == 0 ? 0 : -1 );
719
755
}
@@ -1078,9 +1114,9 @@ static void make_final_options_checks(void)
1078
1114
{
1079
1115
unsigned ext_format_bits = (opt .printf_str ? 0x100 : 0 ) | (opt .template_file ? 0x200 : 0 );
1080
1116
1081
- if ((opt .flags & OPT_VERBOSE ) && conf_opt .config_file ) {
1117
+ if ((opt .flags & OPT_VERBOSE ) && !! rhash_data .config_file . real_path ) {
1082
1118
/* note that the first log_msg call shall be made after setup_output() */
1083
- log_msg (_ ("Config file: %s\n" ), conf_opt .config_file );
1119
+ log_msg_file_t (_ ("Config file: %s\n" ), & rhash_data .config_file );
1084
1120
}
1085
1121
1086
1122
if (opt .bt_batch_file )
0 commit comments