diff --git a/STYLE b/STYLE index 4e35af6..5322661 100644 --- a/STYLE +++ b/STYLE @@ -65,7 +65,7 @@ opening curly brace and before a closing one: 8. If a control flow statement is short enough to be easily understood in a glance, it may be placed on a single line: - if (!argc < 0) { usage(program_name); } + if !(argc < 0) { usage(program_name); } 9. In C, note everything you use from a library in a comment subsequent to its #include statement: @@ -86,21 +86,29 @@ library crates. Group alike statements: 11. Do not use do while loops in C. -12. Follow the rules from the paper The Power of 10: Rules for Developing -Safety-Critical Code [0]: +12. Adhere to the following rules from the paper The Power of 10: Rules for +Developing Safety-Critical Code [0]: 1. Avoid complex flow constructs, such as goto and recursion. 2. All loops must have fixed bounds. This prevents runaway code. 3. Avoid heap memory allocation. - 4. Restrict functions to a single printed page. - 5. Use a minimum of two runtime assertions per function. + 4. Restrict functions to the length of a single printed page. + 6. Restrict the scope of data to the smallest possible. 7. Check the return value of all non-void functions, or cast to void to - indicate the return value is useless. + indicate the return value is useless (such as in the case of using + fprintf(3p) to print to the standard error). 8. Use the preprocessor sparingly. 9. Limit pointer use to a single dereference, and do not use function pointers. 10. Compile with all possible warnings active; all warnings should then be - addressed before release of the software. + addressed before release of the software (for C compilers, compile with + -Wpedantic). + +13. Remember this quote from The Elements of Programming Style by Brian +Kernighan: + Everyone knows that debugging is twice as hard as writing a program in the + first place. So if you're as clever as you can be when you write it, how + will you ever debug it? References diff --git a/src/dj.c b/src/dj.c index c4ebf38..8dc066a 100644 --- a/src/dj.c +++ b/src/dj.c @@ -165,7 +165,6 @@ int main(int argc, char *argv[]) { size_t i; /* side of io being modified */ char noerror; /* 0=exits (default) 1=retries on partial reads or writes */ struct Io io[2 /* { in, out } */]; - program_name = (argv[0] == NULL ? program_name : argv[0]); /* Set defaults. */ align = -1; diff --git a/src/fop.rs b/src/fop.rs index 061815e..bbca85e 100644 --- a/src/fop.rs +++ b/src/fop.rs @@ -42,12 +42,12 @@ fn main() { while let Some(opt) = argv.getopt("d:") { match opt.opt() { - Ok(_) => { + Ok("d") => { /* delimiter */ d = opt.arg().unwrap(); optind = opt.ind(); }, - Err(_) => { + _ => { eprintln!("{}", usage); exit(EX_USAGE); } @@ -70,13 +70,16 @@ fn main() { }); let mut buf = String::new(); - let _ = stdin().read_to_string(&mut buf); + if let Err(e) = stdin().read_to_string(&mut buf) { + eprintln!("{}: {}", argv[0], e.strerror()); + exit(EX_IOERR); + }; /* split the buffer by the delimiter (by default, '\u{1E}') */ let mut fields = buf.split(&d).collect::>(); /* collect arguments for the operator command */ - let opts = argv + let command_args = argv .iter() .clone() .skip(command_arg + 1) /* skip the command name */ @@ -84,7 +87,7 @@ fn main() { /* spawn the command to operate on the field */ let mut spawned = Command::new(operator) - .args(opts) /* spawn with the specified arguments */ + .args(command_args) /* spawn with the specified arguments */ .stdin(Stdio::piped()) .stdout(Stdio::piped()) /* piped stdout to handle output ourselves */ .spawn() @@ -117,8 +120,13 @@ fn main() { /* get the output with which the original field will be replaced */ let mut replace = output.stdout.clone(); - /* as long as it’s not a newline, set the replacement to the output */ - if replace.pop() != Some(b'\n') { replace = output.stdout; } + /* pop trailing newline out if the input did not contain it */ + if fields[index].chars().last() != Some('\n') /* no newline */ + && replace.pop() != Some(b'\n') { /* pop last char of replacement */ + /* restore replacement to original command output if popped char was not + * a newline */ + replace = output.stdout; + } /* convert the output of the program to UTF-8 */ let new_field = String::from_utf8(replace).unwrap_or_else(|e| { diff --git a/src/intcmp.c b/src/intcmp.c index 36cc579..1ce87b3 100644 --- a/src/intcmp.c +++ b/src/intcmp.c @@ -44,22 +44,22 @@ int main(int argc, char *argv[]) { size_t i; unsigned char mode; int r; /* reference integer */ - program_name = (argv[0] == NULL ? program_name : argv[0]); - mode = 0; - if (argc == 0) { return usage(program_name); } + if (argc < 3) { + return usage(argv[0] == NULL ? program_name : argv[0]); + } while ((c = getopt(argc, argv, "egl")) != -1) { switch (c) { case 'e': mode |= EQUAL; break; case 'g': mode |= GREATER; break; case 'l': mode |= LESSER; break; - default: return usage(program_name); + default: return usage(argv[0]); } } - if (optind + 2 /* ref cmp */ > argc) { return usage(program_name); } + if (optind + 2 /* ref cmp */ > argc) { return usage(argv[0]); } i = optind; @@ -71,7 +71,7 @@ int main(int argc, char *argv[]) { fprintf( stderr, "%s: argument #%d: Invalid integer\n", - program_name, + argv[0], (int)i ); return EX_USAGE; diff --git a/src/scrut.c b/src/scrut.c index 4d5a932..39fa698 100644 --- a/src/scrut.c +++ b/src/scrut.c @@ -39,16 +39,15 @@ usage(char *argv0) { int main(int argc, char *argv[]) { char sel[(sizeof opts) / (sizeof *opts)]; - program_name = (argv[0] == NULL ? program_name : argv[0]); - if (argc < 2) { return usage(program_name); } + if (argc < 2) { return usage(argv[0] == NULL ? program_name : argv[0]); } { /* option parsing */ char *p; memset(sel, '\0', sizeof sel); for (int c; (c = getopt(argc, argv, opts)) != -1;) { - if ((p = strchr(opts, c)) == NULL) { return usage(program_name); } + if ((p = strchr(opts, c)) == NULL) { return usage(argv[0]); } else { sel[p - opts] = c; } } @@ -62,7 +61,7 @@ int main(int argc, char *argv[]) { } } - if (optind == argc) { return usage(program_name); } + if (optind == argc) { return usage(argv[0]); } for (argv += optind ; *argv != NULL; ++argv) { struct stat buf;