1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +00:00

fmt: style modifications suggested by Arcterus

This commit is contained in:
kwantam 2014-06-18 22:23:48 -04:00
parent 6228bb4b85
commit 5d2a2b6a0b
2 changed files with 194 additions and 175 deletions

View file

@ -49,7 +49,7 @@ struct FmtOptions {
prefix_len : uint,
use_anti_prefix : bool,
anti_prefix : String,
xanti_prefix: bool,
xanti_prefix : bool,
uniform : bool,
width : uint,
goal : uint,
@ -97,21 +97,22 @@ fn uumain(args: Vec<String>) -> int {
return 0
}
let mut fmt_opts = FmtOptions { crown : false
, tagged : false
, mail : false
, uniform : false
, split_only : false
, use_prefix : false
, prefix : String::new()
, xprefix : false
, prefix_len : 0
, use_anti_prefix : false
, anti_prefix : String::new()
, xanti_prefix: false
, width : 78
, goal : 72
, tabwidth : 8
let mut fmt_opts = FmtOptions {
crown : false,
tagged : false,
mail : false,
uniform : false,
split_only : false,
use_prefix : false,
prefix : String::new(),
xprefix : false,
prefix_len : 0,
use_anti_prefix : false,
anti_prefix : String::new(),
xanti_prefix : false,
width : 78,
goal : 72,
tabwidth : 8,
};
if matches.opt_present("t") { fmt_opts.tagged = true; }
@ -123,44 +124,58 @@ fn uumain(args: Vec<String>) -> int {
if matches.opt_present("X") { fmt_opts.xanti_prefix = true; }
match matches.opt_str("p") {
Some(s) => { fmt_opts.prefix = s; fmt_opts.use_prefix = true; fmt_opts.prefix_len = fmt_opts.prefix.as_slice().char_len() },
Some(s) => {
fmt_opts.prefix = s;
fmt_opts.use_prefix = true;
fmt_opts.prefix_len = fmt_opts.prefix.as_slice().char_len()
}
None => ()
};
match matches.opt_str("P") {
Some(s) => { fmt_opts.anti_prefix = s; fmt_opts.use_anti_prefix = true; },
Some(s) => {
fmt_opts.anti_prefix = s;
fmt_opts.use_anti_prefix = true;
}
None => ()
};
match matches.opt_str("w") {
Some(s) => { fmt_opts.width = match from_str(s.as_slice()) {
Some(s) => {
fmt_opts.width =
match from_str(s.as_slice()) {
Some(t) => t,
None => { crash!(1, "Invalid WIDTH specification: `{}'", s); }
};
fmt_opts.goal = std::cmp::min(fmt_opts.width * 92 / 100, fmt_opts.width - 4);
},
}
None => ()
};
match matches.opt_str("g") {
Some(s) => { fmt_opts.goal = match from_str(s.as_slice()) {
Some(s) => {
fmt_opts.goal =
match from_str(s.as_slice()) {
Some(t) => t,
None => { crash!(1, "Invalid GOAL specification: `{}'", s); }
};
if ! matches.opt_present("w") {
if !matches.opt_present("w") {
fmt_opts.width = std::cmp::max(fmt_opts.goal * 100 / 92, fmt_opts.goal + 4);
} else if fmt_opts.goal > fmt_opts.width {
crash!(1, "GOAL cannot be greater than WIDTH.");
}
},
}
None => ()
};
match matches.opt_str("T") {
Some(s) => fmt_opts.tabwidth = match from_str(s.as_slice()) {
Some(s) => {
fmt_opts.tabwidth =
match from_str(s.as_slice()) {
Some(t) => t,
None => { crash!(1, "Invalid TABWIDTH specification: `{}'", s); }
},
};
}
None => ()
};
@ -179,8 +194,10 @@ fn uumain(args: Vec<String>) -> int {
let mut ostream = box BufferedWriter::new(stdout_raw()) as Box<Writer>;
for i in files.iter().map(|x| x.as_slice()) {
let mut fp = match open_file(i) {
Err(e) => { show_warning!("{}: {}",i,e);
let mut fp =
match open_file(i) {
Err(e) => {
show_warning!("{}: {}",i,e);
continue;
}
Ok(f) => f
@ -204,7 +221,7 @@ fn uumain(args: Vec<String>) -> int {
// handle "init" portion
silent_unwrap!(ostream.write(para.init_str.as_bytes()));
para.init_len
} else if ! para.mail_header {
} else if !para.mail_header {
// for non-(crown, tagged) that's the same as a normal indent
silent_unwrap!(ostream.write(pIndent.as_bytes()));
pIndentLen

View file

@ -65,14 +65,14 @@ impl<'a> FileLines<'a> {
// returns true if this line should be formatted
fn match_prefix(&self, line: &str) -> (bool, uint) {
if ! self.opts.use_prefix { return (true, 0u); }
if !self.opts.use_prefix { return (true, 0u); }
FileLines::match_prefix_generic(self.opts.prefix.as_slice(), line, self.opts.xprefix)
}
// returns true if this line should be formatted
fn match_anti_prefix(&self, line: &str) -> bool {
if ! self.opts.use_anti_prefix { return true; }
if !self.opts.use_anti_prefix { return true; }
match FileLines::match_prefix_generic(self.opts.anti_prefix.as_slice(), line, self.opts.xanti_prefix) {
(true, _) => false,
@ -85,7 +85,7 @@ impl<'a> FileLines<'a> {
return (true, 0);
}
if ! exact {
if !exact {
// we do it this way rather than byte indexing to support unicode whitespace chars
let mut i = 0u;
while (i < line.len()) && line.char_at(i).is_whitespace() {
@ -98,6 +98,10 @@ impl<'a> FileLines<'a> {
(false, 0)
}
fn displayed_length(&self, s: &str) -> uint {
s.char_len() + (self.opts.tabwidth - 1) * s.chars().filter(|x| x == &'\t').count()
}
}
impl<'a> Iterator<Line> for FileLines<'a> {
@ -122,13 +126,13 @@ impl<'a> Iterator<Line> for FileLines<'a> {
// if this line does not match the prefix,
// emit the line unprocessed and iterate again
let (pmatch, poffset) = self.match_prefix(n.as_slice());
if ! pmatch {
if !pmatch {
return Some(NoFormatLine(n, false));
}
// if this line matches the anti_prefix
// (NOTE definition of match_anti_prefix is TRUE if we should process)
if ! self.match_anti_prefix(n.as_slice()) {
if !self.match_anti_prefix(n.as_slice()) {
return Some(NoFormatLine(n, false));
}
@ -154,19 +158,16 @@ impl<'a> Iterator<Line> for FileLines<'a> {
let pfxEnd = poffset + self.opts.prefix.len();
let nSlice = n.as_slice().slice_from(pfxEnd);
let nSlice2 = nSlice.trim_left();
(pfxEnd + nSlice.len() - nSlice2.len(), pfxEnd, poffset)
} else {
let nSlice = n.as_slice().trim_left();
(nLen - nSlice.len(), 0, 0)
};
// indent length
let indLen =
if indEnd > 0 {
let nSlice = n.as_slice().slice(pfxEnd, indEnd);
nSlice.char_len() + (self.opts.tabwidth - 1) * nSlice.chars().filter(|x| x == &'\t').count()
self.displayed_length(n.as_slice().slice(pfxEnd, indEnd))
} else {
0
};
@ -174,8 +175,7 @@ impl<'a> Iterator<Line> for FileLines<'a> {
// prefix indent length
let pfxIndLen =
if pfxIndEnd > 0 {
let nSlice = n.as_slice().slice_to(pfxIndEnd);
nSlice.char_len() + (self.opts.tabwidth - 1) * nSlice.chars().filter(|x| x == &'\t').count()
self.displayed_length(n.as_slice().slice_to(pfxIndEnd))
} else {
0
};
@ -185,7 +185,7 @@ impl<'a> Iterator<Line> for FileLines<'a> {
// [?!.]\t\t is. We could expand tabs to two spaces to force detection of tab as
// sentence ending
if self.opts.uniform {
let tabinds: Vec<uint> = n.as_slice().slice_from(indEnd).char_indices().filter_map(|(i,c)| if c == '\t' { Some(i) } else { None }).collect();
let tabinds: Vec<uint> = n.as_slice().slice_from(indEnd).char_indices().filter_map(|(i, c)| if c == '\t' { Some(i) } else { None }).collect();
unsafe {
let nmut = n.as_mut_bytes();
for i in tabinds.iter() {
@ -194,12 +194,13 @@ impl<'a> Iterator<Line> for FileLines<'a> {
}
}
Some(FormatLine(FileLine { line: n
, indent_end: indEnd
, prefix_end: pfxEnd
, pfxind_end: pfxIndEnd
, indent_len: indLen
, pfxind_len: pfxIndLen
Some(FormatLine(FileLine {
line : n,
indent_end : indEnd,
prefix_end : pfxEnd,
pfxind_end : pfxIndEnd,
indent_len : indLen,
pfxind_len : pfxIndLen,
}))
}
}
@ -245,11 +246,11 @@ impl<'a> ParagraphStream<'a> {
// or with a sequence of printable ASCII chars (33 to 126, inclusive,
// except colon) followed by a colon.
if line.indent_end > 0 {
return false;
false
} else {
let lSlice = line.line.as_slice();
if lSlice.starts_with("From ") {
return true;
true
} else {
let colonPosn =
match lSlice.find(':') {
@ -260,8 +261,7 @@ impl<'a> ParagraphStream<'a> {
// header field must be nonzero length
if colonPosn == 0 { return false; }
return lSlice.slice_to(colonPosn).chars()
.all(|x| match x as uint {
return lSlice.slice_to(colonPosn).chars().all(|x| match x as uint {
y if y < 33 || y > 126 => false,
_ => true
});
@ -335,7 +335,7 @@ impl<'a> Iterator<Result<Paragraph,String>> for ParagraphStream<'a> {
// these will be overwritten in the 2nd line of crown or tagged mode, but
// we are not guaranteed to get to the 2nd line, e.g., if the next line
// is a NoFormatLine or None. Thus, we set sane defaults the 1st time around
indent_str.push_str(fl.line.as_slice().slice(fl.prefix_end,fl.indent_end));
indent_str.push_str(fl.line.as_slice().slice(fl.prefix_end, fl.indent_end));
indent_len = fl.indent_len;
indent_end = fl.indent_end;
@ -356,10 +356,10 @@ impl<'a> Iterator<Result<Paragraph,String>> for ParagraphStream<'a> {
}
} else if in_mail {
// lines following mail headers must begin with spaces
if (self.opts.use_prefix && fl.pfxind_end == 0) || (! self.opts.use_prefix && fl.indent_end == 0) {
if (self.opts.use_prefix && fl.pfxind_end == 0) || (!self.opts.use_prefix && fl.indent_end == 0) {
break; // this line does not begin with spaces
}
} else if ! second_done && (self.opts.crown || self.opts.tagged) {
} else if !second_done && (self.opts.crown || self.opts.tagged) {
// now we have enough info to handle crown margin and tagged mode
if pfxind_len != fl.pfxind_len {
// in both crown and tagged modes we require that pfxind is the same
@ -370,7 +370,7 @@ impl<'a> Iterator<Result<Paragraph,String>> for ParagraphStream<'a> {
} else {
// this is part of the same paragraph, get the indent info from this line
indent_str.clear();
indent_str.push_str(fl.line.as_slice().slice(fl.prefix_end,fl.indent_end));
indent_str.push_str(fl.line.as_slice().slice(fl.prefix_end, fl.indent_end));
indent_len = fl.indent_len;
indent_end = fl.indent_end;
}
@ -396,16 +396,17 @@ impl<'a> Iterator<Result<Paragraph,String>> for ParagraphStream<'a> {
// NoFormatLine.
self.next_mail = in_mail;
Some(Ok(Paragraph { lines: pLines
, init_str: init_str
, init_len: init_len
, init_end: init_end
, indent_str: indent_str
, indent_len: indent_len
, indent_end: indent_end
, pfxind_str: pfxind_str
, pfxind_len: pfxind_len
, mail_header: in_mail
Some(Ok(Paragraph {
lines : pLines,
init_str : init_str,
init_len : init_len,
init_end : init_end,
indent_str : indent_str,
indent_len : indent_len,
indent_end : indent_end,
pfxind_str : pfxind_str,
pfxind_len : pfxind_len,
mail_header : in_mail
}))
}
}
@ -500,7 +501,7 @@ impl<'a> Iterator<&'a str> for WordSplit<'a> {
// note that this preserves the invariant that self.position points to
// non-whitespace character OR end of string
self.position =
match self.string.slice_from(ws_start).find(|x: char| ! x.is_whitespace()) {
match self.string.slice_from(ws_start).find(|x: char| !x.is_whitespace()) {
None => self.length,
Some(s) => s + ws_start
};
@ -525,6 +526,7 @@ impl<'a> Iterator<&'a str> for WordSplit<'a> {
// eventually we will want to annotate where the sentence boundaries are
// so that we can give preference to splitting lines appropriately
self.string.slice(old_position, self.position)
})
}
)
}
}