@@ -394,7 +394,6 @@ enum option_type_t
394394 F_TSTR = 3 | F_NEED_PARAM , /* store parameter as a tstr_t */
395395 F_TOUT = 4 | F_NEED_PARAM | F_OUTPUT_OPT ,
396396 F_VFNC = 5 , /* just call a function */
397- F_PFNC = 6 | F_NEED_PARAM , /* process option parameter by calling a handler */
398397 F_TFNC = 7 | F_NEED_PARAM , /* process option parameter by calling a handler */
399398 F_UFNC = 8 | F_NEED_PARAM , /* pass UTF-8 encoded parameter to the handler */
400399 F_PRNT = 9 , /* print a constant C-string and exit */
@@ -483,18 +482,18 @@ cmdline_opt_t cmdline_opt[] =
483482 { F_UFLG , 0 , 0 , "speed" , 0 , & opt .flags , OPT_SPEED },
484483 { F_UFLG , 'e' , 0 , "embed-crc" , 0 , & opt .flags , OPT_EMBED_CRC },
485484 { F_CSTR , 0 , 0 , "embed-crc-delimiter" , 0 , & opt .embed_crc_delimiter , 0 },
486- { F_PFNC , 0 , 0 , "path-separator" , (opt_handler_t )set_path_separator , 0 , 0 },
485+ { F_UFNC , 0 , 0 , "path-separator" , (opt_handler_t )set_path_separator , 0 , 0 },
487486 { F_TOUT , 'o' , 0 , "output" , 0 , & opt .output , 0 },
488487 { F_TOUT , 'l' , 0 , "log" , 0 , & opt .log , 0 },
489- { F_PFNC , 'q' , 0 , "accept" , (opt_handler_t )add_file_suffix , 0 , MASK_ACCEPT },
490- { F_PFNC , 't' , 0 , "crc-accept" , (opt_handler_t )add_file_suffix , 0 , MASK_CRC_ACCEPT },
491- { F_PFNC , 0 , 0 , "exclude" , (opt_handler_t )add_file_suffix , 0 , MASK_EXCLUDE },
488+ { F_UFNC , 'q' , 0 , "accept" , (opt_handler_t )add_file_suffix , 0 , MASK_ACCEPT },
489+ { F_UFNC , 't' , 0 , "crc-accept" , (opt_handler_t )add_file_suffix , 0 , MASK_CRC_ACCEPT },
490+ { F_UFNC , 0 , 0 , "exclude" , (opt_handler_t )add_file_suffix , 0 , MASK_EXCLUDE },
492491 { F_VFNC , 0 , 0 , "video" , (opt_handler_t )accept_video , 0 , 0 },
493492 { F_VFNC , 0 , 0 , "nya" , (opt_handler_t )nya , 0 , 0 },
494- { F_PFNC , 0 , 0 , "max-depth" , (opt_handler_t )set_max_depth , 0 , 0 },
493+ { F_UFNC , 0 , 0 , "max-depth" , (opt_handler_t )set_max_depth , 0 , 0 },
495494 { F_UFLG , 0 , 0 , "bt-private" , 0 , & opt .flags , OPT_BT_PRIVATE },
496495 { F_UFLG , 0 , 0 , "bt-transmission" , 0 , & opt .flags , OPT_BT_TRANSMISSION },
497- { F_PFNC , 0 , 0 , "bt-piece-length" , (opt_handler_t )set_bt_piece_length , 0 , 0 },
496+ { F_UFNC , 0 , 0 , "bt-piece-length" , (opt_handler_t )set_bt_piece_length , 0 , 0 },
498497 { F_UFNC , 0 , 0 , "bt-announce" , (opt_handler_t )bt_announce , 0 , 0 },
499498 { F_TSTR , 0 , 0 , "bt-batch" , 0 , & opt .bt_batch_file , 0 },
500499 { F_UFLG , 0 , 0 , "benchmark-raw" , 0 , & opt .flags , OPT_BENCH_RAW },
@@ -503,10 +502,10 @@ cmdline_opt_t cmdline_opt[] =
503502 { F_UFLG , 0 , 0 , "hex" , 0 , & opt .flags , OPT_HEX },
504503 { F_UFLG , 0 , 0 , "base32" , 0 , & opt .flags , OPT_BASE32 },
505504 { F_UFLG , 'b' , 0 , "base64" , 0 , & opt .flags , OPT_BASE64 },
506- { F_PFNC , 0 , 0 , "openssl" , (opt_handler_t )openssl_flags , 0 , 0 },
505+ { F_UFNC , 0 , 0 , "openssl" , (opt_handler_t )openssl_flags , 0 , 0 },
507506
508507 /* for compatibility */
509- { F_PFNC , 0 , 0 , "maxdepth" , (opt_handler_t )set_max_depth , 0 , 0 },
508+ { F_UFNC , 0 , 0 , "maxdepth" , (opt_handler_t )set_max_depth , 0 , 0 },
510509
511510#ifdef _WIN32 /* code pages (windows only) */
512511 { F_UENC , 0 , 0 , "utf8" , 0 , & opt .flags , OPT_UTF8 },
@@ -553,25 +552,35 @@ static void apply_option(options_t* opts, parsed_option_t* option)
553552
554553 /* check if option requires a parameter */
555554 if (is_param_required (option_type )) {
556- if (!option -> parameter ) {
555+ #ifdef _WIN32
556+ int from_config = (opts == & conf_opt );
557+ #endif
558+ rsh_tchar * tparam = (rsh_tchar * )option -> parameter ;
559+ if (!tparam ) {
557560 die (_ ("argument is required for option %s\n" ), option -> name );
558561 }
559562
560563#ifdef _WIN32
564+ if (from_config ) {
565+ /* treat config lines as UTF-8 encoded and convert it to UTF-16 */
566+ tparam = convert_str_to_wcs ((char * )option -> parameter , ConvertToUtf8 );
567+ }
561568 if (option_type == F_TOUT || option_type == F_TFNC || option_type == F_TSTR ) {
562569 /* leave the value in UTF-16 */
563- value = (char * )rsh_wcsdup (( wchar_t * ) option -> parameter );
570+ value = (char * )rsh_wcsdup (tparam );
564571 }
565572 else if (option_type == F_UFNC ) {
566573 /* convert from UTF-16 to UTF-8 */
567- value = convert_wcs_to_str (( wchar_t * ) option -> parameter , ConvertToUtf8 | ConvertExact );
574+ value = convert_wcs_to_str (tparam , ConvertToUtf8 | ConvertExact );
568575 } else {
569576 /* convert from UTF-16 */
570- value = convert_wcs_to_str (( wchar_t * ) option -> parameter , ConvertToPrimaryEncoding );
577+ value = convert_wcs_to_str (tparam , ConvertToPrimaryEncoding );
571578 }
572579 rsh_vector_add_ptr (opt .mem , value );
580+ if (from_config )
581+ free (tparam );
573582#else
574- value = ( char * ) option -> parameter ;
583+ value = tparam ;
575584#endif
576585 }
577586
@@ -587,7 +596,6 @@ static void apply_option(options_t* opts, parsed_option_t* option)
587596 /* save the option parameter */
588597 * (char * * )((char * )opts + ((char * )o -> ptr - (char * )& opt )) = value ;
589598 break ;
590- case F_PFNC :
591599 case F_TFNC :
592600 case F_UFNC :
593601 /* call option parameter handler */
@@ -741,7 +749,7 @@ static int read_config(void)
741749 int res ;
742750
743751 /* initialize conf_opt */
744- memset (& conf_opt , 0 , sizeof (opt ));
752+ memset (& conf_opt , 0 , sizeof (conf_opt ));
745753 conf_opt .find_max_depth = -1 ;
746754
747755 if (!find_conf_file ()) return 0 ;
@@ -750,14 +758,19 @@ static int read_config(void)
750758
751759 fd = file_fopen (& rhash_data .config_file , FOpenRead );
752760 if (!fd ) return -1 ;
761+ memset (& option , 0 , sizeof (option ));
753762
754763 while (fgets (buf , LINE_BUF_SIZE , fd )) {
755764 size_t index ;
756765 cmdline_opt_t * t ;
757- char * line = str_trim ( buf ) ;
766+ char * line = buf ;
758767 char * name ;
759768 char * value ;
760769
770+ if (STARTS_WITH_UTF8_BOM (line ))
771+ line += 3 ;
772+ line = str_trim (line );
773+
761774 line_number ++ ;
762775 if (* line == 0 || IS_COMMENT (* line ))
763776 continue ;
0 commit comments