From 4b756e3e53bee48de6f235a253e13e9f30bcf9dd Mon Sep 17 00:00:00 2001 From: Carlos Fernandez Date: Sat, 17 Oct 2026 15:52:00 -0700 Subject: [PATCH] Accept the remaining v0.94 option spellings The C parser in v0.94 accepted short and underscore spellings such as -nofc, -bi, -gt, -haup, -ocr_mode and --gui_mode_reports. The Rust parser rejects 46 of them with "Unknown Argument", so old scripts and frontends stop working. #2368 covered nine; this covers the rest that still have an equivalent option. Each spelling becomes a hidden clap alias on the option with the same behaviour, so --help is unchanged and option values are still skipped by normalize_legacy_args. -ntm/--no-timestamp-map get a hidden no-op flag: v0.94 wrote the X-TIMESTAMP-MAP header by default and this turned it off, but the header is now off unless --timestamp-map is given. The sharing and translation options (-enable-sharing, -sharing-url, -sharing-debug, -translate, -translate-auth) stay rejected because that feature no longer exists. -curlposturl already works in builds with libcurl, as in v0.94. --- src/rust/src/args.rs | 83 ++++++++++++++++--------------- src/rust/src/lib.rs | 114 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+), 39 deletions(-) diff --git a/src/rust/src/args.rs b/src/rust/src/args.rs index 7476ba532..e20eb3e22 100644 --- a/src/rust/src/args.rs +++ b/src/rust/src/args.rs @@ -170,7 +170,7 @@ pub struct Args { pub outinterval: Option, /// When segmenting files, do it only after a I frame /// trying to behave like FFmpeg - #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_FILE_SEGMENTATION)] + #[arg(long, alias="key", verbatim_doc_comment, help_heading=OUTPUT_FILE_SEGMENTATION)] pub segmentonkeyonly: bool, /// Read the input via UDP (listening in the specified port) /// instead of reading a file. @@ -196,11 +196,11 @@ pub struct Args { pub tcp: Option, /// Sets server password for new connections to /// tcp server - #[arg(long, value_name="port", verbatim_doc_comment, help_heading=NETWORK_SUPPORT)] + #[arg(long, alias="tcppassword", value_name="port", verbatim_doc_comment, help_heading=NETWORK_SUPPORT)] pub tcp_password: Option, /// Sends to the server short description about /// captions e.g. channel name or file name - #[arg(long, value_name="port", verbatim_doc_comment, help_heading=NETWORK_SUPPORT)] + #[arg(long, alias="tcpdesc", value_name="port", verbatim_doc_comment, help_heading=NETWORK_SUPPORT)] pub tcp_description: Option, /// Values: 1 = Output Field 1 /// 2 = Output Field 2 @@ -270,9 +270,9 @@ pub struct Args { pub dvdraw: bool, #[arg(long, hide = true)] pub mcc: bool, - #[arg(long, hide = true)] + #[arg(long, alias = "transcript", hide = true)] pub txt: bool, - #[arg(long, hide = true)] + #[arg(long, alias = "timedtranscript", hide = true)] pub ttxt: bool, #[arg(long, hide = true)] pub null: bool, @@ -280,16 +280,16 @@ pub struct Args { /// to Program or Transport Streams with MPEG2 data and /// overrides the default PTS timing. /// GOP timing is always used for Elementary Streams. - #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] + #[arg(long, alias="gt", verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] pub goptime: bool, /// Never use GOP timing (use PTS), even if ccextractor /// detects GOP timing is the reasonable choice. - #[arg(long, verbatim_doc_comment, conflicts_with="goptime", help_heading=OPTIONS_AFFECTING_INPUT_FILES)] + #[arg(long, aliases=["nogt", "nogoptime"], verbatim_doc_comment, conflicts_with="goptime", help_heading=OPTIONS_AFFECTING_INPUT_FILES)] pub no_goptime: bool, /// Fix padding - some cards (or providers, or whatever) /// seem to send 0000 as CC padding instead of 8080. If you /// get bad timing, this might solve it. - #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] + #[arg(long, alias="fp", verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] pub fixpadding: bool, /// Use 90090 (instead of 90000) as MPEG clock frequency. /// (reported to be needed at least by Panasonic DMR-ES15 @@ -314,7 +314,7 @@ pub struct Args { /// are processing video that was split with a editing /// tool, use --videoedited so ccextractor doesn't try to rebuild /// the original timing. - #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] + #[arg(long, alias="ve", verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] pub videoedited: bool, /// Consider the file as a continuous stream that is /// growing as ccextractor processes it, so don't try @@ -333,7 +333,7 @@ pub struct Args { /// to order the CC information. The default way is to /// use the PTS information. Use this switch only when /// needed. - #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] + #[arg(long, alias="poc", verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] pub usepicorder: bool, /// Force MythTV code branch. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] @@ -362,7 +362,7 @@ pub struct Args { /// program in the input, it will list the programs found /// and terminate without doing anything, unless /// --autoprogram (see below) is used. - #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] + #[arg(long, alias="pn", verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] pub program_number: Option, /// If there's more than one program in the stream, just use /// the first one we find that contains a suitable stream. @@ -394,7 +394,7 @@ pub struct Args { /// If the video was recorder using a Hauppauge card, it /// might need special processing. This parameter will /// force the special treatment. - #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] + #[arg(long, alias="haup", verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] pub hauppauge: bool, /// In MP4 files the closed caption data can be embedded in /// the video track or in a dedicated CC track. If a @@ -426,13 +426,18 @@ pub struct Args { pub deblev: bool, /// Analyze the video stream even if it's not used for /// subtitles. This allows to provide video information. - #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] + #[arg(long, alias="anvid", verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] pub analyzevideo: bool, /// Enable the X-TIMESTAMP-MAP header for WebVTT (HLS) #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] pub timestamp_map: bool, + /// Legacy spelling kept for old scripts. The header used to be on by + /// default and this turned it off; it is now off unless --timestamp-map + /// is given, so this flag has nothing left to do. + #[arg(long, alias = "ntm", hide = true, conflicts_with = "timestamp_map")] + pub no_timestamp_map: bool, /// Don't attempt to correct typos with Levenshtein distance. - #[arg(long, verbatim_doc_comment, help_heading=LEVENSHTEIN_DISTANCE)] + #[arg(long, alias="nolevdist", verbatim_doc_comment, help_heading=LEVENSHTEIN_DISTANCE)] pub no_levdist: bool, /// Minimum distance we always allow regardless /// of the length of the strings.Default 2. @@ -479,13 +484,13 @@ pub struct Args { #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] pub latin1: bool, /// For .srt/.sami/.vtt, don't add font color tags. - #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] + #[arg(long, aliases=["nofc", "nofontcolor"], verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] pub no_fontcolor: bool, /// For .srt/.sami/.vtt, don't covert html unsafe character - #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] + #[arg(long, alias="nohtmlescape", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] pub no_htmlescape: bool, /// For .srt/.sami/.vtt, don't add typesetting tags. - #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] + #[arg(long, aliases=["nots", "notypesetting"], verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] pub no_typesetting: bool, /// Trim lines. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] @@ -495,7 +500,7 @@ pub struct Args { /// files to have a font tag, which makes the files /// larger. Add the color you want in RGB, such as /// --defaultcolor #FF0000 for red. - #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] + #[arg(long, alias="dc", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] pub defaultcolor: Option, /// Sentence capitalization. Use if you hate /// ALL CAPS in subtitles. @@ -512,7 +517,7 @@ pub struct Args { /// exactly as they appear in the file. /// Use one line per word. Lines starting with # are /// considered comments and discarded. - #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] + #[arg(long, alias="caf", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] pub capfile: Option, /// Censors profane words from subtitles. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] @@ -525,7 +530,7 @@ pub struct Args { /// Split output text so each frame contains a complete /// sentence. Timings are adjusted based on number of /// characters - #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] + #[arg(long, alias="sbs", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] pub splitbysentence: bool, /// For timed transcripts that have an absolute date /// instead of a timestamp relative to the file start), use @@ -668,7 +673,7 @@ pub struct Args { pub mkvlang: Option, /// When processing DVB don't use the OCR to write the text as /// comments in the XML file. - #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] + #[arg(long, alias="nospupngocr", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] pub no_spupngocr: bool, /// Specify the full path of the font that is to be used when /// generating SPUPNG files. If not specified, you need to @@ -685,14 +690,14 @@ pub struct Args { #[arg(long, verbatim_doc_comment, value_name="path", help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] pub italics: Option, /// Forces input buffering. - #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_BUFFERING)] + #[arg(long, alias="bi", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_BUFFERING)] pub bufferinput: bool, /// Disables input buffering. - #[arg(long, verbatim_doc_comment, conflicts_with="bufferinput", help_heading=OUTPUT_AFFECTING_BUFFERING)] + #[arg(long, aliases=["nobi", "nobufferinput"], verbatim_doc_comment, conflicts_with="bufferinput", help_heading=OUTPUT_AFFECTING_BUFFERING)] pub no_bufferinput: bool, /// Specify a size for reading, in bytes (suffix with K or /// or M for kilobytes and megabytes). Default is 16M. - #[arg(long, verbatim_doc_comment, value_name="val", help_heading=OUTPUT_AFFECTING_BUFFERING)] + #[arg(long, alias="bs", verbatim_doc_comment, value_name="val", help_heading=OUTPUT_AFFECTING_BUFFERING)] pub buffersize: Option, /// keep-output-close. If used then CCExtractor will close /// the output file after writing each subtitle frame and @@ -700,7 +705,7 @@ pub struct Args { #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_BUFFERING)] pub koc: bool, /// Flush the file buffer whenever content is written. - #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_BUFFERING)] + #[arg(long, alias="ff", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_BUFFERING)] pub forceflush: bool, /// Direct Roll-Up. When in roll-up mode, write character by /// character instead of line by line. Note that this @@ -710,7 +715,7 @@ pub struct Args { /// If you hate the repeated lines caused by the roll-up /// emulation, you can have ccextractor write only one /// line at a time, getting rid of these repeated lines. - #[arg(long, alias="noru", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_BUFFERING)] + #[arg(long, aliases=["noru", "norollup"], verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_BUFFERING)] pub no_rollup: bool, /// roll-up captions can consist of 2, 3 or 4 visible /// lines at any time (the number of lines is part of @@ -749,7 +754,7 @@ pub struct Args { #[arg(long, verbatim_doc_comment, value_name="time", help_heading=OUTPUT_AFFECTING_SEGMENT)] pub endat: Option, /// Write 'num' screenfuls and terminate processing. - #[arg(long, verbatim_doc_comment, value_name="num", help_heading=OUTPUT_AFFECTING_SEGMENT)] + #[arg(long, alias="scr", verbatim_doc_comment, value_name="num", help_heading=OUTPUT_AFFECTING_SEGMENT)] pub screenfuls: Option, /// --codec dvbsub /// select the dvb subtitle from all elementary stream, @@ -763,7 +768,7 @@ pub struct Args { /// ignore dvb subtitle and follow default behaviour /// --no-codec teletext /// ignore teletext subtitle - #[arg(long, verbatim_doc_comment, conflicts_with="codec", value_name="value", help_heading=OUTPUT_AFFECTING_CODEC)] + #[arg(long, alias="nocodec", verbatim_doc_comment, conflicts_with="codec", value_name="value", help_heading=OUTPUT_AFFECTING_CODEC)] pub no_codec: Option, /// Write this text as start credits. If there are /// several lines, separate them with the @@ -827,7 +832,7 @@ pub struct Args { pub cbraw: bool, /// Disable the syncing code. Only useful for debugging /// purposes. - #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] + #[arg(long, alias="nosync", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] pub no_sync: bool, /// Disable the removal of trailing padding blocks /// when exporting to bin format. Only useful for @@ -849,7 +854,7 @@ pub struct Args { pub dumpdef: bool, /// If no CC packets are detected based on the PMT, try /// to find data in all packets by scanning. - #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] + #[arg(long, alias="investigate_packets", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] pub investigate_packets: bool, /// Use this page for subtitles (if this parameter /// is not used, try to autodetect). In Spain the @@ -904,10 +909,10 @@ pub struct Args { /// in a easy to parse format. This is intended to be /// used by other programs. See docs directory for. /// details. - #[arg(long, verbatim_doc_comment, help_heading=COMMUNICATION_PROTOCOL)] + #[arg(long, alias="gui_mode_reports", verbatim_doc_comment, help_heading=COMMUNICATION_PROTOCOL)] pub gui_mode_reports: bool, /// Suppress the output of the progress bar - #[arg(long, verbatim_doc_comment, help_heading=COMMUNICATION_PROTOCOL)] + #[arg(long, alias="no_progress_bar", verbatim_doc_comment, help_heading=COMMUNICATION_PROTOCOL)] pub no_progress_bar: bool, /// Don't write any message. #[arg(long, verbatim_doc_comment, help_heading=COMMUNICATION_PROTOCOL)] @@ -920,13 +925,13 @@ pub struct Args { pub hardsubx: bool, /// Search for burned-in ticker text at the bottom of /// the screen. - #[arg(long, verbatim_doc_comment, help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] + #[arg(long, alias="tickertape", verbatim_doc_comment, help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] pub tickertext: bool, /// Set the OCR mode to either frame-wise, word-wise /// or letter wise. /// e.g. --ocr-mode frame (default), --ocr-mode word, /// --ocr-mode letter - #[arg(long = "ocr-mode", verbatim_doc_comment, value_name="mode", help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] + #[arg(long = "ocr-mode", alias="ocr_mode", verbatim_doc_comment, value_name="mode", help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] pub ocr_mode: Option, /// Specify the color of the subtitles /// Possible values are in the set @@ -935,7 +940,7 @@ pub struct Args { /// may also be specified. /// e.g. --subcolor white or --subcolor 270 (for violet). /// Refer to an HSV color chart for values. - #[arg(long, verbatim_doc_comment, value_name="color", help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] + #[arg(long, alias="sub_color", verbatim_doc_comment, value_name="color", help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] pub subcolor: Option, /// Specify the minimum duration that a subtitle line /// must exist on the screen. @@ -944,20 +949,20 @@ pub struct Args { /// processing time. /// The recommended value is 0.5 (default). /// e.g. --min-sub-duration 1.0 (for a duration of 1 second) - #[arg(long = "min-sub-duration", verbatim_doc_comment, value_name="duration", help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] + #[arg(long = "min-sub-duration", alias="min_sub_duration", verbatim_doc_comment, value_name="duration", help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] pub min_sub_duration: Option, /// Specify whether italics are to be detected from the /// OCR text. /// Italic detection automatically enforces the OCR mode /// to be word-wise - #[arg(long = "detect-italics", verbatim_doc_comment, help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] + #[arg(long = "detect-italics", alias="detect_italics", verbatim_doc_comment, help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] pub detect_italics: bool, /// Specify the classifier confidence threshold between /// 1 and 100. /// Try and use a threshold which works for you if you get /// a lot of garbage text. /// e.g. --conf-thresh 50 - #[arg(long = "conf-thresh", verbatim_doc_comment, help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] + #[arg(long = "conf-thresh", alias="conf_thresh", verbatim_doc_comment, help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] pub conf_thresh: Option, /// For white subtitles only, specify the luminance /// threshold between 1 and 100 @@ -965,7 +970,7 @@ pub struct Args { /// values may give you better results /// Recommended values are in the range 80 to 100. /// The default value is 95 - #[arg(long = "whiteness-thresh", verbatim_doc_comment, value_name="threshold", help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] + #[arg(long = "whiteness-thresh", aliases=["whiteness_thresh", "lum_thresh"], verbatim_doc_comment, value_name="threshold", help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] pub whiteness_thresh: Option, /// This option will be used if the file should have both /// closed captions and burned in subtitles diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index 3192b6eb8..666151d4e 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -1059,6 +1059,120 @@ mod test { assert!(parse("-parsepmt").parse_pmt); } + fn parse_with_input(args: &[&str]) -> Result { + let mut args = args.to_vec(); + args.push("input.ts"); + parse_normalized(&args) + } + + #[test] + fn test_more_legacy_spellings_match_modern() { + // Each v0.94 spelling must parse to exactly the same Args as its + // modern equivalent, values included. + let cases: &[(&[&str], &[&str])] = &[ + (&["-bi"], &["--bufferinput"]), + (&["-nobi"], &["--no-bufferinput"]), + (&["--nobufferinput"], &["--no-bufferinput"]), + (&["-ff"], &["--forceflush"]), + (&["-bs", "16M"], &["--buffersize", "16M"]), + (&["-nofc"], &["--no-fontcolor"]), + (&["--nofontcolor"], &["--no-fontcolor"]), + (&["--nohtmlescape"], &["--no-htmlescape"]), + (&["-nots"], &["--no-typesetting"]), + (&["--notypesetting"], &["--no-typesetting"]), + (&["-nocodec", "teletext"], &["--no-codec", "teletext"]), + (&["-nospupngocr"], &["--no-spupngocr"]), + (&["--transcript"], &["--txt"]), + (&["--timedtranscript"], &["--ttxt"]), + (&["-ve"], &["--videoedited"]), + (&["-gt"], &["--goptime"]), + (&["-nogt"], &["--no-goptime"]), + (&["--nogoptime"], &["--no-goptime"]), + (&["-fp"], &["--fixpadding"]), + (&["--norollup"], &["--no-rollup"]), + (&["-key"], &["--segmentonkeyonly"]), + (&["--gui_mode_reports"], &["--gui-mode-reports"]), + (&["--no_progress_bar"], &["--no-progress-bar"]), + (&["-sbs"], &["--splitbysentence"]), + (&["-caf", "caps.txt"], &["--capfile", "caps.txt"]), + (&["-pn", "5"], &["--program-number", "5"]), + (&["-dc", "#FF0000"], &["--defaultcolor", "#FF0000"]), + (&["-scr", "3"], &["--screenfuls", "3"]), + (&["-nolevdist"], &["--no-levdist"]), + (&["-anvid"], &["--analyzevideo"]), + (&["-investigate_packets"], &["--investigate-packets"]), + (&["-nosync"], &["--no-sync"]), + (&["-haup"], &["--hauppauge"]), + (&["-poc"], &["--usepicorder"]), + (&["-tcppassword", "secret"], &["--tcp-password", "secret"]), + (&["-tcpdesc", "desc"], &["--tcp-description", "desc"]), + (&["-tickertape"], &["--tickertext"]), + (&["-ocr_mode", "word"], &["--ocr-mode", "word"]), + (&["-sub_color", "yellow"], &["--subcolor", "yellow"]), + ( + &["-min_sub_duration", "0.5"], + &["--min-sub-duration", "0.5"], + ), + (&["-detect_italics"], &["--detect-italics"]), + (&["-conf_thresh", "60"], &["--conf-thresh", "60"]), + (&["-whiteness_thresh", "90"], &["--whiteness-thresh", "90"]), + (&["-lum_thresh", "90"], &["--whiteness-thresh", "90"]), + ]; + + for (legacy, modern) in cases { + let legacy_args = parse_with_input(legacy) + .unwrap_or_else(|e| panic!("legacy {:?} rejected: {}", legacy, e)); + let modern_args = parse_with_input(modern) + .unwrap_or_else(|e| panic!("modern {:?} rejected: {}", modern, e)); + assert_eq!( + format!("{:?}", legacy_args), + format!("{:?}", modern_args), + "{:?} does not parse like {:?}", + legacy, + modern + ); + } + } + + #[test] + fn test_no_timestamp_map_is_accepted_and_inert() { + // The X-TIMESTAMP-MAP header is now off by default, so the old + // switch that turned it off parses but changes nothing. + for flag in ["-ntm", "--no-timestamp-map"] { + let args = parse_with_input(&[flag]) + .unwrap_or_else(|e| panic!("legacy {} rejected: {}", flag, e)); + assert!(args.no_timestamp_map); + assert!(!args.timestamp_map); + } + assert!(parse_with_input(&["-ntm", "--timestamp-map"]).is_err()); + } + + #[test] + fn test_removed_feature_spellings_still_rejected() { + // These belonged to the sharing/translation feature, which no + // longer exists; accepting them would silently do nothing. + for flag in [ + "-enable-sharing", + "-sharing-debug", + "-sharing-url", + "-translate", + "-translate-auth", + ] { + let err = parse_with_input(&[flag]).expect_err(flag); + assert_eq!(err.kind(), ErrorKind::UnknownArgument, "{}", flag); + } + } + + #[test] + fn test_legacy_spelling_kept_as_option_value() { + // A value that looks like a legacy option must not be rewritten. + let args: Vec = ["ccextractor", "--capfile", "-nofc", "input.ts"] + .iter() + .map(|a| a.to_string()) + .collect(); + assert_eq!(normalize_legacy_args(args.clone()), args); + } + #[test] fn test_normalize_legacy_option_non_options() { // Non-option arguments should remain unchanged