From 6cf7fd979416ddac9c4e58ae1ac4336b95232118 Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 12 Jul 2024 15:23:57 -0600 Subject: [PATCH 01/84] dj(1): reformatting --- src/dj.c | 233 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 135 insertions(+), 98 deletions(-) diff --git a/src/dj.c b/src/dj.c index 3b5bc5f..9edee0f 100644 --- a/src/dj.c +++ b/src/dj.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2024 DTB + * Copyright (c) 2024 Emma Tebibyte * SPDX-License-Identifier: AGPL-3.0-or-later * * This program is free software: you can redistribute it and/or modify it under @@ -27,8 +28,8 @@ #endif #include /* close(2), getopt(3), lseek(2), read(2), write(2), * optarg, optind, STDIN_FILENO, STDOUT_FILENO */ -#include /* S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, - S_IWUSR */ +#include /* S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR */ + extern int errno; char *program_name = "dj"; @@ -36,7 +37,7 @@ char *program_name = "dj"; /* dj uses two structures that respectively correspond to the reading and * writing ends of its jockeyed "pipe". User-configurable members are noted * with their relevant options. */ -struct Io{ +struct Io { char *buf; /* buffer */ char *fn; /* file name (-io) */ size_t bs; /* buffer size (-bB) */ @@ -67,14 +68,13 @@ static int write_flags = O_WRONLY | O_CREAT; /* Macro to check if fd is stdin or stdout */ #define fdisstd(fd) ((fd) == STDIN_FILENO || (fd) == STDOUT_FILENO) -static struct Io * -Io_read(struct Io *io){ +static struct Io * Io_read(struct Io *io) { int t; assert(io->bs > 0); assert(io->bufuse < io->bs); - if((t = read(io->fd, &(io->buf)[io->bufuse], io->bs - io->bufuse)) < 0){ + if ((t = read(io->fd, &(io->buf)[io->bufuse], io->bs - io->bufuse)) < 0) { io->error = errno; t = 0; } @@ -89,17 +89,16 @@ Io_read(struct Io *io){ return io; } -static struct Io * -Io_write(struct Io *io){ +static struct Io * Io_write(struct Io *io) { int t; assert(io->bufuse > 0); assert(io->bufuse <= io->bs); - if((t = write(io->fd, io->buf, io->bufuse)) < 0){ + if ((t = write(io->fd, io->buf, io->bufuse)) < 0) { io->error = errno; t = 0; - }else if(t > 0) + } else if (t > 0) memmove(io->buf, &(io->buf)[t], (io->bufuse -= t)); io->bytes += t; @@ -109,20 +108,24 @@ Io_write(struct Io *io){ return io; } -static int -oserr(char *e, int n){ +static int oserr(char *e, int n) { fprintf(stderr, "%s: %s: %s\n", program_name, e, strerror(n)); return EX_OSERR; } /* Prints statistics regarding the use of dj, particularly partially and * completely read and written records. */ -static void -fprintio(FILE *stream, char *fmt, struct Io io[2]){ - - fprintf(stream, fmt, - io[0].rec, io[0].prec, io[1].rec, io[1].prec, - io[0].bytes, io[1].bytes); +static void fprintio(FILE *stream, char *fmt, struct Io io[2]) { + fprintf( + stream, + fmt, + io[0].rec, + io[0].prec, + io[1].rec, + io[1].prec, + io[0].bytes, + io[1].bytes + ); return; } @@ -130,8 +133,7 @@ fprintio(FILE *stream, char *fmt, struct Io io[2]){ /* Parses the string s to an integer, returning either the integer or in the * case of an error a negative integer. This is used for argument parsing * (e.g. -B [int]) in dj and no negative integer would be valid anyway. */ -static long -parse(char *s){ +static long parse(char *s){ long r; errno = 0; @@ -141,18 +143,17 @@ parse(char *s){ : -1; } -static int -usage(char *s){ - - fprintf(stderr, "Usage: %s [-Hn] [-a byte] [-c count]\n" +static int usage(char *s){ + fprintf( + stderr, "Usage: %s [-Hn] [-a byte] [-c count]\n" "\t[-i file] [-b block_size] [-s offset]\n" - "\t[-o file] [-B block_size] [-S offset]\n", - program_name); + "\t[-o file] [-B block_size] [-S offset]\n", program_name + ); return EX_USAGE; } -int main(int argc, char *argv[]){ +int main(int argc, char *argv[]) { int align; /* low 8b used, negative if no alignment is being done */ int count; /* 0 if dj(1) runs until no more reads are possible */ char *fmt; /* == fmt_asv (default) or fmt_human (-H) */ @@ -165,7 +166,7 @@ int main(int argc, char *argv[]){ count = 0; fmt = fmt_asv; noerror = 0; - for(i = 0; i < (sizeof io) / (sizeof *io); ++i){ + for (i = 0; i < (sizeof io) / (sizeof *io); ++i) { io[i].bs = 1024 /* 1 KiB */; /* GNU dd(1) default; POSIX says 512B */ io[i].bufuse = 0; io[i].bytes = 0; @@ -178,119 +179,144 @@ int main(int argc, char *argv[]){ io[i].seek = 0; } - if(argc > 0){ - int c; + if (!argc < 0) { usage(program_name); } - program_name = argv[0]; - while((c = getopt(argc, argv, ":a:b:B:c:i:hHns:S:o:")) != -1) - switch(c){ - case 'i': case 'o': i = (c == 'o'); - if(optarg[0] == '-' && optarg[1] == '\0'){ /* optarg == "-" */ + int c; + + program_name = argv[0]; + while ((c = getopt(argc, argv, "a:b:B:c:i:hHns:S:o:")) != -1) { + switch (c) { + case 'i': case 'o': /* input, output */ + i = (c == 'o'); + + /* optarg == "-" (stdin/stdout) */ + if (optarg[0] == '-' && optarg[1] == '\0') { io[i].fd = i == 0 ? STDIN_FILENO : STDOUT_FILENO; io[i].fn = i == 0 ? stdin_name : stdout_name; break; - }else{ + } else { int fd; - if((fd = open(optarg, io[i].fl, creat_mode)) != -1 - && (fdisstd(io[i].fd) || close(io[i].fd) == 0)){ + if (( + fd = open(optarg, io[i].fl, creat_mode)) != -1 + && (fdisstd(io[i].fd) || close(io[i].fd) == 0 + )) { io[i].fd = fd; io[i].fn = optarg; break; } } - return oserr(optarg, errno); - case 'n': noerror = 1; break; - case 'H': fmt = fmt_human; break; - case 'a': - if(optarg[0] == '\0' || optarg[1] == '\0'){ + + return oserr(optarg, errno); /* break; */ + case 'n': noerror = 1; break; /* retry failed reads once */ + case 'H': fmt = fmt_human; break; /* human-readable output */ + case 'a': /* input buffer padding */ + if (optarg[0] == '\0' || optarg[1] == '\0') { align = optarg[0]; break; } /* FALLTHROUGH */ - case 'c': case 'b': case 's': case 'B': case 'S': /* numbers */ - if(c == 'c' && (count = parse(optarg)) >= 0) - break; + case 'c': /* number of reads */ + case 'b': case 'B': /* input/output block size */ + case 's': case 'S': /* (s)kip/(S)eek in input/output */ + if (c == 'c' && (count = parse(optarg)) >= 0) { break; } + i = (c >= 'A' && c <= 'Z'); - c |= 0x20 /* 0b 0010 0000 */; /* (ASCII) make lowercase */ - if((c == 'b' && (io[i].bs = parse(optarg)) > 0) - || (c == 's' && (io[i].seek = parse(optarg)) >= 0)) - break; + c |= 0b00100000; /* (ASCII) make lowercase */ + + if(( + c == 'b' && (io[i].bs = parse(optarg)) > 0) + || (c == 's' && (io[i].seek = parse(optarg)) >= 0 + )) { break; } + /* FALLTHROUGH */ default: return usage(program_name); - } + } } assert(io->fd != STDIN_FILENO || io->fl == read_flags); assert(io->fd != STDOUT_FILENO || io->fl == write_flags); - if(argc > optind) - return usage(program_name); + if (argc > optind) { return usage(program_name); } - for(i = 0; i < (sizeof io) / (sizeof *io); ++i){ + for (i = 0; i < (sizeof io) / (sizeof *io); ++i) { /* buffer allocation */ - if((io[i].buf = malloc(io[i].bs * (sizeof *(io[i].buf)))) == NULL){ + if ((io[i].buf = malloc(io[i].bs * (sizeof *(io[i].buf)))) == NULL) { fprintf(stderr, "%s: Failed to allocate %zd bytes\n", program_name, io[i].bs); return EX_OSERR; } + /* easy seeking */ - if(!fdisstd(io[i].fd) && lseek(io[i].fd, io[i].seek, SEEK_SET) != -1) + if (!fdisstd(io[i].fd) && lseek(io[i].fd, io[i].seek, SEEK_SET) != -1) { io[i].seek = 0; + } } /* hard seeking */ - if(io[1].seek > 0){ + if (io[1].seek > 0) { size_t t; - do{ - memset(io[1].buf, '\0', - (t = io[1].bufuse = MIN(io[1].bs, io[1].seek))); - if(Io_write(&io[1])->bufuse == t && !noerror && io[1].error == 0) + + do { + memset( + io[1].buf, '\0', + (t = io[1].bufuse = MIN(io[1].bs, io[1].seek)) + ); + + if (Io_write(&io[1])->bufuse == t && !noerror && io[1].error == 0) { Io_write(&io[1]); /* second chance */ - if(io[1].error != 0) - return oserr(io[1].fn, io[1].error); - }while((io[1].seek -= (t - io[1].bufuse)) > 0 && io[1].bufuse != t); + } + if (io[1].error != 0) { return oserr(io[1].fn, io[1].error); } + } while ((io[1].seek -= (t - io[1].bufuse)) > 0 && io[1].bufuse != t); + io[1].bufuse = 0; } - if(io[1].seek > 0){ + if (io[1].seek > 0) { fprintio(stderr, fmt, io); return oserr(io[1].fn, errno); } - do{ + do { /* while(count == 0 || --count > 0); */ assert(io[0].bufuse == 0); { /* read */ long skipping; - size_t t; /* hack to intentionally get a partial read from Io_read */ - if((skipping = MIN(io[0].seek, io[0].bs)) > 0) + if ((skipping = MIN(io[0].seek, io[0].bs)) > 0) { io[0].bufuse = io[0].bs - (size_t)skipping; + } - t = io[0].bufuse; - if(Io_read(&io[0])->bufuse == t && !noerror && io[0].error == 0) + size_t t = io[0].bufuse; + if (Io_read(&io[0])->bufuse == t && !noerror && io[0].error == 0) { Io_read(&io[0]); /* second chance */ - assert(io[0].bufuse >= t); - if(io[0].bufuse == t) /* that's all she wrote */ - break; + } - if(/* t < io[0].bufuse && */ io[0].bufuse < io[0].bs){ + assert(io[0].bufuse >= t); + + if (io[0].bufuse == t) /* that's all she wrote */ { break; } + + if (/* t < io[0].bufuse && */ io[0].bufuse < io[0].bs) { fprintf(stderr, "%s: Partial read:\n\t", program_name); fprintio(stderr, fmt, io); - if(!noerror) - count = 1; - if(align >= 0){ + + if (!noerror) { count = 1; } + + if (align >= 0) { /* fill the rest of the ibuf with padding */ - memset(&(io[0].buf)[io[0].bufuse], align, - io[0].bs - io[0].bufuse); + memset( + &(io[0].buf)[io[0].bufuse], + align, + io[0].bs - io[0].bufuse + ); + io->bufuse = io->bs; } } - if(skipping > 0){ + if (skipping > 0) { io[0].seek -= skipping; io[0].bufuse = 0; count += (count != 0); @@ -299,55 +325,66 @@ int main(int argc, char *argv[]){ } /* write */ - do{ + do { /* while(io[0].bufuse > 0); */ int t; - if(io[0].bs <= io[1].bs){ + if (io[0].bs <= io[1].bs) { int n; /* saturate obuf */ - memcpy(io[1].buf, io[0].buf, - (io[1].bufuse = (n = MIN(io[0].bufuse, io[1].bs)))); + memcpy( + io[1].buf, io[0].buf, + (io[1].bufuse = (n = MIN(io[0].bufuse, io[1].bs))) + ); /* permute the copied units out of ibuf */ memmove(io[0].buf, &(io[0].buf)[n], (io[0].bufuse -= n)); - }else /* if(io[0].bs < io[1].bs) */ { + } else /* if(io[0].bs < io[1].bs) */ { int n; /* drain what we can from ibuf */ - memcpy(&(io[1].buf)[io[1].bufuse], io[0].buf, - (n = MIN(io[0].bufuse, io[1].bs - io[1].bufuse))); + memcpy( + &(io[1].buf)[io[1].bufuse], io[0].buf, + (n = MIN(io[0].bufuse, io[1].bs - io[1].bufuse)) + ); + io[1].bufuse += n; + /* permute out the copied units */ memmove(io[0].buf, &(io[0].buf)[n], io[0].bs - n); + io[0].bufuse -= n; - if(io[0].bs + io[1].bufuse <= io[1].bs && count != 1) + if(io[0].bs + io[1].bufuse <= io[1].bs && count != 1) { continue; /* obuf not saturated - we could write more */ + } } t = io[1].bufuse; - if(Io_write(&io[1])->bufuse == t && !noerror && io[1].error == 0) + if (Io_write(&io[1])->bufuse == t && !noerror && io[1].error == 0) { Io_write(&io[1]); /* second chance */ + } + assert(io[1].bufuse <= t); - if(io[1].bufuse == t){ /* no more love */ + + if (io[1].bufuse == t) { /* no more love */ count = 1; break; } - if(0 < io[1].bufuse /* && io[1].bufuse < t */){ + if (0 < io[1].bufuse /* && io[1].bufuse < t */) { fprintf(stderr, "%s: Partial write:\n\t", program_name); fprintio(stderr, fmt, io); - if(!noerror) - count = 1; + + if(!noerror) { count = 1; } } - }while(io[0].bufuse > 0); - }while(count == 0 || --count > 0); + } while(io[0].bufuse > 0); + } while(count == 0 || --count > 0); fprintio(stderr, fmt, io); - for(i = 0; i < (sizeof io) / (sizeof *io); ++i) - if(io[i].error) - return oserr(io[i].fn, io[i].error); + for (i = 0; i < (sizeof io) / (sizeof *io); ++i) { + if (io[i].error) { return oserr(io[i].fn, io[i].error); } + } return EX_OK; } From db0dd02d558b001c22ace501712dd8ab97ab7398 Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 12 Jul 2024 15:32:30 -0600 Subject: [PATCH 02/84] dj(1): more formatting --- src/dj.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/dj.c b/src/dj.c index 9edee0f..c0ae9cc 100644 --- a/src/dj.c +++ b/src/dj.c @@ -138,9 +138,7 @@ static long parse(char *s){ errno = 0; r = strtol(s, &s, 0); - return (*s == '\0' /* no chars left unparsed */ && errno == 0) - ? r - : -1; + return (*s == '\0' && errno == 0) ? r : -1; /* no chars left unparsed */ } static int usage(char *s){ @@ -197,10 +195,10 @@ int main(int argc, char *argv[]) { } else { int fd; - if (( - fd = open(optarg, io[i].fl, creat_mode)) != -1 - && (fdisstd(io[i].fd) || close(io[i].fd) == 0 - )) { + if ( + (fd = open(optarg, io[i].fl, creat_mode)) != -1 + && (fdisstd(io[i].fd) || close(io[i].fd) == 0) + ) { io[i].fd = fd; io[i].fn = optarg; break; @@ -224,10 +222,10 @@ int main(int argc, char *argv[]) { i = (c >= 'A' && c <= 'Z'); c |= 0b00100000; /* (ASCII) make lowercase */ - if(( - c == 'b' && (io[i].bs = parse(optarg)) > 0) - || (c == 's' && (io[i].seek = parse(optarg)) >= 0 - )) { break; } + if ( + (c == 'b' && (io[i].bs = parse(optarg)) > 0) + || (c == 's' && (io[i].seek = parse(optarg)) >= 0) + ) { break; } /* FALLTHROUGH */ default: @@ -243,8 +241,10 @@ int main(int argc, char *argv[]) { for (i = 0; i < (sizeof io) / (sizeof *io); ++i) { /* buffer allocation */ if ((io[i].buf = malloc(io[i].bs * (sizeof *(io[i].buf)))) == NULL) { - fprintf(stderr, "%s: Failed to allocate %zd bytes\n", - program_name, io[i].bs); + fprintf( + stderr, "%s: Failed to allocate %zd bytes\n", + program_name, io[i].bs + ); return EX_OSERR; } From 1ad411488250ff93713f8f5461cb5e6e38c64689 Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 12 Jul 2024 15:42:24 -0600 Subject: [PATCH 03/84] dj(1): remove unnecessary macros --- src/dj.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/dj.c b/src/dj.c index c0ae9cc..a36123e 100644 --- a/src/dj.c +++ b/src/dj.c @@ -23,9 +23,7 @@ #include /* fprintf(3), stderr */ #include /* malloc(3), strtol(3), size_t */ #include /* memcpy(3), memmove(3), memset(3) */ -#if !defined EX_OK || !defined EX_OSERR || !defined EX_USAGE -# include -#endif +#include #include /* close(2), getopt(3), lseek(2), read(2), write(2), * optarg, optind, STDIN_FILENO, STDOUT_FILENO */ #include /* S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR */ From acc3cf3e90c353461fa45612c64c4ea51eadf760 Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 12 Jul 2024 15:43:00 -0600 Subject: [PATCH 04/84] swab(1): formatting, remove gotos --- src/npc.c | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/npc.c b/src/npc.c index 1f96668..d17f258 100644 --- a/src/npc.c +++ b/src/npc.c @@ -22,7 +22,12 @@ #include /* getopt(3) */ #include -int main(int argc, char *argv[]){ +int usage(char *s) { + fprintf(stderr, "Usage: %s [-et]\n", s); + return EX_USAGE; +} + +int main(int argc, char *argv[]) { int c; char showend; char showtab; @@ -30,32 +35,30 @@ int main(int argc, char *argv[]){ showend = 0; showtab = 0; - if(argc > 0) - while((c = getopt(argc, argv, "et")) != -1) - switch(c){ - case 'e': showend = 1; break; - case 't': showtab = 1; break; - default: goto usage; - } + if(!argc > 0) { usage(argv[0]); } - if(argc > optind){ -usage: fprintf(stderr, "Usage: %s [-et]\n", argv[0]); - return EX_USAGE; + while ((c = getopt(argc, argv, "et")) != -1) { + switch(c){ + case 'e': showend = 1; break; + case 't': showtab = 1; break; + default: return usage(argv[0]); + } } - while((c = getc(stdin)) != EOF){ - if((c & 0x80) != 0) - fputs("M-", stdout); - switch(c ^ 0x80 /* 0b 1000 0000 */){ - case 0x7f: fputs("^?", stdout); - break; - case '\n': if(showend) - putc('$', stdout); - default: - if(c >= ' ' || c == '\n' || (!showtab && c == '\t')) - putc(c, stdout); - else - fprintf(stdout, "^%c", c + '@'); + if(argc > optind) { return usage(argv[0]); } + + while ((c = getc(stdin)) != EOF) { + if ((c & 0x80) != 0) { fputs("M-", stdout); } + + switch (c ^ 0b10000000) { + case 0x7f: fputs("^?", stdout); break; + case '\n': if (showend) { putc('$', stdout); } + default: + if(c >= ' ' || c == '\n' || (!showtab && c == '\t')) { + putc(c, stdout); + } else { + fprintf(stdout, "^%c", c + '@'); + } } } From 9cfc48c96020b0d36ef05cae7b79179698e678e5 Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 12 Jul 2024 15:54:30 -0600 Subject: [PATCH 05/84] intcmp(1): formatting, removed gotos --- src/intcmp.c | 70 ++++++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/src/intcmp.c b/src/intcmp.c index d6dff0d..ce4a5e0 100644 --- a/src/intcmp.c +++ b/src/intcmp.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2023 DTB + * Copyright (c) 2024 Emma Tebibyte * SPDX-License-Identifier: AGPL-3.0-or-later * * This program is free software: you can redistribute it and/or modify it under @@ -22,16 +23,24 @@ #include /* getopt(3), optind */ #include -/* 0b00? */ /* Equal | -e | 0b001 | 1 */ -#define EQUAL 0x01 /* Greater | -g | 0b010 | 2 */ -/* 0b0?0 */ /* Greater or Equal | -ge | 0b011 | 3 */ -#define GREATER 0x02 /* Less | -l | 0b100 | 4 */ -/* 0b?00 */ /* Less or Equal | -le | 0b101 | 5 */ -#define LESS 0x04 /* Inequal (Greater or Less) | -gl | 0b110 | 6 */ +/* 0b00? */ /* Equal | -e | 0b001 | 1 */ +#define EQUAL 0x01 /* Greater | -g | 0b010 | 2 */ +/* 0b0?0 */ /* Greater or Equal | -ge | 0b011 | 3 */ +#define GREATER 0x02 /* Lesser | -l | 0b100 | 4 */ +/* 0b?00 */ /* Lesser or Equal | -le | 0b101 | 5 */ +#define LESSER 0x04 /* Inequal (Greater or Lesser) | -gl | 0b110 | 6 */ static char *program_name = "intcmp"; -int main(int argc, char *argv[]){ +int usage(char *s) { + fprintf( + stderr, "Usage: %s [-egl] integer integer...\n", + s == NULL ? program_name : s + ); + return EX_USAGE; +} + +int main(int argc, char *argv[]) { int c; size_t i; unsigned char mode; @@ -39,44 +48,41 @@ int main(int argc, char *argv[]){ mode = 0; - if(argc < 3) - goto usage; + if(argc < 3) { return usage(argv[0]); } - while((c = getopt(argc, argv, "egl")) != -1) + while ((c = getopt(argc, argv, "egl")) != -1) { switch(c){ - case 'e': mode |= EQUAL; break; - case 'g': mode |= GREATER; break; - case 'l': mode |= LESS; break; - default: goto usage; + case 'e': mode |= EQUAL; break; + case 'g': mode |= GREATER; break; + case 'l': mode |= LESSER; break; + default: return usage(argv[0]); } - - if(optind + 2 /* ref cmp */ > argc){ -usage: fprintf(stderr, - "Usage: %s [-egl] integer integer...\n", - argv[0] == NULL ? program_name : argv[0]); - return EX_USAGE; } + if(optind + 2 /* ref cmp */ > argc){ return usage(argv[0]); } + i = optind; - do{ r = c; + do{ + r = c; c = strtol(argv[i], &argv[i], 10); - if(*argv[i] != '\0' || errno != 0){ - fprintf(stderr, "%s: argument #%d: Invalid integer\n", - argv[0], (int)i); + + if (*argv[i] != '\0' || errno != 0) { + fprintf( + stderr, "%s: argument #%d: Invalid integer\n", argv[0], (int)i + ); return EX_USAGE; } - if(i == optind) - continue; + if (i == optind) { continue; } /* rule enforcement; if a mode isn't permitted and the numbers * correspond to it, return 1 */ - if( (!(mode & EQUAL) && r == c) - || (!(mode & GREATER) && r > c) - || (!(mode & LESS) && r < c)) - return 1; - }while(++i < argc); + if ( (!(mode & EQUAL) && r == c) + || (!(mode & GREATER) && r > c) + || (!(mode & LESSER) && r < c) + ) { return 1; } + } while(++i < argc); - return 0; + return EX_OK; } From 6e1e3db6c877592056810c22fc5e38d7b0228fc8 Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 12 Jul 2024 15:55:36 -0600 Subject: [PATCH 06/84] npc(1): forgot to update copyright --- src/npc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/npc.c b/src/npc.c index d17f258..a6e3ce9 100644 --- a/src/npc.c +++ b/src/npc.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2023 DTB + * Copyright (c) 2024 Emma Tebibyte * SPDX-License-Identifier: AGPL-3.0-or-later * * This program is free software: you can redistribute it and/or modify it under From 5d2872d05046fca6d326c5ae3552dac208ee7787 Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 12 Jul 2024 16:04:07 -0600 Subject: [PATCH 07/84] scrut(1): formatting, removes gotos --- src/scrut.c | 62 +++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/src/scrut.c b/src/scrut.c index d85d243..f708eb5 100644 --- a/src/scrut.c +++ b/src/scrut.c @@ -20,9 +20,7 @@ #include /* fprintf(3), stderr, NULL */ #include /* EXIT_FAILURE, EXIT_SUCCESS */ #include /* memset(3), strchr(3) */ -#ifndef EX_USAGE -# include -#endif +#include #include /* access(3), getopt(3), F_OK, R_OK, W_OK, X_OK */ #include /* lstat(3), stat struct, S_ISBLK, S_ISCHR, S_ISDIR, * S_ISFIFO, S_ISGID, S_ISREG, S_ISLNK, S_ISSOCK, @@ -32,48 +30,56 @@ static char args[] = "bcdefghkprsuwxLS"; static char ops[(sizeof args) / (sizeof *args)]; static char *program_name = "scrut"; -int main(int argc, char *argv[]){ +int usage(char *s) { + fprintf( + stderr, + "Usage: %s [-%s] file...\n", + s == NULL ? program_name : s, args + ); + + return EX_USAGE; +} + +int main(int argc, char *argv[]) { struct stat buf; int c; size_t i; char *p; - if(argc < 2) - goto usage; + if (argc < 2) { return usage(argv[0]); } memset(ops, '\0', sizeof ops); - while((c = getopt(argc, argv, args)) != -1) - if((p = strchr(args, c)) == NULL) - goto usage; - else + while ((c = getopt(argc, argv, args)) != -1) { + if ((p = strchr(args, c)) == NULL) { + return usage(argv[0]); + } else { ops[p - args] = c; + } + } + /* straighten out ops */ - for(i = 0, p = ops; i < (sizeof ops) / (sizeof *ops); ++i) + for (i = 0, p = ops; i < (sizeof ops) / (sizeof *ops); ++i) { if(ops[i] != '\0'){ *p = ops[i]; if(&ops[i] != p++) ops[i] = '\0'; } + } - if(optind == argc) - goto usage; + if (optind == argc) { return usage(argv[0]); } argv += optind; - do{ if(access(*argv, F_OK) != 0 || lstat(*argv, &buf) == -1) + do { /* while(*++argv != NULL); */ + if(access(*argv, F_OK) != 0 || lstat(*argv, &buf) == -1) { return EXIT_FAILURE; /* doesn't exist or isn't stattable */ + } - for(i = 0; ops[i] != '\0'; ++i) - if(ops[i] == 'e') + for (i = 0; ops[i] != '\0'; ++i) + if (ops[i] == 'e') { continue; - else if(ops[i] == 'h'){ -usage: fprintf(stderr, "Usage: %s [-%s] file...\n", - argv[0] == NULL - ? program_name - : argv[0], - args); - - return EX_USAGE; - }else if( + } else if (ops[i] == 'h') { + return usage(argv[0]); + } else if ( (ops[i] == 'b' && !S_ISBLK(buf.st_mode)) || (ops[i] == 'c' @@ -99,9 +105,9 @@ usage: fprintf(stderr, "Usage: %s [-%s] file...\n", || (ops[i] == 'L' && !S_ISLNK(buf.st_mode)) || (ops[i] == 'S' - && !S_ISSOCK(buf.st_mode))) - return EXIT_FAILURE; - }while(*++argv != NULL); + && !S_ISSOCK(buf.st_mode)) + ) { return EXIT_FAILURE; } + } while(*++argv != NULL); return EXIT_SUCCESS; } From 59de0262bd5a543c19b494944ef3cfe658d8205d Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 12 Jul 2024 16:15:41 -0600 Subject: [PATCH 08/84] strcmp(1): adds copyright header, formatting, removes unused #include --- src/strcmp.c | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/src/strcmp.c b/src/strcmp.c index 33b73c2..2872788 100644 --- a/src/strcmp.c +++ b/src/strcmp.c @@ -1,24 +1,49 @@ +/* + * Copyright (c) 2023 DTB + * Copyright (c) 2023–2024 Emma Tebibyte + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ + #include /* fprintf(3), stderr */ -#include /* EXIT_FAILURE */ #include static char *program_name = "strcmp"; -int main(int argc, char *argv[]){ +int main(int argc, char *argv[]) { int i; - if(argc < 3){ - fprintf(stderr, "Usage: %s string string...\n", - argv[0] == NULL ? program_name : argv[0]); + if (argc < 3) { + fprintf( + stderr, + "Usage: %s string string...\n", + argv[0] == NULL ? program_name : argv[0] + ); + return EX_USAGE; } - for(; *argv[1] != '\0'; ++argv[1]) - for(i = 2; i < argc; ++i) - if(*argv[i-1] > *argv[i]) + for (; *argv[1] != '\0'; ++argv[1]) { + for(i = 2; i < argc; ++i) { + if (*argv[i-1] > *argv[i]) { return 1; - else if(*argv[i-1] < *argv[i]++) - return -1; /* actually 255 */ + } else if (*argv[i-1] < *argv[i]++) { + return 255; + } + } + } - return 0; + return EX_OK; } From 958bfa52ed3fab3b251bb350f98b76fe7ddaa486 Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 12 Jul 2024 16:18:48 -0600 Subject: [PATCH 09/84] scrut(1): more formatting --- src/scrut.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/scrut.c b/src/scrut.c index f708eb5..a0ee93d 100644 --- a/src/scrut.c +++ b/src/scrut.c @@ -59,10 +59,9 @@ int main(int argc, char *argv[]) { /* straighten out ops */ for (i = 0, p = ops; i < (sizeof ops) / (sizeof *ops); ++i) { - if(ops[i] != '\0'){ + if (ops[i] != '\0') { *p = ops[i]; - if(&ops[i] != p++) - ops[i] = '\0'; + if (&ops[i] != p++) { ops[i] = '\0'; } } } From 34cd715e37bb4999cd925a62a4b6764f30f0d81f Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 12 Jul 2024 16:22:56 -0600 Subject: [PATCH 10/84] mm(1): removes unnecessary macros --- src/mm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/mm.c b/src/mm.c index e905b35..231985d 100644 --- a/src/mm.c +++ b/src/mm.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2024 DTB + * Copyright (c) 2024 Emma Tebibyte * SPDX-License-Identifier: AGPL-3.0-or-later * * This program is free software: you can redistribute it and/or modify it under @@ -23,9 +24,7 @@ #include /* free(3), realloc(3) */ #include /* strcmp(3), strerror(3) */ #include /* getopt(3) */ -#if !defined EX_IOERR || !defined EX_OK || !defined EX_OSERR \ - || !defined EX_USAGE -# include +#include #endif extern int errno; From 666c621a02d1ec7ed935b5c3257478d2aadfb63f Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 12 Jul 2024 16:38:50 -0600 Subject: [PATCH 11/84] strcmp(1): more formatting --- src/strcmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strcmp.c b/src/strcmp.c index 2872788..b18f8c8 100644 --- a/src/strcmp.c +++ b/src/strcmp.c @@ -36,7 +36,7 @@ int main(int argc, char *argv[]) { } for (; *argv[1] != '\0'; ++argv[1]) { - for(i = 2; i < argc; ++i) { + for (i = 2; i < argc; ++i) { if (*argv[i-1] > *argv[i]) { return 1; } else if (*argv[i-1] < *argv[i]++) { From 99f2b2963a5f5d7288326edee6836cbb7f5d6ce1 Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 12 Jul 2024 16:39:11 -0600 Subject: [PATCH 12/84] dj(1): more formatting --- src/dj.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dj.c b/src/dj.c index a36123e..7a2512e 100644 --- a/src/dj.c +++ b/src/dj.c @@ -96,8 +96,9 @@ static struct Io * Io_write(struct Io *io) { if ((t = write(io->fd, io->buf, io->bufuse)) < 0) { io->error = errno; t = 0; - } else if (t > 0) + } else if (t > 0) { memmove(io->buf, &(io->buf)[t], (io->bufuse -= t)); + } io->bytes += t; io->prec += (t > 0 && io->bufuse > 0); From 1dfad87e8742faae253951d5d43d635a1feb2f8a Mon Sep 17 00:00:00 2001 From: emma Date: Sat, 13 Jul 2024 16:56:56 -0600 Subject: [PATCH 13/84] dj(1): lists sysexits imports, fixes negation --- src/dj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dj.c b/src/dj.c index 7a2512e..b847b38 100644 --- a/src/dj.c +++ b/src/dj.c @@ -23,7 +23,7 @@ #include /* fprintf(3), stderr */ #include /* malloc(3), strtol(3), size_t */ #include /* memcpy(3), memmove(3), memset(3) */ -#include +#include /* EX_OK, EX_OSERR, EX_USAGE */ #include /* close(2), getopt(3), lseek(2), read(2), write(2), * optarg, optind, STDIN_FILENO, STDOUT_FILENO */ #include /* S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR */ @@ -176,7 +176,7 @@ int main(int argc, char *argv[]) { io[i].seek = 0; } - if (!argc < 0) { usage(program_name); } + if (!(argc < 0)) { usage(program_name); } int c; From d9dd4e60571292b32f7aa94b7bc6b0e01e6ed638 Mon Sep 17 00:00:00 2001 From: emma Date: Sat, 13 Jul 2024 16:57:52 -0600 Subject: [PATCH 14/84] intcmp(1): formatting, lists sysexits imports, allows no args --- src/intcmp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/intcmp.c b/src/intcmp.c index ce4a5e0..961b8a9 100644 --- a/src/intcmp.c +++ b/src/intcmp.c @@ -21,7 +21,7 @@ #include /* fprintf(3), stderr */ #include /* strtol(3), size_t, EXIT_FAILURE */ #include /* getopt(3), optind */ -#include +#include /* EX_OK, EX_USAGE */ /* 0b00? */ /* Equal | -e | 0b001 | 1 */ #define EQUAL 0x01 /* Greater | -g | 0b010 | 2 */ @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) { mode = 0; - if(argc < 3) { return usage(argv[0]); } + if (argc == 0 | argc < 3) { return usage(argv[0]); } while ((c = getopt(argc, argv, "egl")) != -1) { switch(c){ From 0c530dffbfc60f65862c8c05222758b4f4149906 Mon Sep 17 00:00:00 2001 From: emma Date: Sat, 13 Jul 2024 17:01:53 -0600 Subject: [PATCH 15/84] intcmp(1): formatting, fixes argv[0] ternary and usage function --- src/intcmp.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/intcmp.c b/src/intcmp.c index 961b8a9..132c230 100644 --- a/src/intcmp.c +++ b/src/intcmp.c @@ -33,10 +33,8 @@ static char *program_name = "intcmp"; int usage(char *s) { - fprintf( - stderr, "Usage: %s [-egl] integer integer...\n", - s == NULL ? program_name : s - ); + fprintf(stderr, "Usage: %s [-egl] integer integer...\n", s); + return EX_USAGE; } @@ -45,25 +43,26 @@ int main(int argc, char *argv[]) { size_t i; unsigned char mode; int r; /* reference integer */ + char *s = (argv[0] == NULL ? program_name : argv[0]); mode = 0; - if (argc == 0 | argc < 3) { return usage(argv[0]); } + if (argc == 0 | argc < 3) { return usage(s); } while ((c = getopt(argc, argv, "egl")) != -1) { - switch(c){ + switch (c){ case 'e': mode |= EQUAL; break; case 'g': mode |= GREATER; break; case 'l': mode |= LESSER; break; - default: return usage(argv[0]); + default: return usage(s); } } - if(optind + 2 /* ref cmp */ > argc){ return usage(argv[0]); } + if (optind + 2 /* ref cmp */ > argc) { return usage(s); } i = optind; - do{ + do { r = c; c = strtol(argv[i], &argv[i], 10); @@ -82,7 +81,7 @@ int main(int argc, char *argv[]) { || (!(mode & GREATER) && r > c) || (!(mode & LESSER) && r < c) ) { return 1; } - } while(++i < argc); + } while (++i < argc); return EX_OK; } From 8421f8be8761b322c4eb6afbe1977c24a9172fd7 Mon Sep 17 00:00:00 2001 From: emma Date: Sat, 13 Jul 2024 17:02:23 -0600 Subject: [PATCH 16/84] mm(1): specifies sysexits imports --- src/mm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mm.c b/src/mm.c index 231985d..01fd400 100644 --- a/src/mm.c +++ b/src/mm.c @@ -24,8 +24,8 @@ #include /* free(3), realloc(3) */ #include /* strcmp(3), strerror(3) */ #include /* getopt(3) */ -#include -#endif +#include /* EX_IOERR, EX_OK, EX_OSERR, EX_USAGE */ + extern int errno; /* This structure is how open files are tracked. */ From 35a20dca7906eebc221af8672163130af2876aec Mon Sep 17 00:00:00 2001 From: emma Date: Sat, 13 Jul 2024 17:03:41 -0600 Subject: [PATCH 17/84] npc(1): specifies sysexits imports, formatting --- src/npc.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/npc.c b/src/npc.c index a6e3ce9..0892a72 100644 --- a/src/npc.c +++ b/src/npc.c @@ -19,9 +19,9 @@ #include /* fprintf(3), fputs(3), getc(3), putc(3), stdin, stdout, * EOF */ -#include /* EXIT_FAILURE, EXIT_SUCCESS */ +#include /* EXIT_FAILURE */ #include /* getopt(3) */ -#include +#include /* EX_OK, EX_USAGE */ int usage(char *s) { fprintf(stderr, "Usage: %s [-et]\n", s); @@ -36,17 +36,17 @@ int main(int argc, char *argv[]) { showend = 0; showtab = 0; - if(!argc > 0) { usage(argv[0]); } - - while ((c = getopt(argc, argv, "et")) != -1) { - switch(c){ - case 'e': showend = 1; break; - case 't': showtab = 1; break; - default: return usage(argv[0]); + if (argc > 0) { + while ((c = getopt(argc, argv, "et")) != -1) { + switch (c){ + case 'e': showend = 1; break; + case 't': showtab = 1; break; + default: return usage(argv[0]); + } } } - if(argc > optind) { return usage(argv[0]); } + if (argc > optind) { return usage(argv[0]); } while ((c = getc(stdin)) != EOF) { if ((c & 0x80) != 0) { fputs("M-", stdout); } @@ -55,7 +55,7 @@ int main(int argc, char *argv[]) { case 0x7f: fputs("^?", stdout); break; case '\n': if (showend) { putc('$', stdout); } default: - if(c >= ' ' || c == '\n' || (!showtab && c == '\t')) { + if (c >= ' ' || c == '\n' || (!showtab && c == '\t')) { putc(c, stdout); } else { fprintf(stdout, "^%c", c + '@'); From 26b0c93f4d8be439bee4c5171b39a1897425e95e Mon Sep 17 00:00:00 2001 From: emma Date: Sat, 13 Jul 2024 17:04:38 -0600 Subject: [PATCH 18/84] strcmp(1): returns -1, specifies sysexits imports --- src/strcmp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/strcmp.c b/src/strcmp.c index b18f8c8..4b6bf3c 100644 --- a/src/strcmp.c +++ b/src/strcmp.c @@ -18,7 +18,7 @@ */ #include /* fprintf(3), stderr */ -#include +#include /* EX_OK, EX_USAGE */ static char *program_name = "strcmp"; @@ -40,7 +40,7 @@ int main(int argc, char *argv[]) { if (*argv[i-1] > *argv[i]) { return 1; } else if (*argv[i-1] < *argv[i]++) { - return 255; + return -1; /* actually 255 */ } } } From c7c6ca2c60d92e58fda3375c4a76ad0d051b2511 Mon Sep 17 00:00:00 2001 From: emma Date: Sat, 13 Jul 2024 17:23:31 -0600 Subject: [PATCH 19/84] mm(1): formatting --- src/mm.c | 187 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 110 insertions(+), 77 deletions(-) diff --git a/src/mm.c b/src/mm.c index 01fd400..0aced76 100644 --- a/src/mm.c +++ b/src/mm.c @@ -59,9 +59,9 @@ static char *wharsh = "wb"; * returning the FILE if successful and NULL if not, allocating more memory in * the files buffers as needed. */ static FILE * -Files_append(struct Files *files, FILE *file, char *name){ +Files_append(struct Files *files, FILE *file, char *name) { - if(file == NULL || (files->s == files->a + if (file == NULL || (files->s == files->a && ((files->files = realloc(files->files, (files->a += (files->a == 0) ? ALLOC_INITIAL @@ -83,7 +83,7 @@ Files_append(struct Files *files, FILE *file, char *name){ /* Prints a diagnostic message based on errno and returns an exit status * appropriate for an OS error. */ static int -oserr(char *s, char *r){ +oserr(char *s, char *r) { fprintf(stderr, "%s: %s: %s\n", s, r, strerror(errno)); @@ -94,12 +94,16 @@ oserr(char *s, char *r){ * closing its files and freeing its files and names arrays, returning retval * from main. */ #define terminate \ - for(i = 0; i < 2; ++i){ \ - for(j = 0; j < files[i].s; ++j) \ - if(files[i].files[j] != stdin \ - && files[i].files[j] != stdout \ - && files[i].files[j] != stderr) \ + for (i = 0; i < 2; ++i) { \ + for (j = 0; j < files[i].s; ++j) { \ + if ( \ + files[i].files[j] != stdin \ + && files[i].files[j] != stdout \ + && files[i].files[j] != stderr \ + ) { \ fclose(files[i].files[j]); \ + } \ + } \ free(files[i].files); \ free(files[i].names); \ } \ @@ -107,14 +111,14 @@ oserr(char *s, char *r){ /* Prints a usage text, in which s is the program being run (i.e. argv[0]), and * returns an exit status appropriate for a usage error. */ -int usage(char *s){ +int usage(char *s) { fprintf(stderr, "Usage: %s [-aenu] [-i input]... [-o output]...\n", s); return EX_USAGE; } -int main(int argc, char *argv[]){ +int main(int argc, char *argv[]) { int c; struct Files files[2]; /* {read, write} */ size_t i; @@ -127,70 +131,83 @@ int main(int argc, char *argv[]){ * these initial values will be overwritten, so to, say, use mm(1) * equivalently to tee(1p), -o - will need to be specified before * additional files to ensure standard output is still written. */ - for(i = 0; i < 2; ++i){ + for (i = 0; i < 2; ++i) { files[i].a = 0; files[i].s = 0; files[i].mode = fmode[i]; files[i].files = NULL; files[i].names = NULL; - Files_append(&files[i], i == 0 ? stdin : stdout, - i == 0 ? stdin_name : stdout_name); + + Files_append( + &files[i], + i == 0 ? stdin : stdout, + i == 0 ? stdin_name : stdout_name + ); + files[i].s = 0; } k = 0; - if(argc > 0) - program_name = argv[0]; + if (argc > 0) { program_name = argv[0]; } - if(argc > 1) - while((c = getopt(argc, argv, "aehi:no:u")) != -1) - switch(c){ - case 'a': /* "rb+" -> "ab" */ - files[1].mode[0] = 'a'; - files[1].mode[2] = '\0'; - break; - case 'e': - if(Files_append(&files[1], stderr, stderr_name) != NULL) + if (argc > 1) { + while ((c = getopt(argc, argv, "aehi:no:u")) != -1) { + switch (c){ + case 'a': /* "rb+" -> "ab" */ + files[1].mode[0] = 'a'; + files[1].mode[2] = '\0'; break; - retval = oserr(argv[0], "-e"); - terminate; - case 'i': - if((strcmp(optarg, "-") == 0 && Files_append(&files[0], - stdin, stdin_name) != NULL) - || Files_open(&files[0], optarg) != NULL) - break; - retval = oserr(argv[0], optarg); - terminate; - case 'o': - if((strcmp(optarg, "-") == 0 && Files_append(&files[1], - stdout, stdout_name) != NULL) - || Files_open(&files[1], optarg) != NULL) - break; - /* does not exist, so try to create it */ - if(errno == ENOENT){ - files[1].mode = wharsh; - if(Files_open(&files[1], optarg) != NULL){ - files[1].mode = fmode[1]; + case 'e': + if (Files_append(&files[1], stderr, stderr_name) != NULL) { break; } - } - retval = oserr(argv[0], optarg); - terminate; - case 'n': - if(signal(SIGINT, SIG_IGN) != SIG_ERR) - break; - retval = oserr(argv[0], "-n"); - terminate; - case 'u': - k = 1; - break; - default: - retval = usage(argv[0]); - terminate; - } - if(optind != argc){ + retval = oserr(argv[0], "-e"); + terminate; + case 'i': + if ( + (strcmp(optarg, "-") == 0 + && Files_append(&files[0], stdin, stdin_name) != NULL) + || Files_open(&files[0], optarg) != NULL + ) { break; } + + retval = oserr(argv[0], optarg); + terminate; + case 'o': + if ( + (strcmp(optarg, "-") == 0 + && Files_append(&files[1], stdout, stdout_name) != NULL) + || Files_open(&files[1], optarg) != NULL + ) { break; } + /* does not exist, so try to create it */ + if (errno == ENOENT) { + files[1].mode = wharsh; + + if (Files_open(&files[1], optarg) != NULL) { + files[1].mode = fmode[1]; + break; + } + } + + retval = oserr(argv[0], optarg); + terminate; + case 'n': + if (signal(SIGINT, SIG_IGN) != SIG_ERR) { break; } + + retval = oserr(argv[0], "-n"); + terminate; + case 'u': + k = 1; + break; + default: + retval = usage(argv[0]); + terminate; + } + } + } + + if (optind != argc) { retval = usage(argv[0]); terminate; } @@ -199,37 +216,53 @@ int main(int argc, char *argv[]){ files[1].s += files[1].s == 0; /* Unbuffer files. */ - if(k){ - for(i = 0; - i < files[0].s; - setvbuf(files[0].files[i++], NULL, _IONBF, 0)); - for(i = 0; - i < files[1].s; - setvbuf(files[1].files[i++], NULL, _IONBF, 0)); + if (k) { + for ( + i = 0; i < files[0].s; setvbuf(files[0].files[i++], NULL, _IONBF, 0) + ); + for ( + i = 0; i < files[1].s; setvbuf(files[1].files[i++], NULL, _IONBF, 0) + ); } retval = EX_OK; /* Actual program loop. */ - for(i = 0; i < files[0].s; ++i) /* iterate ins */ - while((c = getc(files[0].files[i])) != EOF) /* iterate chars */ - for(j = 0; j < files[1].s; ++j) /* iterate outs */ - if(putc(c, files[1].files[j]) == EOF){ + for (i = 0; i < files[0].s; ++i) { /* iterate ins */ + while ((c = getc(files[0].files[i])) != EOF) { /* iterate chars */ + for (j = 0; j < files[1].s; ++j) { /* iterate outs */ + if (putc(c, files[1].files[j]) == EOF) { /* notebook's full */ retval = EX_IOERR; - fprintf(stderr, "%s: %s: %s\n", - program_name, files[1].names[j], strerror(errno)); - if(fclose(files[1].files[j]) == EOF) - fprintf(stderr, "%s: %s: %s\n", - program_name, files[1].names[j], strerror(errno)); + fprintf( + stderr, + "%s: %s: %s\n", + program_name, + files[1].names[j], + strerror(errno) + ); + + if (fclose(files[1].files[j]) == EOF) { + fprintf( + stderr, + "%s: %s: %s\n", + program_name, + files[1].names[j], + strerror(errno) + ); + } + /* massage out the tense muscle */ for(k = j--; k < files[1].s - 1; ++k){ files[1].files[k] = files[1].files[k+1]; files[1].names[k] = files[1].names[k+1]; } - if(--files[1].s == 0) - terminate; + + if(--files[1].s == 0) { terminate; } } + } + } + } terminate; } From e4e823a3092822358de0fbafaefe49924391ed82 Mon Sep 17 00:00:00 2001 From: emma Date: Sat, 13 Jul 2024 18:03:49 -0600 Subject: [PATCH 20/84] fop(1): adds more comments --- src/fop.rs | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/fop.rs b/src/fop.rs index 91c8a72..061815e 100644 --- a/src/fop.rs +++ b/src/fop.rs @@ -32,8 +32,8 @@ use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE }; fn main() { let argv = args().collect::>(); - let mut d = '\u{1E}'.to_string(); - let mut index_arg = 0; + let mut d = '\u{1E}'.to_string(); /* ASCII record separator */ + let mut optind = 0; let usage = format!( "Usage: {} [-d delimiter] index command [args...]", @@ -43,10 +43,9 @@ fn main() { while let Some(opt) = argv.getopt("d:") { match opt.opt() { Ok(_) => { - /* unwrap because Err(OptError::MissingArg) will be returned if - * opt.arg() is None */ + /* delimiter */ d = opt.arg().unwrap(); - index_arg = opt.ind(); + optind = opt.ind(); }, Err(_) => { eprintln!("{}", usage); @@ -55,38 +54,46 @@ fn main() { }; } - let command_arg = index_arg as usize + 1; + /* index of the argv[0] for the operator command */ + let command_arg = optind as usize + 1; - argv.get(command_arg).unwrap_or_else(|| { + /* argv[0] of the operator command */ + let operator = argv.get(command_arg).unwrap_or_else(|| { eprintln!("{}", usage); exit(EX_USAGE); }); - let index = argv[index_arg].parse::().unwrap_or_else(|e| { + /* parse the specified index as a number we can use */ + let index = argv[optind].parse::().unwrap_or_else(|e| { eprintln!("{}: {}: {}", argv[0], argv[1], e); exit(EX_DATAERR); }); let mut buf = String::new(); let _ = stdin().read_to_string(&mut buf); + + /* 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 .iter() .clone() - .skip(command_arg + 1) + .skip(command_arg + 1) /* skip the command name */ .collect::>(); - let mut spawned = Command::new(argv.get(command_arg).unwrap()) - .args(opts) + /* spawn the command to operate on the field */ + let mut spawned = Command::new(operator) + .args(opts) /* spawn with the specified arguments */ .stdin(Stdio::piped()) - .stdout(Stdio::piped()) + .stdout(Stdio::piped()) /* piped stdout to handle output ourselves */ .spawn() .unwrap_or_else( |e| { eprintln!("{}: {}: {}", argv[0], argv[command_arg], e.strerror()); exit(EX_UNAVAILABLE); }); + /* get field we want to pipe into spawned program */ let field = fields.get(index).unwrap_or_else(|| { eprintln!( "{}: {}: No such index in input", @@ -96,9 +103,10 @@ fn main() { exit(EX_DATAERR); }); + /* get the stdin of the newly spawned program and feed it the field val */ if let Some(mut child_stdin) = spawned.stdin.take() { let _ = child_stdin.write_all(field.as_bytes()); - drop(child_stdin); + drop(child_stdin); /* stay safe! drop your children! */ } let output = spawned.wait_with_output().unwrap_or_else(|e| { @@ -106,17 +114,22 @@ fn main() { exit(EX_IOERR); }); + /* 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; } + /* convert the output of the program to UTF-8 */ let new_field = String::from_utf8(replace).unwrap_or_else(|e| { eprintln!("{}: {}: {}", argv[0], argv[command_arg], e); exit(EX_IOERR); }); + /* store the new field in the old fields vector */ fields[index] = &new_field; + /* fop it */ stdout().write_all( fields.join(&d.to_string()).as_bytes() ).unwrap_or_else(|e| { From a9b388fe4b9101d8106064679cac6bfbe25a00c3 Mon Sep 17 00:00:00 2001 From: emma Date: Sat, 13 Jul 2024 18:18:32 -0600 Subject: [PATCH 21/84] hru(1): adds more descriptive comments --- src/hru.rs | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/hru.rs b/src/hru.rs index b7937f7..c02d4c1 100644 --- a/src/hru.rs +++ b/src/hru.rs @@ -29,40 +29,45 @@ extern crate sysexits; use strerror::StrError; use sysexits::{ EX_DATAERR, EX_IOERR, EX_SOFTWARE }; +/* list of SI prefixes */ const LIST: [(u32, &str); 10] = [ - (3, "k"), - (6, "M"), - (9, "G"), - (12, "T"), - (15, "P"), - (18, "E"), - (21, "Z"), - (24, "Y"), - (27, "R"), - (30, "Q") + (3, "k"), /* kilo */ + (6, "M"), /* mega */ + (9, "G"), /* giga */ + (12, "T"), /* tera */ + (15, "P"), /* peta */ + (18, "E"), /* exa */ + (21, "Z"), /* zetta */ + (24, "Y"), /* yotta */ + (27, "R"), /* ronna */ + (30, "Q"), /* quetta */ ]; fn convert(input: u128) -> Result<(f64, (u32, &'static str)), String> { + /* preserve decimal places in output by casting to a float */ + let mut out = (input as f64, (0_u32, "")); - let mut out = (input as f64, (0_u32, "")); - if input < 1000 { return Ok(out); } + if input < 1000 { return Ok(out); } /* too low to convert */ for (n, p) in LIST { let c = match 10_u128.checked_pow(n) { Some(c) => c, - None => { + None => { /* too big for the laws of computing :( */ return Err(format!("10^{}: Integer overflow", n.to_string())); }, }; match c.cmp(&input) { - Ordering::Less => { + Ordering::Less => { /* c < input */ + /* the program will keep assigning out every loop until either + * the list runs out of higher prefix bases or the input is + * greater than the prefix base */ out = (input as f64 / c as f64, (n, p)); }, - Ordering::Equal => { + Ordering::Equal => { /* c == input */ return Ok((input as f64 / c as f64, (n, p))); }, - Ordering::Greater => {}, + Ordering::Greater => {}, /* c > input */ }; } @@ -72,6 +77,7 @@ fn convert(input: u128) -> Result<(f64, (u32, &'static str)), String> { fn main() -> ExitCode { let argv = args().collect::>(); let mut buf = String::new(); + while let Ok(_) = stdin().read_line(&mut buf) { if buf.is_empty() { return ExitCode::SUCCESS; } @@ -96,6 +102,7 @@ fn main() -> ExitCode { let si_prefix = format!("{}B", prefix.1); + /* round output number to one decimal place */ let out = ((number * 10.0).round() / 10.0).to_string(); stdout().write_all(format!("{} {}\n", out, si_prefix).as_bytes()) From b0602388e7663b22e9472646366982984f723b7b Mon Sep 17 00:00:00 2001 From: emma Date: Sat, 13 Jul 2024 18:29:27 -0600 Subject: [PATCH 22/84] rpn(1): better comments --- src/rpn.rs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/rpn.rs b/src/rpn.rs index 2bfbbf5..784e323 100644 --- a/src/rpn.rs +++ b/src/rpn.rs @@ -57,7 +57,7 @@ extern crate sysexits; use sysexits::EX_DATAERR; #[derive(Clone, PartialEq, PartialOrd, Debug)] -// enum CalcType is a type containing operations used in the calculator +/* enum CalcType is a type containing operations used in the calculator */ enum CalcType { Add, Subtract, @@ -117,8 +117,8 @@ struct EvaluationError { code: i32, } -// I’m no math nerd but I want the highest possible approximation of 0.9 -// repeating and it seems this can give it to me +/* I’m no math nerd but I want the highest possible approximation of 0.9 + * repeating and it seems this can give it to me */ const PRECISION_MOD: f64 = 0.9 + f64::EPSILON * 100.0; fn eval( @@ -133,7 +133,7 @@ fn eval( return Ok((stack, oper)); } - // Split the input into tokens. + /* Split the input into tokens. */ let mut toks: VecDeque = input .split_whitespace() .rev() @@ -183,7 +183,7 @@ fn eval( Ok((stack, oper)) } -// Round a float to the given precision level +/* Round a float to the given precision level */ fn round_precise(value: &f64, precision: usize) -> f64 { let multiplier = 10_f64.powi(precision as i32); (value * multiplier).round() / multiplier @@ -193,11 +193,11 @@ fn main() -> ExitCode { let argv = args().collect::>(); let mut stack = VecDeque::new(); let mut buf = String::new(); - // Set floating-point precision for correcting rounding errors based on - // machine epsilon + /* Set floating-point precision for correcting rounding errors based on + * machine epsilon */ let precision = (-f64::EPSILON.log10() * PRECISION_MOD).ceil() as usize; - if argv.get(1).is_none() { + if argv.get(1).is_none() { /* read from stdin */ while let Ok(_) = stdin().read_line(&mut buf) { match eval(&buf.trim(), stack) { Ok(s) => { @@ -219,12 +219,13 @@ fn main() -> ExitCode { }, }; } - } else { + } else { /* read from argv */ + /* join argv into an owned String joined by spaces minus argv[0] */ let input = argv .iter() .skip(1) .map(|x| x.to_owned()) - .collect::>() + .collect::>() .join(" "); match eval(&input, stack) { @@ -233,7 +234,7 @@ fn main() -> ExitCode { let val = match stack.iter().last() { Some(v) => v, - None => return ExitCode::from(0), + None => return ExitCode::SUCCESS, }; println!("{}", round_precise(val, precision).to_string()) @@ -244,5 +245,5 @@ fn main() -> ExitCode { }, }; } - ExitCode::from(0) + ExitCode::SUCCESS } From 579bf3b622b161f6d0fd2e232bacd7044a1e5d5a Mon Sep 17 00:00:00 2001 From: emma Date: Sat, 13 Jul 2024 23:47:50 -0600 Subject: [PATCH 23/84] STYLE: initial commit --- STYLE | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 STYLE diff --git a/STYLE b/STYLE new file mode 100644 index 0000000..01940d9 --- /dev/null +++ b/STYLE @@ -0,0 +1,56 @@ +- Braces are mandatory for all control flow +- Indentation should be kept to a minimum +- Empty lines should be placed between different kinds of statements: + +int t; + +assert(io->bufuse > 0); +assert(io->bufuse <= io->bs); + +if ((t = write(io->fd, io->buf, io->bufuse)) < 0) { + io->error = errno; + t = 0; +} else if (t > 0) { + memmove(io->buf, &(io->buf)[t], (io->bufuse -= t)); +} + +io->bytes += t; +io->prec += (t > 0 && io->bufuse > 0); +io->rec += (t > 0 && io->bufuse == 0); + +return io; + +- Cases in switch statements and matches in match statements should be indented + one level +- In C, spaces should be placed in control flow statements after the keyword and + before the opening brace: + +for (i = 2; i < argc; ++i) { + +- If a function, a C control flow statement, or a Rust macro has arguments that + cause the statement to be broken into multiple lines, this should be done by + placing the arguments on a new line inside the parentheses: + +let usage = format!( + "Usage: {} [-d delimiter] index command [args...]", + argv[0], +); + +- If Rust function arguments or fields are on their own lines, they should + always have a trailing comma. + +- If text is on the same line as a brace, spaces should be placed after an + opening curly brace and before a closing one: + +use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE }; + +- 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); } + +-- +Copyright © 2024 Emma Tebibyte + +This work is licensed under CC BY-SA 4.0. To view a copy of this license, visit +. From b22ded9e98a68e56dae6efb878f2ad685bd95af2 Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 14 Jul 2024 02:15:07 -0600 Subject: [PATCH 24/84] STYLE: adds do while rule --- STYLE | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/STYLE b/STYLE index 01940d9..5560aa3 100644 --- a/STYLE +++ b/STYLE @@ -47,7 +47,12 @@ use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE }; - 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); } +if (!argc < 0) { usage(program_name); } + +- If a do while loop in C is longer than ~25 lines, place the while statement + in a comment after the opening brace: + +do { /* while(count == 0 || --count > 0); */ -- Copyright © 2024 Emma Tebibyte From aa074ad9b6d2feb74ad7e8baab76d24ca3f4a08f Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 14 Jul 2024 02:37:37 -0600 Subject: [PATCH 25/84] dj.1: fixes ambiguity in block size options --- docs/dj.1 | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/docs/dj.1 b/docs/dj.1 index d358e3f..1440ff4 100644 --- a/docs/dj.1 +++ b/docs/dj.1 @@ -4,7 +4,7 @@ .\" This work is licensed under CC BY-SA 4.0. To see a copy of this license, .\" visit . .\" -.TH DJ 1 2024-07-03 "Harakit X.X.X" +.TH DJ 1 2024-07-14 "Harakit X.X.X" .SH NAME dj \(en disk jockey .\" @@ -56,9 +56,9 @@ bytes read to this point are discarded. .IP \fB-o\fP Takes a file path as an argument and opens it for use as an output. .IP \fB-B\fP\ \fIblock_size\fP -Does the same as -.B -b -but for the output buffer. +Takes a numeric argument as the size in bytes of the output buffer, the default +being 1024. Note that this option only affects the size of output writes and not +the amount of output data itself. See the CAVEATS section. .IP \fB-S\fP Takes a numeric argument as the index of the byte at which writing will commence; \(lqseeks\(rq that number of bytes. If the standard output is used, @@ -68,8 +68,8 @@ Accepts a single literal byte with which the input buffer is padded in the event of an incomplete read from the input file. If the option argument is empty, the null byte is used. .IP \fB-c\fP -Specifies a number of reads to make. The default is 0, in which case the -input is read until a partial or empty read is made. +Specifies a number of blocks to read. The default is 0, in which case the input +is read until a partial or empty read is made. .IP \fB-H\fP Prints diagnostic messages in a human-readable manner as described in the DIAGNOSTICS section. @@ -181,15 +181,22 @@ option is specified, this could make written data nonsensical. Existing files are not truncated on ouput and are instead overwritten. -The options -.B -b -and +Option variants that have uppercase and lowercase forms could be confused for +each other. The former affects input and the latter affects output. + +The .B -B -could be confused for each other, and so could -.B -s +option could be mistaken for write size, meaning the count in bytes of data +placed in the output. This conception is intuitive but incorrect; the amount of +data read and output is controlled by the +.B -c and -.BR -S . -The lowercase option affects input and the capitalized option affects output. +.B -b +options. The latter sets the size of blocks to be read and the former sets the +number of blocks to be read. The +.B -B +option is similar to the latter but sets the size of blocks to be written, +regardless of the amount of data that will actually be written. The skipped or sought bytes while processing irregular files, such as streams, are reported in the diagnostic output, because they were actually read or From fe0c631d42aed6f8eb97351f0efcb24b4aa8678b Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 14 Jul 2024 02:41:59 -0600 Subject: [PATCH 26/84] dj.1: reverts change to hex literals --- src/dj.c | 2 +- src/npc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dj.c b/src/dj.c index b847b38..53adb61 100644 --- a/src/dj.c +++ b/src/dj.c @@ -219,7 +219,7 @@ int main(int argc, char *argv[]) { if (c == 'c' && (count = parse(optarg)) >= 0) { break; } i = (c >= 'A' && c <= 'Z'); - c |= 0b00100000; /* (ASCII) make lowercase */ + c |= 0x20 /* ASCII make lowercase 0b 0010 0000 */ if ( (c == 'b' && (io[i].bs = parse(optarg)) > 0) diff --git a/src/npc.c b/src/npc.c index 0892a72..d160523 100644 --- a/src/npc.c +++ b/src/npc.c @@ -51,7 +51,7 @@ int main(int argc, char *argv[]) { while ((c = getc(stdin)) != EOF) { if ((c & 0x80) != 0) { fputs("M-", stdout); } - switch (c ^ 0b10000000) { + switch (c ^ 0x80) { /* 0b 1000 0000 */ case 0x7f: fputs("^?", stdout); break; case '\n': if (showend) { putc('$', stdout); } default: From fd1ed79329c25563bc128de278d2e43c7979b929 Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 14 Jul 2024 02:43:01 -0600 Subject: [PATCH 27/84] dj(1): return top-of-scope variable --- src/dj.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dj.c b/src/dj.c index 53adb61..1dead90 100644 --- a/src/dj.c +++ b/src/dj.c @@ -282,13 +282,14 @@ int main(int argc, char *argv[]) { { /* read */ long skipping; + size_t t; /* hack to intentionally get a partial read from Io_read */ if ((skipping = MIN(io[0].seek, io[0].bs)) > 0) { io[0].bufuse = io[0].bs - (size_t)skipping; } - size_t t = io[0].bufuse; + t = io[0].bufuse; if (Io_read(&io[0])->bufuse == t && !noerror && io[0].error == 0) { Io_read(&io[0]); /* second chance */ } From 49031102f2b3cb36dc338487c039062ce84b5dd8 Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 14 Jul 2024 03:17:21 -0600 Subject: [PATCH 28/84] npc(1): commenting --- src/npc.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/npc.c b/src/npc.c index d160523..34fb9ce 100644 --- a/src/npc.c +++ b/src/npc.c @@ -30,11 +30,8 @@ int usage(char *s) { int main(int argc, char *argv[]) { int c; - char showend; - char showtab; - - showend = 0; - showtab = 0; + char showend = 0; /* print a dollar sign before each newline */ + char showtab = 0; /* prints tab characters in caret notation */ if (argc > 0) { while ((c = getopt(argc, argv, "et")) != -1) { @@ -52,7 +49,7 @@ int main(int argc, char *argv[]) { if ((c & 0x80) != 0) { fputs("M-", stdout); } switch (c ^ 0x80) { /* 0b 1000 0000 */ - case 0x7f: fputs("^?", stdout); break; + case 0x7f: fputs("^?", stdout); break; /* delete character */ case '\n': if (showend) { putc('$', stdout); } default: if (c >= ' ' || c == '\n' || (!showtab && c == '\t')) { From 3c243e4a09a55e7659f703b13a1c50f9ce82d5d9 Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 14 Jul 2024 03:20:15 -0600 Subject: [PATCH 29/84] str(1): formatting --- src/str.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/str.c b/src/str.c index b4725eb..73bb911 100644 --- a/src/str.c +++ b/src/str.c @@ -29,7 +29,7 @@ static char *program_name = "str"; static struct { char *name; int (*f)(int); -}ctypes[] = { +} ctypes[] = { { "isalnum", isalnum }, { "isalpha", isalpha }, { "isblank", isblank }, @@ -49,27 +49,33 @@ int main(int argc, char *argv[]){ int i; int r; - if(argc >= 3){ - for(ctype = 0; ctype < (sizeof ctypes) / (sizeof *ctypes); - ++ctype) - if(strcmp(argv[1], ctypes[ctype].name) == 0) + if (argc >= 3) { + for (ctype = 0; ctype < (sizeof ctypes) / (sizeof *ctypes); ++ctype) { + if(strcmp(argv[1], ctypes[ctype].name) == 0) { goto pass; + } + } } - fprintf(stderr, "Usage: %s type string...\n", - argv[0] == NULL ? program_name : argv[0]); + fprintf( + stderr, + "Usage: %s type string...\n", + argv[0] == NULL ? program_name : argv[0] + ); return EX_USAGE; -pass: for(argv += 2, r = 1; *argv != NULL; ++argv) - for(i = 0; argv[0][i] != '\0'; ++i) +pass: for (argv += 2, r = 1; *argv != NULL; ++argv) { + for (i = 0; argv[0][i] != '\0'; ++i) { /* First checks if argv[0][i] is valid ASCII; ctypes(3) * don't handle non-ASCII. * This is bad. */ - if((unsigned char)argv[0][i] < 0x80 && !ctypes[ctype].f(argv[0][i])) - return 1; - else - r = 0; + if( + (unsigned char)argv[0][i] < 0x80 && !ctypes[ctype].f(argv[0][i]) + ) { return 1; } + else { r = 0; } + } + } return r; } From ab003f7d4aff847bdf3f836331c58ecb663a859f Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 14 Jul 2024 03:25:52 -0600 Subject: [PATCH 30/84] strcmp(1): commenting --- src/strcmp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/strcmp.c b/src/strcmp.c index 4b6bf3c..c9d56b0 100644 --- a/src/strcmp.c +++ b/src/strcmp.c @@ -37,8 +37,10 @@ int main(int argc, char *argv[]) { for (; *argv[1] != '\0'; ++argv[1]) { for (i = 2; i < argc; ++i) { - if (*argv[i-1] > *argv[i]) { + /* a former string has a greater byte value */ + if (*argv[i-1] > *argv[i]) { return 1; + /* a latter string has a greater byte value */ } else if (*argv[i-1] < *argv[i]++) { return -1; /* actually 255 */ } From 789046f69457fb58560f4dbdca32ca5733b30fb1 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 15 Jul 2024 13:03:30 -0600 Subject: [PATCH 31/84] STYLE: removes do while constraint & reword indentation rule --- STYLE | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/STYLE b/STYLE index 5560aa3..5a236a0 100644 --- a/STYLE +++ b/STYLE @@ -1,5 +1,5 @@ - Braces are mandatory for all control flow -- Indentation should be kept to a minimum +- Nested indentation should be kept to a minimum - Empty lines should be placed between different kinds of statements: int t; @@ -49,11 +49,6 @@ use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE }; if (!argc < 0) { usage(program_name); } -- If a do while loop in C is longer than ~25 lines, place the while statement - in a comment after the opening brace: - -do { /* while(count == 0 || --count > 0); */ - -- Copyright © 2024 Emma Tebibyte From e9496cb4a5ff144566e1023af1baa25fb30cc13b Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 15 Jul 2024 13:04:23 -0600 Subject: [PATCH 32/84] dj.1: fixes ambiguity and false information --- docs/dj.1 | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/dj.1 b/docs/dj.1 index 1440ff4..a110166 100644 --- a/docs/dj.1 +++ b/docs/dj.1 @@ -181,22 +181,22 @@ option is specified, this could make written data nonsensical. Existing files are not truncated on ouput and are instead overwritten. -Option variants that have uppercase and lowercase forms could be confused for +Option variants that have lowercase and uppercase forms could be confused for each other. The former affects input and the latter affects output. The .B -B option could be mistaken for write size, meaning the count in bytes of data -placed in the output. This conception is intuitive but incorrect; the amount of -data read and output is controlled by the +placed in the output. This conception is intuitive but incorrect, as the .B -c -and +option controls the number of blocks to read and the .B -b -options. The latter sets the size of blocks to be read and the former sets the -number of blocks to be read. The +option sets the size of the blocks. The .B -B option is similar to the latter but sets the size of blocks to be written, -regardless of the amount of data that will actually be written. +regardless of the amount of data that will actually be written. In practice, +this means the input buffer should be very large to make use of modern hardware +input and output speeds. The skipped or sought bytes while processing irregular files, such as streams, are reported in the diagnostic output, because they were actually read or @@ -223,3 +223,4 @@ Copyright \(co 2023 DTB. License AGPLv3+: GNU AGPL version 3 or later .SH SEE ALSO .BR dd (1p) .BR lseek (3p) +.BR mm (1) From 71e98dbde72346f8bdbbbf62a01943bceb82a23c Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 15 Jul 2024 13:06:34 -0600 Subject: [PATCH 33/84] dj.1: fixes more ambiguity --- docs/dj.1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dj.1 b/docs/dj.1 index a110166..79096d5 100644 --- a/docs/dj.1 +++ b/docs/dj.1 @@ -186,8 +186,8 @@ each other. The former affects input and the latter affects output. The .B -B -option could be mistaken for write size, meaning the count in bytes of data -placed in the output. This conception is intuitive but incorrect, as the +option could be mistaken for the count in bytes of data written to the output. +This conception is intuitive but incorrect, as the .B -c option controls the number of blocks to read and the .B -b From c2e6744e2b242239150a43698735ce9798ffb158 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 15 Jul 2024 13:09:09 -0600 Subject: [PATCH 34/84] dj(1): revert changes to function return type formatting --- src/dj.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/dj.c b/src/dj.c index 1dead90..d1fae4c 100644 --- a/src/dj.c +++ b/src/dj.c @@ -66,7 +66,8 @@ static int write_flags = O_WRONLY | O_CREAT; /* Macro to check if fd is stdin or stdout */ #define fdisstd(fd) ((fd) == STDIN_FILENO || (fd) == STDOUT_FILENO) -static struct Io * Io_read(struct Io *io) { +static struct Io * +Io_read(struct Io *io) { int t; assert(io->bs > 0); @@ -87,7 +88,8 @@ static struct Io * Io_read(struct Io *io) { return io; } -static struct Io * Io_write(struct Io *io) { +static struct Io * +Io_write(struct Io *io) { int t; assert(io->bufuse > 0); @@ -107,14 +109,16 @@ static struct Io * Io_write(struct Io *io) { return io; } -static int oserr(char *e, int n) { +static int +oserr(char *e, int n) { fprintf(stderr, "%s: %s: %s\n", program_name, e, strerror(n)); return EX_OSERR; } /* Prints statistics regarding the use of dj, particularly partially and * completely read and written records. */ -static void fprintio(FILE *stream, char *fmt, struct Io io[2]) { +static void +fprintio(FILE *stream, char *fmt, struct Io io[2]) { fprintf( stream, fmt, @@ -132,7 +136,8 @@ static void fprintio(FILE *stream, char *fmt, struct Io io[2]) { /* Parses the string s to an integer, returning either the integer or in the * case of an error a negative integer. This is used for argument parsing * (e.g. -B [int]) in dj and no negative integer would be valid anyway. */ -static long parse(char *s){ +static long +parse(char *s) { long r; errno = 0; @@ -140,7 +145,8 @@ static long parse(char *s){ return (*s == '\0' && errno == 0) ? r : -1; /* no chars left unparsed */ } -static int usage(char *s){ +static int +usage(char *s) { fprintf( stderr, "Usage: %s [-Hn] [-a byte] [-c count]\n" "\t[-i file] [-b block_size] [-s offset]\n" From a3ceb845e370ba4471616735d50693cc153762f8 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 15 Jul 2024 13:16:05 -0600 Subject: [PATCH 35/84] dj(1): revert some formatting changes --- src/dj.c | 94 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/src/dj.c b/src/dj.c index d1fae4c..7a05e3e 100644 --- a/src/dj.c +++ b/src/dj.c @@ -142,7 +142,7 @@ parse(char *s) { errno = 0; r = strtol(s, &s, 0); - return (*s == '\0' && errno == 0) ? r : -1; /* no chars left unparsed */ + return (*s == '\0' /* no chars left unparsed */ && errno == 0) ? r : -1; } static int @@ -182,59 +182,59 @@ int main(int argc, char *argv[]) { io[i].seek = 0; } - if (!(argc < 0)) { usage(program_name); } + if (argc > 0) { + int c; - int c; + program_name = argv[0]; + while ((c = getopt(argc, argv, "a:b:B:c:i:hHns:S:o:")) != -1) { + switch (c) { + case 'i': case 'o': /* input, output */ + i = (c == 'o'); - program_name = argv[0]; - while ((c = getopt(argc, argv, "a:b:B:c:i:hHns:S:o:")) != -1) { - switch (c) { - case 'i': case 'o': /* input, output */ - i = (c == 'o'); + /* optarg == "-" (stdin/stdout) */ + if (optarg[0] == '-' && optarg[1] == '\0') { + io[i].fd = i == 0 ? STDIN_FILENO : STDOUT_FILENO; + io[i].fn = i == 0 ? stdin_name : stdout_name; + break; + } else { + int fd; - /* optarg == "-" (stdin/stdout) */ - if (optarg[0] == '-' && optarg[1] == '\0') { - io[i].fd = i == 0 ? STDIN_FILENO : STDOUT_FILENO; - io[i].fn = i == 0 ? stdin_name : stdout_name; - break; - } else { - int fd; + if ( + (fd = open(optarg, io[i].fl, creat_mode)) != -1 + && (fdisstd(io[i].fd) || close(io[i].fd) == 0) + ) { + io[i].fd = fd; + io[i].fn = optarg; + break; + } + } - if ( - (fd = open(optarg, io[i].fl, creat_mode)) != -1 - && (fdisstd(io[i].fd) || close(io[i].fd) == 0) - ) { - io[i].fd = fd; - io[i].fn = optarg; + return oserr(optarg, errno); /* break; */ + case 'n': noerror = 1; break; /* retry failed reads once */ + case 'H': fmt = fmt_human; break; /* human-readable output */ + case 'a': /* input buffer padding */ + if (optarg[0] == '\0' || optarg[1] == '\0') { + align = optarg[0]; break; } - } + /* FALLTHROUGH */ + case 'c': /* number of reads */ + case 'b': case 'B': /* input/output block size */ + case 's': case 'S': /* (s)kip/(S)eek in input/output */ + if (c == 'c' && (count = parse(optarg)) >= 0) { break; } - return oserr(optarg, errno); /* break; */ - case 'n': noerror = 1; break; /* retry failed reads once */ - case 'H': fmt = fmt_human; break; /* human-readable output */ - case 'a': /* input buffer padding */ - if (optarg[0] == '\0' || optarg[1] == '\0') { - align = optarg[0]; - break; - } - /* FALLTHROUGH */ - case 'c': /* number of reads */ - case 'b': case 'B': /* input/output block size */ - case 's': case 'S': /* (s)kip/(S)eek in input/output */ - if (c == 'c' && (count = parse(optarg)) >= 0) { break; } + i = (c >= 'A' && c <= 'Z'); + c |= 0x20; /* 0b 0010 0000 (ASCII make lowercase) */ - i = (c >= 'A' && c <= 'Z'); - c |= 0x20 /* ASCII make lowercase 0b 0010 0000 */ + if ( + (c == 'b' && (io[i].bs = parse(optarg)) > 0) + || (c == 's' && (io[i].seek = parse(optarg)) >= 0) + ) { break; } - if ( - (c == 'b' && (io[i].bs = parse(optarg)) > 0) - || (c == 's' && (io[i].seek = parse(optarg)) >= 0) - ) { break; } - - /* FALLTHROUGH */ - default: - return usage(program_name); + /* FALLTHROUGH */ + default: + return usage(program_name); + } } } @@ -272,7 +272,9 @@ int main(int argc, char *argv[]) { if (Io_write(&io[1])->bufuse == t && !noerror && io[1].error == 0) { Io_write(&io[1]); /* second chance */ } - if (io[1].error != 0) { return oserr(io[1].fn, io[1].error); } + if (io[1].error != 0) { + return oserr(io[1].fn, io[1].error); + } } while ((io[1].seek -= (t - io[1].bufuse)) > 0 && io[1].bufuse != t); io[1].bufuse = 0; From 7ff14214c3c983d815e7a4537fdc47bfa1ec58cd Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 15 Jul 2024 13:16:41 -0600 Subject: [PATCH 36/84] npc(1): move bit comment to be next to hex --- src/npc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/npc.c b/src/npc.c index 34fb9ce..5e00351 100644 --- a/src/npc.c +++ b/src/npc.c @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) { while ((c = getc(stdin)) != EOF) { if ((c & 0x80) != 0) { fputs("M-", stdout); } - switch (c ^ 0x80) { /* 0b 1000 0000 */ + switch (c ^ 0x80 /* 0b 1000 0000 */) { case 0x7f: fputs("^?", stdout); break; /* delete character */ case '\n': if (showend) { putc('$', stdout); } default: From dc2a4a39bad2e4ec9553cecf0ddbc5c62f85339d Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 15 Jul 2024 13:17:00 -0600 Subject: [PATCH 37/84] swab(1): note what sysexits are being used --- src/scrut.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scrut.c b/src/scrut.c index a0ee93d..74a96dc 100644 --- a/src/scrut.c +++ b/src/scrut.c @@ -20,7 +20,7 @@ #include /* fprintf(3), stderr, NULL */ #include /* EXIT_FAILURE, EXIT_SUCCESS */ #include /* memset(3), strchr(3) */ -#include +#include /* EX_USAGE */ #include /* access(3), getopt(3), F_OK, R_OK, W_OK, X_OK */ #include /* lstat(3), stat struct, S_ISBLK, S_ISCHR, S_ISDIR, * S_ISFIFO, S_ISGID, S_ISREG, S_ISLNK, S_ISSOCK, From a0ed14a089b6cb02dee790cca9e8357bdd4fa9e9 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 15 Jul 2024 13:29:12 -0600 Subject: [PATCH 38/84] STYLE: example for trailing comma & add includes guideline --- STYLE | 84 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/STYLE b/STYLE index 5a236a0..4344991 100644 --- a/STYLE +++ b/STYLE @@ -1,53 +1,65 @@ -- Braces are mandatory for all control flow -- Nested indentation should be kept to a minimum -- Empty lines should be placed between different kinds of statements: +0. Braces are mandatory for all control flow, as it improves the visibility of + scope. +1. Nested indentation should be kept to a minimum. +2. Empty lines should be placed between different kinds of statements: -int t; + int t; -assert(io->bufuse > 0); -assert(io->bufuse <= io->bs); + assert(io->bufuse > 0); + assert(io->bufuse <= io->bs); -if ((t = write(io->fd, io->buf, io->bufuse)) < 0) { - io->error = errno; - t = 0; -} else if (t > 0) { - memmove(io->buf, &(io->buf)[t], (io->bufuse -= t)); -} + if ((t = write(io->fd, io->buf, io->bufuse)) < 0) { + io->error = errno; + t = 0; + } else if (t > 0) { + memmove(io->buf, &(io->buf)[t], (io->bufuse -= t)); + } -io->bytes += t; -io->prec += (t > 0 && io->bufuse > 0); -io->rec += (t > 0 && io->bufuse == 0); + io->bytes += t; + io->prec += (t > 0 && io->bufuse > 0); + io->rec += (t > 0 && io->bufuse == 0); -return io; + return io; -- Cases in switch statements and matches in match statements should be indented - one level -- In C, spaces should be placed in control flow statements after the keyword and - before the opening brace: +3. Cases in switch statements and matches in match statements should be indented + one level +4. In C, spaces should be placed in control flow statements after the keyword + and before the opening brace: -for (i = 2; i < argc; ++i) { + for (i = 2; i < argc; ++i) { -- If a function, a C control flow statement, or a Rust macro has arguments that - cause the statement to be broken into multiple lines, this should be done by - placing the arguments on a new line inside the parentheses: +5. If a function, a C control flow statement, or a Rust macro has arguments that + cause the statement to be broken into multiple lines, this should be done by + placing the arguments on a new line inside the parentheses: -let usage = format!( - "Usage: {} [-d delimiter] index command [args...]", - argv[0], -); + let usage = format!( + "Usage: {} [-d delimiter] index command [args...]", + argv[0], + ); -- If Rust function arguments or fields are on their own lines, they should - always have a trailing comma. +6. If Rust function arguments or fields are on their own lines, they should + always have a trailing comma: -- If text is on the same line as a brace, spaces should be placed after an - opening curly brace and before a closing one: + return Err(EvaluationError { + message: format!("{}: Invalid token", i), + code: EX_DATAERR, + }) -use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE }; +7. If text is on the same line as a brace, spaces should be placed after an + opening curly brace and before a closing one: -- If a control flow statement is short enough to be easily understood in a - glance, it may be placed on a single line: + use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE }; -if (!argc < 0) { usage(program_name); } +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); } + +9. In C, note everything you use from a library in a comment subsequent to its + #include statement: + + #include /* close(2), getopt(3), lseek(2), read(2), write(2), + * optarg, optind, STDIN_FILENO, STDOUT_FILENO */ -- Copyright © 2024 Emma Tebibyte From 806ddac8da2079924987e2f579d54d3e656296bd Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 15 Jul 2024 13:31:38 -0600 Subject: [PATCH 39/84] dj(1): whitespace formatting --- src/dj.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dj.c b/src/dj.c index 7a05e3e..22772cb 100644 --- a/src/dj.c +++ b/src/dj.c @@ -36,8 +36,8 @@ char *program_name = "dj"; * writing ends of its jockeyed "pipe". User-configurable members are noted * with their relevant options. */ struct Io { - char *buf; /* buffer */ - char *fn; /* file name (-io) */ + char *buf; /* buffer */ + char *fn; /* file name (-io) */ size_t bs; /* buffer size (-bB) */ size_t bufuse; /* buffer usage */ size_t bytes; /* bytes processed */ @@ -45,8 +45,8 @@ struct Io { size_t rec; /* records processed */ long seek; /* remaining bytes to seek/skip (-sS) */ int error; /* errno */ - int fd; /* file descriptor */ - int fl; /* file opening flags */ + int fd; /* file descriptor */ + int fl; /* file opening flags */ }; /* To be assigned to main:fmt and used with printio(). */ From fbdf4f9c45afb3dd6064d97105ebf3fa4afb6181 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 15 Jul 2024 13:38:08 -0600 Subject: [PATCH 40/84] intcmp(1): switch formatting --- src/intcmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/intcmp.c b/src/intcmp.c index 132c230..41a1592 100644 --- a/src/intcmp.c +++ b/src/intcmp.c @@ -50,7 +50,7 @@ int main(int argc, char *argv[]) { if (argc == 0 | argc < 3) { return usage(s); } while ((c = getopt(argc, argv, "egl")) != -1) { - switch (c){ + switch (c) { case 'e': mode |= EQUAL; break; case 'g': mode |= GREATER; break; case 'l': mode |= LESSER; break; From 9f2447ce94550fae406d5755464526f6e5f4de37 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 15 Jul 2024 13:38:26 -0600 Subject: [PATCH 41/84] STYLE: code block indentation edits and example --- STYLE | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/STYLE b/STYLE index 4344991..23cd0c5 100644 --- a/STYLE +++ b/STYLE @@ -21,8 +21,16 @@ return io; -3. Cases in switch statements and matches in match statements should be indented - one level +3. Each block of code should be indented once more than the keyword which + initiated the block: + + switch (c) { + case 'e': mode |= EQUAL; break; + case 'g': mode |= GREATER; break; + case 'l': mode |= LESS; break; + default: return usage(s); + } + 4. In C, spaces should be placed in control flow statements after the keyword and before the opening brace: From 3ba6682ab3af10cf2c1e00a7e4f766f24abe4db7 Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 19 Jul 2024 16:41:02 -0600 Subject: [PATCH 42/84] STYLE: extern and use statements rules --- STYLE | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/STYLE b/STYLE index 23cd0c5..4c03953 100644 --- a/STYLE +++ b/STYLE @@ -1,6 +1,8 @@ 0. Braces are mandatory for all control flow, as it improves the visibility of - scope. +scope. + 1. Nested indentation should be kept to a minimum. + 2. Empty lines should be placed between different kinds of statements: int t; @@ -22,7 +24,7 @@ return io; 3. Each block of code should be indented once more than the keyword which - initiated the block: +initiated the block: switch (c) { case 'e': mode |= EQUAL; break; @@ -32,13 +34,13 @@ } 4. In C, spaces should be placed in control flow statements after the keyword - and before the opening brace: +and before the opening brace: for (i = 2; i < argc; ++i) { 5. If a function, a C control flow statement, or a Rust macro has arguments that - cause the statement to be broken into multiple lines, this should be done by - placing the arguments on a new line inside the parentheses: +cause the statement to be broken into multiple lines, this should be done by +placing the arguments on a new line inside the parentheses: let usage = format!( "Usage: {} [-d delimiter] index command [args...]", @@ -46,7 +48,7 @@ ); 6. If Rust function arguments or fields are on their own lines, they should - always have a trailing comma: +always have a trailing comma: return Err(EvaluationError { message: format!("{}: Invalid token", i), @@ -54,21 +56,32 @@ }) 7. If text is on the same line as a brace, spaces should be placed after an - opening curly brace and before a closing one: +opening curly brace and before a closing one: use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE }; 8. If a control flow statement is short enough to be easily understood in a - glance, it may be placed on a single line: +glance, it may be placed on a single line: if (!argc < 0) { usage(program_name); } 9. In C, note everything you use from a library in a comment subsequent to its - #include statement: +#include statement: #include /* close(2), getopt(3), lseek(2), read(2), write(2), * optarg, optind, STDIN_FILENO, STDOUT_FILENO */ +10. In Rust, place extern statements after use statements that include standard +library crates. Group alike statements: + + use std::fs::Path; + + extern crate strerror; + extern crate sysexits; + + use strerror::StrError; + use sysexits::{ EX_OSERR, EX_USAGE }; + -- Copyright © 2024 Emma Tebibyte From 22bb26b9cbc74b699399e1b5ed27474060add5e1 Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 19 Jul 2024 17:04:49 -0600 Subject: [PATCH 43/84] STYLE: added introduction statement --- STYLE | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/STYLE b/STYLE index 4c03953..e59b6fd 100644 --- a/STYLE +++ b/STYLE @@ -1,5 +1,7 @@ -0. Braces are mandatory for all control flow, as it improves the visibility of -scope. +The following guidelines are conducive to clear and readable code that is +consistent with the style of the rest of the Bonsai Computer System. + +0. Braces are mandatory for all control flow. 1. Nested indentation should be kept to a minimum. From f7ebe7cf573aaedf813fb2f7aa50f8ccd3c64c0d Mon Sep 17 00:00:00 2001 From: emma Date: Fri, 19 Jul 2024 17:31:51 -0600 Subject: [PATCH 44/84] STYLE: added 10 rules reference --- STYLE | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/STYLE b/STYLE index e59b6fd..4e35af6 100644 --- a/STYLE +++ b/STYLE @@ -84,8 +84,33 @@ library crates. Group alike statements: use strerror::StrError; use sysexits::{ EX_OSERR, EX_USAGE }; +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]: + 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. + 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. + 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. + + +References +========== + +[0] + -- Copyright © 2024 Emma Tebibyte +Copyright © Wikipedia contributors This work is licensed under CC BY-SA 4.0. To view a copy of this license, visit . From a01cea572daf71b08624824941b561723967bf80 Mon Sep 17 00:00:00 2001 From: DTB Date: Fri, 19 Jul 2024 18:26:59 -0600 Subject: [PATCH 45/84] dj(1): replace do/while on hard seeking --- src/dj.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/dj.c b/src/dj.c index 22772cb..4af59ff 100644 --- a/src/dj.c +++ b/src/dj.c @@ -259,28 +259,27 @@ int main(int argc, char *argv[]) { } } - /* hard seeking */ - if (io[1].seek > 0) { - size_t t; + assert(io[1].bufuse == 0); /* requirement for hard seeking */ - do { - memset( - io[1].buf, '\0', - (t = io[1].bufuse = MIN(io[1].bs, io[1].seek)) - ); + /* hard seeking; t is io[1].bufuse, before Io_write subtracts from it */ + for(size_t t; io[1].seek > 0; io[1].seek -= (t - io[1].bufuse)) { + memset( + io[1].buf, '\0', /* set buf to all nulls */ + (t = io[1].bufuse = MIN(io[1].bs, io[1].seek)) /* saturate block */ + ); - if (Io_write(&io[1])->bufuse == t && !noerror && io[1].error == 0) { - Io_write(&io[1]); /* second chance */ - } - if (io[1].error != 0) { - return oserr(io[1].fn, io[1].error); - } - } while ((io[1].seek -= (t - io[1].bufuse)) > 0 && io[1].bufuse != t); + if (Io_write(&io[1])->bufuse == t && !noerror && io[1].error == 0) { + Io_write(&io[1]); /* second chance */ + } - io[1].bufuse = 0; + if (io[1].error != 0) { return oserr(io[1].fn, io[1].error); } + + if (io[1].bufuse == t) { break; } /* all writes failed! */ } - if (io[1].seek > 0) { + io[1].bufuse = 0; + + if (io[1].seek > 0) { /* hard seeking failed */ fprintio(stderr, fmt, io); return oserr(io[1].fn, errno); } From 71f4a411b69356772ee90466586670f4c194b6c7 Mon Sep 17 00:00:00 2001 From: DTB Date: Fri, 19 Jul 2024 18:40:24 -0600 Subject: [PATCH 46/84] dj(1): replace do/while in write loop --- src/dj.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/dj.c b/src/dj.c index 4af59ff..593ae31 100644 --- a/src/dj.c +++ b/src/dj.c @@ -157,7 +157,7 @@ usage(char *s) { } int main(int argc, char *argv[]) { - int align; /* low 8b used, negative if no alignment is being done */ + int align; /* low 8b used, negative if no alignment is being done */ int count; /* 0 if dj(1) runs until no more reads are possible */ char *fmt; /* == fmt_asv (default) or fmt_human (-H) */ size_t i; /* side of io being modified */ @@ -331,21 +331,20 @@ int main(int argc, char *argv[]) { } } - /* write */ - do { /* while(io[0].bufuse > 0); */ - int t; + assert(io[0].bufuse > 0); + while (io[0].bufuse > 0) { /* write */ if (io[0].bs <= io[1].bs) { int n; - /* saturate obuf */ - memcpy( + memcpy( /* saturate obuf */ io[1].buf, io[0].buf, (io[1].bufuse = (n = MIN(io[0].bufuse, io[1].bs))) ); + /* permute the copied units out of ibuf */ memmove(io[0].buf, &(io[0].buf)[n], (io[0].bufuse -= n)); - } else /* if(io[0].bs < io[1].bs) */ { + } else /* if(io[0].bs > io[1].bs) */ { int n; /* drain what we can from ibuf */ @@ -353,12 +352,10 @@ int main(int argc, char *argv[]) { &(io[1].buf)[io[1].bufuse], io[0].buf, (n = MIN(io[0].bufuse, io[1].bs - io[1].bufuse)) ); - io[1].bufuse += n; /* permute out the copied units */ memmove(io[0].buf, &(io[0].buf)[n], io[0].bs - n); - io[0].bufuse -= n; if(io[0].bs + io[1].bufuse <= io[1].bs && count != 1) { @@ -366,16 +363,27 @@ int main(int argc, char *argv[]) { } } - t = io[1].bufuse; - if (Io_write(&io[1])->bufuse == t && !noerror && io[1].error == 0) { - Io_write(&io[1]); /* second chance */ - } + { /* writes actually happen, or die */ + size_t t; - assert(io[1].bufuse <= t); + t = io[1].bufuse; + if (Io_write(&io[1])->bufuse == t + && !noerror + && io[1].error == 0) { + Io_write(&io[1]); /* second chance */ + } - if (io[1].bufuse == t) { /* no more love */ - count = 1; - break; + assert(io[1].error == 0 || io[1].bufuse == t); + /* if the Io_writes errored, bufuse wouldn't have changed, and + * the error will be reported at the end of the read/write + * loop */ + + assert(io[1].bufuse <= t); + + if (io[1].bufuse == t) { /* no more love */ + count = 1; + break; + } } if (0 < io[1].bufuse /* && io[1].bufuse < t */) { @@ -384,7 +392,7 @@ int main(int argc, char *argv[]) { if(!noerror) { count = 1; } } - } while(io[0].bufuse > 0); + } } while(count == 0 || --count > 0); fprintio(stderr, fmt, io); From c8b4f7a8b3bf4e39b1ce3e45302ab1f6994d29a2 Mon Sep 17 00:00:00 2001 From: DTB Date: Fri, 19 Jul 2024 19:03:23 -0600 Subject: [PATCH 47/84] str(1): edit out goto --- src/str.c | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/str.c b/src/str.c index 73bb911..d6a89c3 100644 --- a/src/str.c +++ b/src/str.c @@ -20,11 +20,11 @@ #include #include /* NULL */ #include /* fprintf(3) */ -#include /* EXIT_FAILURE */ +#include /* size_t, EXIT_FAILURE */ #include /* strcmp(3) */ -#include +#include /* EX_USAGE */ -static char *program_name = "str"; +char *program_name = "str"; static struct { char *name; @@ -41,41 +41,41 @@ static struct { { "isprint", isprint }, { "ispunct", ispunct }, { "isspace", isspace }, - { "isupper", isupper } + { "isupper", isupper }, + { NULL, NULL } /* marks end */ }; +int usage(char *s){ + fprintf(stderr, "Usage: %s type string...\n", s); + return EX_USAGE; +} + int main(int argc, char *argv[]){ - int ctype; - int i; - int r; + size_t ctype; /* selected from ctypes.h; index of ctype */ + int retval; - if (argc >= 3) { - for (ctype = 0; ctype < (sizeof ctypes) / (sizeof *ctypes); ++ctype) { - if(strcmp(argv[1], ctypes[ctype].name) == 0) { - goto pass; - } - } - } + if (argc < 3) { return usage(argv[0] == NULL ? program_name : argv[0]); } - fprintf( - stderr, - "Usage: %s type string...\n", - argv[0] == NULL ? program_name : argv[0] + for ( /* iterate ctypes */ + ctype = 0; + ctypes[ctype].f != NULL /* break at the end of ctypes */ + && strcmp(argv[1], ctypes[ctype].name) != 0; /* break at match */ + ++ctype ); - return EX_USAGE; + if (ctypes[ctype].f == NULL) { return usage(argv[0]); } -pass: for (argv += 2, r = 1; *argv != NULL; ++argv) { - for (i = 0; argv[0][i] != '\0'; ++i) { - /* First checks if argv[0][i] is valid ASCII; ctypes(3) - * don't handle non-ASCII. - * This is bad. */ + /* iterate args */ + for (argv += 2, retval = EXIT_FAILURE; *argv != NULL; ++argv) { + for (size_t i = 0; argv[0][i] != '\0'; ++i) { /* iterate arg bytes */ + /* First checks if argv[0][i] is valid ASCII; ctypes(3) don't + * handle non-ASCII. This is bad. */ if( (unsigned char)argv[0][i] < 0x80 && !ctypes[ctype].f(argv[0][i]) - ) { return 1; } - else { r = 0; } + ) { return EXIT_FAILURE; } + else { retval = EXIT_SUCCESS; } } } - return r; + return retval; } From 9086bf0d08ddc582273a516510ff7cf962a8d867 Mon Sep 17 00:00:00 2001 From: DTB Date: Fri, 19 Jul 2024 19:18:04 -0600 Subject: [PATCH 48/84] dj(1): remove do/while statement in read loop --- src/dj.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/dj.c b/src/dj.c index 593ae31..2301eb4 100644 --- a/src/dj.c +++ b/src/dj.c @@ -158,7 +158,7 @@ usage(char *s) { int main(int argc, char *argv[]) { int align; /* low 8b used, negative if no alignment is being done */ - int count; /* 0 if dj(1) runs until no more reads are possible */ + int count; /* -1 if dj(1) runs until no more reads are possible */ char *fmt; /* == fmt_asv (default) or fmt_human (-H) */ size_t i; /* side of io being modified */ char noerror; /* 0=exits (default) 1=retries on partial reads or writes */ @@ -166,7 +166,7 @@ int main(int argc, char *argv[]) { /* Set defaults. */ align = -1; - count = 0; + count = -1; fmt = fmt_asv; noerror = 0; for (i = 0; i < (sizeof io) / (sizeof *io); ++i) { @@ -284,7 +284,10 @@ int main(int argc, char *argv[]) { return oserr(io[1].fn, errno); } - do { /* while(count == 0 || --count > 0); */ + for ( ; + count == -1 || count > 0; + count -= (count != -1) /* decrement if counting */ + ) { assert(io[0].bufuse == 0); { /* read */ @@ -303,7 +306,7 @@ int main(int argc, char *argv[]) { assert(io[0].bufuse >= t); - if (io[0].bufuse == t) /* that's all she wrote */ { break; } + if (io[0].bufuse == t) { break; } /* that's all she wrote */ if (/* t < io[0].bufuse && */ io[0].bufuse < io[0].bs) { fprintf(stderr, "%s: Partial read:\n\t", program_name); @@ -326,7 +329,7 @@ int main(int argc, char *argv[]) { if (skipping > 0) { io[0].seek -= skipping; io[0].bufuse = 0; - count += (count != 0); + count += (count != -1); /* increment if counting */ continue; } } @@ -393,7 +396,7 @@ int main(int argc, char *argv[]) { if(!noerror) { count = 1; } } } - } while(count == 0 || --count > 0); + } fprintio(stderr, fmt, io); From 19eee6b4e569d8fd81617fc02012e739e5d45e0b Mon Sep 17 00:00:00 2001 From: DTB Date: Fri, 19 Jul 2024 19:31:34 -0600 Subject: [PATCH 49/84] scrut(1): replace do/while loop --- src/scrut.c | 100 ++++++++++++++++++++-------------------------------- 1 file changed, 39 insertions(+), 61 deletions(-) diff --git a/src/scrut.c b/src/scrut.c index 74a96dc..cb84f33 100644 --- a/src/scrut.c +++ b/src/scrut.c @@ -26,87 +26,65 @@ * S_ISFIFO, S_ISGID, S_ISREG, S_ISLNK, S_ISSOCK, * S_ISUID, S_ISVTX */ -static char args[] = "bcdefghkprsuwxLS"; -static char ops[(sizeof args) / (sizeof *args)]; -static char *program_name = "scrut"; +char *program_name = "scrut"; +static char args[] = "bcdefgkprsuwxLS"; int usage(char *s) { - fprintf( - stderr, - "Usage: %s [-%s] file...\n", - s == NULL ? program_name : s, args - ); - + fprintf(stderr, "Usage: %s [-%s] file...\n", s, args); return EX_USAGE; } int main(int argc, char *argv[]) { - struct stat buf; - int c; - size_t i; - char *p; + char sel[(sizeof args) / (sizeof *args)]; - if (argc < 2) { return usage(argv[0]); } + if (argc < 2) { return usage(argv[0] == NULL ? program_name : argv[0]); } - memset(ops, '\0', sizeof ops); - while ((c = getopt(argc, argv, args)) != -1) { - if ((p = strchr(args, c)) == NULL) { - return usage(argv[0]); - } else { - ops[p - args] = c; + { /* option parsing */ + char *p; + + memset(sel, '\0', sizeof sel); + for (int c; (c = getopt(argc, argv, args)) != -1;) { + if ((p = strchr(args, c)) == NULL) { return usage(argv[0]); } + else { sel[p - args] = c; } } - } - /* straighten out ops */ - for (i = 0, p = ops; i < (sizeof ops) / (sizeof *ops); ++i) { - if (ops[i] != '\0') { - *p = ops[i]; - if (&ops[i] != p++) { ops[i] = '\0'; } + /* straighten out selections */ + for (size_t i = 0, p = sel; i < (sizeof sel) / (sizeof *sel); ++i) { + if (sel[i] != '\0') { + *p = sel[i]; + if (&sel[i] != p++) { sel[i] = '\0'; } + } } } if (optind == argc) { return usage(argv[0]); } - argv += optind; - do { /* while(*++argv != NULL); */ + for (argv += optind ; *argv != NULL; ++argv) { + struct stat buf; + if(access(*argv, F_OK) != 0 || lstat(*argv, &buf) == -1) { return EXIT_FAILURE; /* doesn't exist or isn't stattable */ } - for (i = 0; ops[i] != '\0'; ++i) - if (ops[i] == 'e') { - continue; - } else if (ops[i] == 'h') { - return usage(argv[0]); - } else if ( - (ops[i] == 'b' - && !S_ISBLK(buf.st_mode)) - || (ops[i] == 'c' - && !S_ISCHR(buf.st_mode)) - || (ops[i] == 'd' - && !S_ISDIR(buf.st_mode)) - || (ops[i] == 'f' - && !S_ISREG(buf.st_mode)) - || (ops[i] == 'g' - && !(buf.st_mode & S_ISGID)) - || (ops[i] == 'k' - && !(buf.st_mode & S_ISVTX)) - || (ops[i] == 'p' - && !S_ISFIFO(buf.st_mode)) - || (ops[i] == 'r' - && access(*argv, R_OK) != 0) - || (ops[i] == 'u' - && !(buf.st_mode & S_ISUID)) - || (ops[i] == 'w' - && access(*argv, W_OK) != 0) - || (ops[i] == 'x' - && access(*argv, X_OK) != 0) - || (ops[i] == 'L' - && !S_ISLNK(buf.st_mode)) - || (ops[i] == 'S' - && !S_ISSOCK(buf.st_mode)) + for (size_t i = 0; sel[i] != '\0'; ++i) { + if ( + (sel[i] == 'b' && !S_ISBLK(buf.st_mode)) + || (sel[i] == 'c' && !S_ISCHR(buf.st_mode)) + || (sel[i] == 'd' && !S_ISDIR(buf.st_mode)) + || (sel[i] == 'e' && 0) + || (sel[i] == 'f' && !S_ISREG(buf.st_mode)) + || (sel[i] == 'g' && !(buf.st_mode & S_ISGID)) + || (sel[i] == 'k' && !(buf.st_mode & S_ISVTX)) + || (sel[i] == 'p' && !S_ISFIFO(buf.st_mode)) + || (sel[i] == 'r' && access(*argv, R_OK) != 0) + || (sel[i] == 'u' && !(buf.st_mode & S_ISUID)) + || (sel[i] == 'w' && access(*argv, W_OK) != 0) + || (sel[i] == 'x' && access(*argv, X_OK) != 0) + || (sel[i] == 'L' && !S_ISLNK(buf.st_mode)) + || (sel[i] == 'S' && !S_ISSOCK(buf.st_mode)) ) { return EXIT_FAILURE; } - } while(*++argv != NULL); + } + } return EXIT_SUCCESS; } From f96ed9c1f3f0d80d6277bdf6d9c143704fd0fe39 Mon Sep 17 00:00:00 2001 From: DTB Date: Fri, 19 Jul 2024 19:34:37 -0600 Subject: [PATCH 50/84] scrut(1): fix syntax error --- src/scrut.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/scrut.c b/src/scrut.c index cb84f33..5e41def 100644 --- a/src/scrut.c +++ b/src/scrut.c @@ -48,8 +48,9 @@ int main(int argc, char *argv[]) { else { sel[p - args] = c; } } - /* straighten out selections */ - for (size_t i = 0, p = sel; i < (sizeof sel) / (sizeof *sel); ++i) { + /* straighten out selections; permute out nulls */ + p = sel; + for (size_t i = 0; i < (sizeof sel) / (sizeof *sel); ++i) { if (sel[i] != '\0') { *p = sel[i]; if (&sel[i] != p++) { sel[i] = '\0'; } From 0282b60e650305182ab13448e58284da5067fb6c Mon Sep 17 00:00:00 2001 From: emma Date: Sat, 20 Jul 2024 07:18:59 -0600 Subject: [PATCH 51/84] dj(1), mm(1), npc(1), scrut(1), str(1): consistent argv[0] handling --- src/dj.c | 9 +++++---- src/mm.c | 17 +++++++++-------- src/npc.c | 7 +++++-- src/scrut.c | 7 ++++--- src/str.c | 11 ++++++----- 5 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/dj.c b/src/dj.c index 2301eb4..894feba 100644 --- a/src/dj.c +++ b/src/dj.c @@ -30,7 +30,7 @@ extern int errno; -char *program_name = "dj"; +static char *program_name = "dj"; /* dj uses two structures that respectively correspond to the reading and * writing ends of its jockeyed "pipe". User-configurable members are noted @@ -150,7 +150,7 @@ usage(char *s) { fprintf( stderr, "Usage: %s [-Hn] [-a byte] [-c count]\n" "\t[-i file] [-b block_size] [-s offset]\n" - "\t[-o file] [-B block_size] [-S offset]\n", program_name + "\t[-o file] [-B block_size] [-S offset]\n", s ); return EX_USAGE; @@ -163,6 +163,7 @@ 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 } */]; + char *s = (argv[0] == NULL ? program_name : argv[0]); /* Set defaults. */ align = -1; @@ -233,7 +234,7 @@ int main(int argc, char *argv[]) { /* FALLTHROUGH */ default: - return usage(program_name); + return usage(s); } } } @@ -241,7 +242,7 @@ int main(int argc, char *argv[]) { assert(io->fd != STDIN_FILENO || io->fl == read_flags); assert(io->fd != STDOUT_FILENO || io->fl == write_flags); - if (argc > optind) { return usage(program_name); } + if (argc > optind) { return usage(s); } for (i = 0; i < (sizeof io) / (sizeof *io); ++i) { /* buffer allocation */ diff --git a/src/mm.c b/src/mm.c index 0aced76..459d3b3 100644 --- a/src/mm.c +++ b/src/mm.c @@ -48,7 +48,7 @@ struct Files{ #endif /* pre-allocated strings */ -static char *program_name = ""; +static char *program_name = "mm"; static char *stdin_name = ""; static char *stdout_name = ""; static char *stderr_name = ""; @@ -125,6 +125,7 @@ int main(int argc, char *argv[]) { size_t j; size_t k; /* loop index but also unbuffer status */ int retval; + char *s = argv[0] == NULL ? program_name : argv[0]; /* Initializes the files structs with their default values, standard * input and standard output. If an input or an output is specified @@ -149,7 +150,7 @@ int main(int argc, char *argv[]) { k = 0; - if (argc > 0) { program_name = argv[0]; } + if (argc > 0) { program_name = s; } if (argc > 1) { while ((c = getopt(argc, argv, "aehi:no:u")) != -1) { @@ -163,7 +164,7 @@ int main(int argc, char *argv[]) { break; } - retval = oserr(argv[0], "-e"); + retval = oserr(s, "-e"); terminate; case 'i': if ( @@ -172,7 +173,7 @@ int main(int argc, char *argv[]) { || Files_open(&files[0], optarg) != NULL ) { break; } - retval = oserr(argv[0], optarg); + retval = oserr(s, optarg); terminate; case 'o': if ( @@ -190,25 +191,25 @@ int main(int argc, char *argv[]) { } } - retval = oserr(argv[0], optarg); + retval = oserr(s, optarg); terminate; case 'n': if (signal(SIGINT, SIG_IGN) != SIG_ERR) { break; } - retval = oserr(argv[0], "-n"); + retval = oserr(s, "-n"); terminate; case 'u': k = 1; break; default: - retval = usage(argv[0]); + retval = usage(s); terminate; } } } if (optind != argc) { - retval = usage(argv[0]); + retval = usage(s); terminate; } diff --git a/src/npc.c b/src/npc.c index 5e00351..0767163 100644 --- a/src/npc.c +++ b/src/npc.c @@ -23,6 +23,8 @@ #include /* getopt(3) */ #include /* EX_OK, EX_USAGE */ +static char *program_name = "dj"; + int usage(char *s) { fprintf(stderr, "Usage: %s [-et]\n", s); return EX_USAGE; @@ -32,18 +34,19 @@ int main(int argc, char *argv[]) { int c; char showend = 0; /* print a dollar sign before each newline */ char showtab = 0; /* prints tab characters in caret notation */ + char *s = (argv[0] == NULL ? program_name : argv[0]); if (argc > 0) { while ((c = getopt(argc, argv, "et")) != -1) { switch (c){ case 'e': showend = 1; break; case 't': showtab = 1; break; - default: return usage(argv[0]); + default: return usage(s); } } } - if (argc > optind) { return usage(argv[0]); } + if (argc > optind) { return usage(s); } while ((c = getc(stdin)) != EOF) { if ((c & 0x80) != 0) { fputs("M-", stdout); } diff --git a/src/scrut.c b/src/scrut.c index 5e41def..ad2ed92 100644 --- a/src/scrut.c +++ b/src/scrut.c @@ -26,7 +26,7 @@ * S_ISFIFO, S_ISGID, S_ISREG, S_ISLNK, S_ISSOCK, * S_ISUID, S_ISVTX */ -char *program_name = "scrut"; +static char *program_name = "scrut"; static char args[] = "bcdefgkprsuwxLS"; int usage(char *s) { @@ -36,15 +36,16 @@ int usage(char *s) { int main(int argc, char *argv[]) { char sel[(sizeof args) / (sizeof *args)]; + char *s = (argv[0] == NULL ? program_name : argv[0]); - if (argc < 2) { return usage(argv[0] == NULL ? program_name : argv[0]); } + if (argc < 2) { return usage(s); } { /* option parsing */ char *p; memset(sel, '\0', sizeof sel); for (int c; (c = getopt(argc, argv, args)) != -1;) { - if ((p = strchr(args, c)) == NULL) { return usage(argv[0]); } + if ((p = strchr(args, c)) == NULL) { return usage(s); } else { sel[p - args] = c; } } diff --git a/src/str.c b/src/str.c index d6a89c3..646e4c7 100644 --- a/src/str.c +++ b/src/str.c @@ -53,8 +53,9 @@ int usage(char *s){ int main(int argc, char *argv[]){ size_t ctype; /* selected from ctypes.h; index of ctype */ int retval; + char *s = (argv[0] == NULL ? program_name : argv[0]); - if (argc < 3) { return usage(argv[0] == NULL ? program_name : argv[0]); } + if (argc < 3) { return usage(s); } for ( /* iterate ctypes */ ctype = 0; @@ -63,15 +64,15 @@ int main(int argc, char *argv[]){ ++ctype ); - if (ctypes[ctype].f == NULL) { return usage(argv[0]); } + if (ctypes[ctype].f == NULL) { return usage(s); } /* iterate args */ for (argv += 2, retval = EXIT_FAILURE; *argv != NULL; ++argv) { - for (size_t i = 0; argv[0][i] != '\0'; ++i) { /* iterate arg bytes */ - /* First checks if argv[0][i] is valid ASCII; ctypes(3) don't + for (size_t i = 0; s[i] != '\0'; ++i) { /* iterate arg bytes */ + /* First checks if s[i] is valid ASCII; ctypes(3) don't * handle non-ASCII. This is bad. */ if( - (unsigned char)argv[0][i] < 0x80 && !ctypes[ctype].f(argv[0][i]) + (unsigned char)s[i] < 0x80 && !ctypes[ctype].f(s[i]) ) { return EXIT_FAILURE; } else { retval = EXIT_SUCCESS; } } From 2fe3aa894c02b8cba4b9dd40a263c52bb94b45b4 Mon Sep 17 00:00:00 2001 From: emma Date: Wed, 24 Jul 2024 19:37:07 -0600 Subject: [PATCH 52/84] dj(1), intcmp(1), mm(1), npc(1), scrut(1), strcmp(1): changes to use and modify program_name --- src/dj.c | 8 ++++---- src/intcmp.c | 12 ++++++------ src/mm.c | 18 ++++++++---------- src/npc.c | 8 ++++---- src/scrut.c | 10 +++++----- src/strcmp.c | 2 +- 6 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/dj.c b/src/dj.c index 894feba..1913dd9 100644 --- a/src/dj.c +++ b/src/dj.c @@ -30,7 +30,7 @@ extern int errno; -static char *program_name = "dj"; +char *program_name = "dj"; /* dj uses two structures that respectively correspond to the reading and * writing ends of its jockeyed "pipe". User-configurable members are noted @@ -163,7 +163,7 @@ 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 } */]; - char *s = (argv[0] == NULL ? program_name : argv[0]); + program_name = (argv[0] == NULL ? program_name : argv[0]); /* Set defaults. */ align = -1; @@ -234,7 +234,7 @@ int main(int argc, char *argv[]) { /* FALLTHROUGH */ default: - return usage(s); + return usage(program_name); } } } @@ -242,7 +242,7 @@ int main(int argc, char *argv[]) { assert(io->fd != STDIN_FILENO || io->fl == read_flags); assert(io->fd != STDOUT_FILENO || io->fl == write_flags); - if (argc > optind) { return usage(s); } + if (argc > optind) { return usage(program_name); } for (i = 0; i < (sizeof io) / (sizeof *io); ++i) { /* buffer allocation */ diff --git a/src/intcmp.c b/src/intcmp.c index 41a1592..7673944 100644 --- a/src/intcmp.c +++ b/src/intcmp.c @@ -30,7 +30,7 @@ /* 0b?00 */ /* Lesser or Equal | -le | 0b101 | 5 */ #define LESSER 0x04 /* Inequal (Greater or Lesser) | -gl | 0b110 | 6 */ -static char *program_name = "intcmp"; +char *program_name = "intcmp"; int usage(char *s) { fprintf(stderr, "Usage: %s [-egl] integer integer...\n", s); @@ -43,22 +43,22 @@ int main(int argc, char *argv[]) { size_t i; unsigned char mode; int r; /* reference integer */ - char *s = (argv[0] == NULL ? program_name : argv[0]); + program_name = (argv[0] == NULL ? program_name : argv[0]); mode = 0; - if (argc == 0 | argc < 3) { return usage(s); } + if (argc == 0 | argc < 3) { return usage(program_name); } 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(s); + default: return usage(program_name); } } - if (optind + 2 /* ref cmp */ > argc) { return usage(s); } + if (optind + 2 /* ref cmp */ > argc) { return usage(program_name); } i = optind; @@ -68,7 +68,7 @@ int main(int argc, char *argv[]) { if (*argv[i] != '\0' || errno != 0) { fprintf( - stderr, "%s: argument #%d: Invalid integer\n", argv[0], (int)i + stderr, "%s: argument #%d: Invalid integer\n", program_name, (int)i ); return EX_USAGE; } diff --git a/src/mm.c b/src/mm.c index 459d3b3..63cc3ff 100644 --- a/src/mm.c +++ b/src/mm.c @@ -48,7 +48,7 @@ struct Files{ #endif /* pre-allocated strings */ -static char *program_name = "mm"; +char *program_name = "mm"; static char *stdin_name = ""; static char *stdout_name = ""; static char *stderr_name = ""; @@ -125,7 +125,7 @@ int main(int argc, char *argv[]) { size_t j; size_t k; /* loop index but also unbuffer status */ int retval; - char *s = argv[0] == NULL ? program_name : argv[0]; + program_name = (argv[0] == NULL ? program_name : argv[0]); /* Initializes the files structs with their default values, standard * input and standard output. If an input or an output is specified @@ -150,8 +150,6 @@ int main(int argc, char *argv[]) { k = 0; - if (argc > 0) { program_name = s; } - if (argc > 1) { while ((c = getopt(argc, argv, "aehi:no:u")) != -1) { switch (c){ @@ -164,7 +162,7 @@ int main(int argc, char *argv[]) { break; } - retval = oserr(s, "-e"); + retval = oserr(program_name, "-e"); terminate; case 'i': if ( @@ -173,7 +171,7 @@ int main(int argc, char *argv[]) { || Files_open(&files[0], optarg) != NULL ) { break; } - retval = oserr(s, optarg); + retval = oserr(program_name, optarg); terminate; case 'o': if ( @@ -191,25 +189,25 @@ int main(int argc, char *argv[]) { } } - retval = oserr(s, optarg); + retval = oserr(program_name, optarg); terminate; case 'n': if (signal(SIGINT, SIG_IGN) != SIG_ERR) { break; } - retval = oserr(s, "-n"); + retval = oserr(program_name, "-n"); terminate; case 'u': k = 1; break; default: - retval = usage(s); + retval = usage(program_name); terminate; } } } if (optind != argc) { - retval = usage(s); + retval = usage(program_name); terminate; } diff --git a/src/npc.c b/src/npc.c index 0767163..4f74c6f 100644 --- a/src/npc.c +++ b/src/npc.c @@ -23,7 +23,7 @@ #include /* getopt(3) */ #include /* EX_OK, EX_USAGE */ -static char *program_name = "dj"; +char *program_name = "npc"; int usage(char *s) { fprintf(stderr, "Usage: %s [-et]\n", s); @@ -34,19 +34,19 @@ int main(int argc, char *argv[]) { int c; char showend = 0; /* print a dollar sign before each newline */ char showtab = 0; /* prints tab characters in caret notation */ - char *s = (argv[0] == NULL ? program_name : argv[0]); + program_name = (argv[0] == NULL ? program_name : argv[0]); if (argc > 0) { while ((c = getopt(argc, argv, "et")) != -1) { switch (c){ case 'e': showend = 1; break; case 't': showtab = 1; break; - default: return usage(s); + default: return usage(program_name); } } } - if (argc > optind) { return usage(s); } + if (argc > optind) { return usage(program_name); } while ((c = getc(stdin)) != EOF) { if ((c & 0x80) != 0) { fputs("M-", stdout); } diff --git a/src/scrut.c b/src/scrut.c index ad2ed92..7320c8f 100644 --- a/src/scrut.c +++ b/src/scrut.c @@ -26,7 +26,7 @@ * S_ISFIFO, S_ISGID, S_ISREG, S_ISLNK, S_ISSOCK, * S_ISUID, S_ISVTX */ -static char *program_name = "scrut"; +char *program_name = "scrut"; static char args[] = "bcdefgkprsuwxLS"; int usage(char *s) { @@ -36,16 +36,16 @@ int usage(char *s) { int main(int argc, char *argv[]) { char sel[(sizeof args) / (sizeof *args)]; - char *s = (argv[0] == NULL ? program_name : argv[0]); + program_name = (argv[0] == NULL ? program_name : argv[0]); - if (argc < 2) { return usage(s); } + if (argc < 2) { return usage(program_name); } { /* option parsing */ char *p; memset(sel, '\0', sizeof sel); for (int c; (c = getopt(argc, argv, args)) != -1;) { - if ((p = strchr(args, c)) == NULL) { return usage(s); } + if ((p = strchr(args, c)) == NULL) { return usage(program_name); } else { sel[p - args] = c; } } @@ -59,7 +59,7 @@ int main(int argc, char *argv[]) { } } - if (optind == argc) { return usage(argv[0]); } + if (optind == argc) { return usage(program_name); } for (argv += optind ; *argv != NULL; ++argv) { struct stat buf; diff --git a/src/strcmp.c b/src/strcmp.c index c9d56b0..16ec3ca 100644 --- a/src/strcmp.c +++ b/src/strcmp.c @@ -20,7 +20,7 @@ #include /* fprintf(3), stderr */ #include /* EX_OK, EX_USAGE */ -static char *program_name = "strcmp"; +char *program_name = "strcmp"; int main(int argc, char *argv[]) { int i; From 0641a487d711fcf11adba9e5b81da9f2407614e2 Mon Sep 17 00:00:00 2001 From: emma Date: Thu, 25 Jul 2024 21:17:30 -0600 Subject: [PATCH 53/84] intcmp(1): fixes pointless condition; formatting --- src/intcmp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/intcmp.c b/src/intcmp.c index 7673944..f990a10 100644 --- a/src/intcmp.c +++ b/src/intcmp.c @@ -47,7 +47,7 @@ int main(int argc, char *argv[]) { mode = 0; - if (argc == 0 | argc < 3) { return usage(program_name); } + if (argc == 0) { return usage(program_name); } while ((c = getopt(argc, argv, "egl")) != -1) { switch (c) { @@ -68,7 +68,10 @@ int main(int argc, char *argv[]) { if (*argv[i] != '\0' || errno != 0) { fprintf( - stderr, "%s: argument #%d: Invalid integer\n", program_name, (int)i + stderr, + "%s: argument #%d: Invalid integer\n", + program_name, + (int)i ); return EX_USAGE; } From c0a5e11eef53f166ba638ac561a4205905c9922b Mon Sep 17 00:00:00 2001 From: emma Date: Thu, 25 Jul 2024 21:28:42 -0600 Subject: [PATCH 54/84] mm(1): revert changes to program_name --- src/mm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mm.c b/src/mm.c index 63cc3ff..8779e8e 100644 --- a/src/mm.c +++ b/src/mm.c @@ -125,7 +125,6 @@ int main(int argc, char *argv[]) { size_t j; size_t k; /* loop index but also unbuffer status */ int retval; - program_name = (argv[0] == NULL ? program_name : argv[0]); /* Initializes the files structs with their default values, standard * input and standard output. If an input or an output is specified @@ -150,6 +149,8 @@ int main(int argc, char *argv[]) { k = 0; + if (argc > 0) { program_name = argv[0]; } + if (argc > 1) { while ((c = getopt(argc, argv, "aehi:no:u")) != -1) { switch (c){ From 199d48d85b29689d37d4bb4f78bc7e8fb83a83e9 Mon Sep 17 00:00:00 2001 From: DTB Date: Sat, 27 Jul 2024 17:59:47 -0600 Subject: [PATCH 55/84] swab(1): comment code --- src/swab.rs | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/swab.rs b/src/swab.rs index 5942c38..771d352 100644 --- a/src/swab.rs +++ b/src/swab.rs @@ -27,15 +27,12 @@ extern crate getopt; use getopt::GetOpt; extern crate sysexits; -use sysexits::{ EX_OK, EX_OSERR, EX_USAGE }; +use sysexits::{ EX_IOERR, EX_OK, EX_USAGE }; extern crate strerror; use strerror::StrError; -fn oserr(s: &str, e: Error) -> ExitCode { - eprintln!("{}: {}", s, e.strerror()); - ExitCode::from(EX_OSERR as u8) -} +fn err(s: &str, e: Error) { eprintln!("{}: {}", s, e.strerror()); } fn usage(s: &str) -> ExitCode { eprintln!("Usage: {} [-f] [-w word_size]", s); @@ -44,19 +41,20 @@ fn usage(s: &str) -> ExitCode { fn main() -> ExitCode { let argv = args().collect::>(); - let mut buf: Vec = Vec::new(); + let mut buf: Vec = Vec::new(); // holds the sequence getting swabbed let mut input = stdin(); let mut output = stdout().lock(); let mut force = false; - let mut wordsize: usize = 2; + let mut wordsize: usize = 2; // default; mimics dd(1p) conv=swab while let Some(opt) = argv.getopt("fw:") { match opt.opt() { Ok("f") => force = true, - Ok("w") => { + Ok("w") => { // sets new sequence length if let Some(arg) = opt.arg() { match arg.parse::() { + // an odd sequence length is nonsensical Ok(w) if w % 2 == 0 => { wordsize = w; () }, _ => { return usage(&argv[0]); }, } @@ -70,21 +68,28 @@ fn main() -> ExitCode { loop { match input.read(&mut buf) { - Ok(0) => break ExitCode::from(EX_OK as u8), - Ok(v) if v == wordsize => { + Ok(0) => break ExitCode::from(EX_OK as u8), // read nothing; bye + Ok(v) if v == wordsize => { // read full block; swab let (left, right) = buf.split_at(v/2); + if let Err(e) = output.write(&right) .and_then(|_| output.write(&left)) { - break oserr(&argv[0], e) + err(&argv[0], e); + break EX_IOERR // write error } + }, - Ok(v) => { + Ok(v) => { // partial read; partially write if let Err(e) = output.write(&buf[..v]) { - break oserr(&argv[0], e) + err(&argv[0], e); + break EX_IOERR // write error } }, Err(e) if e.kind() == ErrorKind::Interrupted && force => continue, - Err(e) => break oserr(&argv[0], e) + Err(e) => { + err(&argv[0], e); + break EX_IOERR // read error (or signal) + } } } } From cba8394d95a76c75801681b929640788ee9f90b3 Mon Sep 17 00:00:00 2001 From: DTB Date: Sat, 27 Jul 2024 18:18:29 -0600 Subject: [PATCH 56/84] str(1): fix argv parsing and add comments --- src/str.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/str.c b/src/str.c index 646e4c7..e503470 100644 --- a/src/str.c +++ b/src/str.c @@ -51,11 +51,10 @@ int usage(char *s){ } int main(int argc, char *argv[]){ - size_t ctype; /* selected from ctypes.h; index of ctype */ - int retval; - char *s = (argv[0] == NULL ? program_name : argv[0]); + size_t ctype; // selected from ctypes.h; index of ctype + int retval; // initially fail but becomes success on the first valid char - if (argc < 3) { return usage(s); } + if (argc < 3) { return usage(argv[0] == NULL ? program_name : argv[0]); } for ( /* iterate ctypes */ ctype = 0; @@ -64,15 +63,16 @@ int main(int argc, char *argv[]){ ++ctype ); - if (ctypes[ctype].f == NULL) { return usage(s); } + if (ctypes[ctype].f == NULL) { return usage(argv[0]); } /* iterate args */ for (argv += 2, retval = EXIT_FAILURE; *argv != NULL; ++argv) { - for (size_t i = 0; s[i] != '\0'; ++i) { /* iterate arg bytes */ - /* First checks if s[i] is valid ASCII; ctypes(3) don't + for (size_t i = 0; argv[0][i] != '\0'; ++i) { /* iterate arg bytes */ + /* First checks if argv[0][i] is valid ASCII; ctypes(3) don't * handle non-ASCII. This is bad. */ if( - (unsigned char)s[i] < 0x80 && !ctypes[ctype].f(s[i]) + (unsigned char)argv[0][i] < 0x80 // argv[0][i] is ASCII, + && !ctypes[ctype].f(argv[0][i]) // so use ctypes(3) ) { return EXIT_FAILURE; } else { retval = EXIT_SUCCESS; } } From c5c0e543e487dcf416ce44e9094606e417ac0650 Mon Sep 17 00:00:00 2001 From: DTB Date: Sat, 27 Jul 2024 18:21:17 -0600 Subject: [PATCH 57/84] mm(1): remove useless extern errno --- src/mm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mm.c b/src/mm.c index 8779e8e..e57e3b3 100644 --- a/src/mm.c +++ b/src/mm.c @@ -26,8 +26,6 @@ #include /* getopt(3) */ #include /* EX_IOERR, EX_OK, EX_OSERR, EX_USAGE */ -extern int errno; - /* This structure is how open files are tracked. */ struct Files{ size_t a; /* allocation */ From 429d0642090e91bc35dfcf7f5e04082d6bb9d250 Mon Sep 17 00:00:00 2001 From: DTB Date: Sat, 27 Jul 2024 18:22:43 -0600 Subject: [PATCH 58/84] mm(1): fix argv use --- src/mm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mm.c b/src/mm.c index e57e3b3..1d97ab5 100644 --- a/src/mm.c +++ b/src/mm.c @@ -147,9 +147,9 @@ int main(int argc, char *argv[]) { k = 0; - if (argc > 0) { program_name = argv[0]; } + if (argc > 0) { + program_name = argv[0]; - if (argc > 1) { while ((c = getopt(argc, argv, "aehi:no:u")) != -1) { switch (c){ case 'a': /* "rb+" -> "ab" */ From 5d481140835ed94e263d3921c9418b4a43059d12 Mon Sep 17 00:00:00 2001 From: DTB Date: Sat, 27 Jul 2024 18:32:04 -0600 Subject: [PATCH 59/84] dj(1), intcmp(1), mm(1), npc(1), scrut(1), str(1): make usage function consistent --- src/dj.c | 10 ++++++---- src/intcmp.c | 5 +++-- src/mm.c | 12 +++++++----- src/npc.c | 6 ++++-- src/scrut.c | 17 ++++++++++------- src/str.c | 6 ++++-- 6 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/dj.c b/src/dj.c index 1913dd9..c4ebf38 100644 --- a/src/dj.c +++ b/src/dj.c @@ -146,11 +146,13 @@ parse(char *s) { } static int -usage(char *s) { - fprintf( - stderr, "Usage: %s [-Hn] [-a byte] [-c count]\n" +usage(char *argv0) { + (void)fprintf( + stderr, + "Usage: %s [-Hn] [-a byte] [-c count]\n" "\t[-i file] [-b block_size] [-s offset]\n" - "\t[-o file] [-B block_size] [-S offset]\n", s + "\t[-o file] [-B block_size] [-S offset]\n", + argv0 ); return EX_USAGE; diff --git a/src/intcmp.c b/src/intcmp.c index f990a10..35fecf3 100644 --- a/src/intcmp.c +++ b/src/intcmp.c @@ -32,8 +32,9 @@ char *program_name = "intcmp"; -int usage(char *s) { - fprintf(stderr, "Usage: %s [-egl] integer integer...\n", s); +static int +usage(char *argv0) { + (void)fprintf(stderr, "Usage: %s [-egl] integer integer...\n", argv0); return EX_USAGE; } diff --git a/src/mm.c b/src/mm.c index 1d97ab5..d148446 100644 --- a/src/mm.c +++ b/src/mm.c @@ -107,11 +107,13 @@ oserr(char *s, char *r) { } \ return retval -/* Prints a usage text, in which s is the program being run (i.e. argv[0]), and - * returns an exit status appropriate for a usage error. */ -int usage(char *s) { - - fprintf(stderr, "Usage: %s [-aenu] [-i input]... [-o output]...\n", s); +static int +usage(char *argv0) { + (void)fprintf( + stderr, + "Usage: %s [-aenu] [-i input]... [-o output]...\n", + argv0 + ); return EX_USAGE; } diff --git a/src/npc.c b/src/npc.c index 4f74c6f..4cc4160 100644 --- a/src/npc.c +++ b/src/npc.c @@ -25,8 +25,10 @@ char *program_name = "npc"; -int usage(char *s) { - fprintf(stderr, "Usage: %s [-et]\n", s); +static int +usage(char *argv0) { + fprintf(stderr, "Usage: %s [-et]\n", argv0); + return EX_USAGE; } diff --git a/src/scrut.c b/src/scrut.c index 7320c8f..4d5a932 100644 --- a/src/scrut.c +++ b/src/scrut.c @@ -27,15 +27,18 @@ * S_ISUID, S_ISVTX */ char *program_name = "scrut"; -static char args[] = "bcdefgkprsuwxLS"; +#define OPTS "bcdefgkprsuwxLS" +static char *opts = OPTS; + +static int +usage(char *argv0) { + (void)fprintf(stderr, "Usage: %s [-" OPTS "] file...\n", argv0); -int usage(char *s) { - fprintf(stderr, "Usage: %s [-%s] file...\n", s, args); return EX_USAGE; } int main(int argc, char *argv[]) { - char sel[(sizeof args) / (sizeof *args)]; + char sel[(sizeof opts) / (sizeof *opts)]; program_name = (argv[0] == NULL ? program_name : argv[0]); if (argc < 2) { return usage(program_name); } @@ -44,9 +47,9 @@ int main(int argc, char *argv[]) { char *p; memset(sel, '\0', sizeof sel); - for (int c; (c = getopt(argc, argv, args)) != -1;) { - if ((p = strchr(args, c)) == NULL) { return usage(program_name); } - else { sel[p - args] = c; } + for (int c; (c = getopt(argc, argv, opts)) != -1;) { + if ((p = strchr(opts, c)) == NULL) { return usage(program_name); } + else { sel[p - opts] = c; } } /* straighten out selections; permute out nulls */ diff --git a/src/str.c b/src/str.c index e503470..a41e4a1 100644 --- a/src/str.c +++ b/src/str.c @@ -45,8 +45,10 @@ static struct { { NULL, NULL } /* marks end */ }; -int usage(char *s){ - fprintf(stderr, "Usage: %s type string...\n", s); +static int +usage(char *argv0){ + (void)fprintf(stderr, "Usage: %s type string...\n", argv0); + return EX_USAGE; } From 970b25dee29cc48e705f62ae49f37d698ca03f1d Mon Sep 17 00:00:00 2001 From: DTB Date: Sat, 27 Jul 2024 18:35:02 -0600 Subject: [PATCH 60/84] str(1): fix brackets --- src/str.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/str.c b/src/str.c index a41e4a1..9f7b351 100644 --- a/src/str.c +++ b/src/str.c @@ -46,13 +46,13 @@ static struct { }; static int -usage(char *argv0){ +usage(char *argv0) { (void)fprintf(stderr, "Usage: %s type string...\n", argv0); return EX_USAGE; } -int main(int argc, char *argv[]){ +int main(int argc, char *argv[]) { size_t ctype; // selected from ctypes.h; index of ctype int retval; // initially fail but becomes success on the first valid char From d45fa19d5cc4375b9706cf7b6ea55ba791a1ba8b Mon Sep 17 00:00:00 2001 From: emma Date: Sat, 27 Jul 2024 23:59:32 -0600 Subject: [PATCH 61/84] dj(1): fixes extraneous ternary for program_name --- src/dj.c | 1 - 1 file changed, 1 deletion(-) 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; From aed64840ea9adcf332ba482cc0fb53f27cc9a5cd Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 28 Jul 2024 00:12:34 -0600 Subject: [PATCH 62/84] STYLE: fixes some concerns --- STYLE | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/STYLE b/STYLE index 4e35af6..76ecc99 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,13 +86,13 @@ 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. Follow 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. @@ -100,7 +100,8 @@ Safety-Critical Code [0]: 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). References From d5d13b84a76a07182814bf87be92d05b9fe45cc1 Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 28 Jul 2024 00:34:42 -0600 Subject: [PATCH 63/84] STYLE: repition & Kernighan quote --- STYLE | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/STYLE b/STYLE index 76ecc99..5322661 100644 --- a/STYLE +++ b/STYLE @@ -86,7 +86,7 @@ library crates. Group alike statements: 11. Do not use do while loops in C. -12. Follow the following rules from the paper The Power of 10: Rules for +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. @@ -95,7 +95,8 @@ Developing Safety-Critical Code [0]: 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. @@ -103,6 +104,12 @@ Developing Safety-Critical Code [0]: 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 ========== From 09193a14d5dcdc324387081667c02aa4854bee0b Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 28 Jul 2024 00:35:55 -0600 Subject: [PATCH 64/84] fop(1): fixes unhandled i/o error --- src/fop.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/fop.rs b/src/fop.rs index 061815e..0faa827 100644 --- a/src/fop.rs +++ b/src/fop.rs @@ -70,7 +70,10 @@ 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::>(); From 0f121cbac735fb5a43c8106a42f4b38e30fcb269 Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 28 Jul 2024 00:40:16 -0600 Subject: [PATCH 65/84] fop(1): more descriptive command arguments variable name --- src/fop.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fop.rs b/src/fop.rs index 0faa827..fc45248 100644 --- a/src/fop.rs +++ b/src/fop.rs @@ -79,7 +79,7 @@ fn main() { 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 */ @@ -87,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() From d2ae35eac9eca030d9b96252706da8494b7f5b18 Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 28 Jul 2024 01:15:08 -0600 Subject: [PATCH 66/84] fop(1): fixes glaring issue with newline handling --- src/fop.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/fop.rs b/src/fop.rs index fc45248..06024d5 100644 --- a/src/fop.rs +++ b/src/fop.rs @@ -71,7 +71,7 @@ fn main() { let mut buf = String::new(); if let Err(e) = stdin().read_to_string(&mut buf) { - eprintln!("{}: {}", argv[0], e.strerror); + eprintln!("{}: {}", argv[0], e.strerror()); exit(EX_IOERR); }; @@ -120,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| { From 68e31058a864052d03605b859fa96459167824b8 Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 28 Jul 2024 17:49:39 -0600 Subject: [PATCH 67/84] intcmp(1): move program_name ternary --- src/intcmp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/intcmp.c b/src/intcmp.c index 35fecf3..88356b4 100644 --- a/src/intcmp.c +++ b/src/intcmp.c @@ -44,10 +44,10 @@ 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; + program_name = (argv[0] == NULL ? program_name : argv[0]); + if (argc == 0) { return usage(program_name); } while ((c = getopt(argc, argv, "egl")) != -1) { From 6b9d13b8a0dc6a8a072148954e0e222a085c57d8 Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 28 Jul 2024 18:27:22 -0600 Subject: [PATCH 68/84] fop(1): better opt matching --- src/fop.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fop.rs b/src/fop.rs index 06024d5..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); } From 338a3e715550c84d4049fb802bf000e1bf26a9ad Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 28 Jul 2024 18:31:01 -0600 Subject: [PATCH 69/84] intcmp(1): move program_name ternary --- src/intcmp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/intcmp.c b/src/intcmp.c index 88356b4..3e329b9 100644 --- a/src/intcmp.c +++ b/src/intcmp.c @@ -46,20 +46,20 @@ int main(int argc, char *argv[]) { int r; /* reference integer */ mode = 0; - program_name = (argv[0] == NULL ? program_name : argv[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; From 44d461fb16ddc9bfb91565ad7417fe7e9f912548 Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 28 Jul 2024 18:33:49 -0600 Subject: [PATCH 70/84] scrut(1): return program_name ternary to former position --- src/scrut.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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; From ca6148e11f188f415677bec659e5150d1aeed14a Mon Sep 17 00:00:00 2001 From: DTB Date: Sun, 28 Jul 2024 21:06:53 -0600 Subject: [PATCH 71/84] intcmp(1): tweak comment --- src/intcmp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/intcmp.c b/src/intcmp.c index 35fecf3..36cc579 100644 --- a/src/intcmp.c +++ b/src/intcmp.c @@ -23,12 +23,12 @@ #include /* getopt(3), optind */ #include /* EX_OK, EX_USAGE */ -/* 0b00? */ /* Equal | -e | 0b001 | 1 */ -#define EQUAL 0x01 /* Greater | -g | 0b010 | 2 */ -/* 0b0?0 */ /* Greater or Equal | -ge | 0b011 | 3 */ -#define GREATER 0x02 /* Lesser | -l | 0b100 | 4 */ -/* 0b?00 */ /* Lesser or Equal | -le | 0b101 | 5 */ -#define LESSER 0x04 /* Inequal (Greater or Lesser) | -gl | 0b110 | 6 */ +#define /* 0b00? */ EQUAL 0x01 /* | -e | 0b001 | 1 */ +#define /* 0b0?0 */ GREATER 0x02 /* | -g | 0b010 | 2 */ +/* Equal | Greater 0x03 | -ge | 0b011 | 3 */ +#define /* 0b?00 */ LESSER 0x04 /* | -l | 0b100 | 4 */ +/* Equal | Lesser 0x05 | -le | 0b101 | 5 */ +/* (Inequal) Greater | Lesser 0x06 | -gl | 0b110 | 6 */ char *program_name = "intcmp"; From 361b34c50f13e32d6c2c67263253d791f665687b Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 29 Jul 2024 02:35:01 -0600 Subject: [PATCH 72/84] npc(1): improves program_name resolution --- src/npc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/npc.c b/src/npc.c index 4cc4160..2e256b0 100644 --- a/src/npc.c +++ b/src/npc.c @@ -36,9 +36,10 @@ int main(int argc, char *argv[]) { int c; char showend = 0; /* print a dollar sign before each newline */ char showtab = 0; /* prints tab characters in caret notation */ - program_name = (argv[0] == NULL ? program_name : argv[0]); if (argc > 0) { + program_name = argv[0]; + while ((c = getopt(argc, argv, "et")) != -1) { switch (c){ case 'e': showend = 1; break; From 549fa98bdb771079219df2af0ce56bb8f379f992 Mon Sep 17 00:00:00 2001 From: DTB Date: Mon, 29 Jul 2024 10:53:58 -0600 Subject: [PATCH 73/84] npc(1): interpret all retvals --- src/npc.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/npc.c b/src/npc.c index 2e256b0..b35aba4 100644 --- a/src/npc.c +++ b/src/npc.c @@ -17,17 +17,23 @@ * along with this program. If not, see https://www.gnu.org/licenses/. */ -#include /* fprintf(3), fputs(3), getc(3), putc(3), stdin, stdout, - * EOF */ -#include /* EXIT_FAILURE */ +#include /* fprintf(3), fputs(3), getc(3), perror(3), putc(3), stdin, + * stdout, EOF */ +#include /* EX_IOERR, EX_OK, EX_USAGE */ #include /* getopt(3) */ -#include /* EX_OK, EX_USAGE */ char *program_name = "npc"; +static int +ioerr(char *argv0, int err) { + perror(argv0); + + return EX_IOERR; +} + static int usage(char *argv0) { - fprintf(stderr, "Usage: %s [-et]\n", argv0); + (void)fprintf(stderr, "Usage: %s [-et]\n", argv0); return EX_USAGE; } @@ -52,16 +58,23 @@ int main(int argc, char *argv[]) { if (argc > optind) { return usage(program_name); } while ((c = getc(stdin)) != EOF) { - if ((c & 0x80) != 0) { fputs("M-", stdout); } + if ((c & 0x80) != 0 && fputs("M-", stdout) == EOF) { + return ioerr(argv[0]); + } switch (c ^ 0x80 /* 0b 1000 0000 */) { - case 0x7f: fputs("^?", stdout); break; /* delete character */ - case '\n': if (showend) { putc('$', stdout); } + case 0x7f: /* ASCII DEL (127d) */ + if(fputs("^?", stdout) == EOF) { return ioerr(argv[0]); } + break; + case '\n': + if (showend && fputc('$', stdout) == EOF) { + return ioerr(argv[0]); } + } default: if (c >= ' ' || c == '\n' || (!showtab && c == '\t')) { - putc(c, stdout); - } else { - fprintf(stdout, "^%c", c + '@'); + if (fputc(c, stdout) == EOF) { return ioerr(argv[0]); } + } else if (fprintf(stdout, "^%c", c + '@') < 0) { + return ioerr(argv[0]); } } } From 2e172d93e8735c6e35040d324dd2e898c7a13840 Mon Sep 17 00:00:00 2001 From: DTB Date: Mon, 29 Jul 2024 11:04:00 -0600 Subject: [PATCH 74/84] dj(1): interpret all retvals --- src/dj.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/dj.c b/src/dj.c index 8dc066a..1d12844 100644 --- a/src/dj.c +++ b/src/dj.c @@ -99,7 +99,7 @@ Io_write(struct Io *io) { io->error = errno; t = 0; } else if (t > 0) { - memmove(io->buf, &(io->buf)[t], (io->bufuse -= t)); + (void)memmove(io->buf, &(io->buf)[t], (io->bufuse -= t)); } io->bytes += t; @@ -111,7 +111,8 @@ Io_write(struct Io *io) { static int oserr(char *e, int n) { - fprintf(stderr, "%s: %s: %s\n", program_name, e, strerror(n)); + (void)fprintf(stderr, "%s: %s: %s\n", program_name, e, strerror(n)); + return EX_OSERR; } @@ -119,7 +120,7 @@ oserr(char *e, int n) { * completely read and written records. */ static void fprintio(FILE *stream, char *fmt, struct Io io[2]) { - fprintf( + return fprintf( stream, fmt, io[0].rec, @@ -129,8 +130,6 @@ fprintio(FILE *stream, char *fmt, struct Io io[2]) { io[0].bytes, io[1].bytes ); - - return; } /* Parses the string s to an integer, returning either the integer or in the @@ -248,7 +247,7 @@ int main(int argc, char *argv[]) { for (i = 0; i < (sizeof io) / (sizeof *io); ++i) { /* buffer allocation */ if ((io[i].buf = malloc(io[i].bs * (sizeof *(io[i].buf)))) == NULL) { - fprintf( + (void)fprintf( stderr, "%s: Failed to allocate %zd bytes\n", program_name, io[i].bs ); @@ -265,13 +264,13 @@ int main(int argc, char *argv[]) { /* hard seeking; t is io[1].bufuse, before Io_write subtracts from it */ for(size_t t; io[1].seek > 0; io[1].seek -= (t - io[1].bufuse)) { - memset( + (void)memset( io[1].buf, '\0', /* set buf to all nulls */ (t = io[1].bufuse = MIN(io[1].bs, io[1].seek)) /* saturate block */ ); if (Io_write(&io[1])->bufuse == t && !noerror && io[1].error == 0) { - Io_write(&io[1]); /* second chance */ + (void)Io_write(&io[1]); /* second chance */ } if (io[1].error != 0) { return oserr(io[1].fn, io[1].error); } @@ -282,7 +281,7 @@ int main(int argc, char *argv[]) { io[1].bufuse = 0; if (io[1].seek > 0) { /* hard seeking failed */ - fprintio(stderr, fmt, io); + (void)fprintio(stderr, fmt, io); return oserr(io[1].fn, errno); } @@ -303,7 +302,7 @@ int main(int argc, char *argv[]) { t = io[0].bufuse; if (Io_read(&io[0])->bufuse == t && !noerror && io[0].error == 0) { - Io_read(&io[0]); /* second chance */ + (void)Io_read(&io[0]); /* second chance */ } assert(io[0].bufuse >= t); @@ -311,14 +310,14 @@ int main(int argc, char *argv[]) { if (io[0].bufuse == t) { break; } /* that's all she wrote */ if (/* t < io[0].bufuse && */ io[0].bufuse < io[0].bs) { - fprintf(stderr, "%s: Partial read:\n\t", program_name); - fprintio(stderr, fmt, io); + (void)fprintf(stderr, "%s: Partial read:\n\t", program_name); + (void)fprintio(stderr, fmt, io); if (!noerror) { count = 1; } if (align >= 0) { /* fill the rest of the ibuf with padding */ - memset( + (void)memset( &(io[0].buf)[io[0].bufuse], align, io[0].bs - io[0].bufuse @@ -342,25 +341,25 @@ int main(int argc, char *argv[]) { if (io[0].bs <= io[1].bs) { int n; - memcpy( /* saturate obuf */ + (void)memcpy( /* saturate obuf */ io[1].buf, io[0].buf, (io[1].bufuse = (n = MIN(io[0].bufuse, io[1].bs))) ); /* permute the copied units out of ibuf */ - memmove(io[0].buf, &(io[0].buf)[n], (io[0].bufuse -= n)); + (void)memmove(io[0].buf, &(io[0].buf)[n], (io[0].bufuse -= n)); } else /* if(io[0].bs > io[1].bs) */ { int n; /* drain what we can from ibuf */ - memcpy( + (void)memcpy( &(io[1].buf)[io[1].bufuse], io[0].buf, (n = MIN(io[0].bufuse, io[1].bs - io[1].bufuse)) ); io[1].bufuse += n; /* permute out the copied units */ - memmove(io[0].buf, &(io[0].buf)[n], io[0].bs - n); + (void)memmove(io[0].buf, &(io[0].buf)[n], io[0].bs - n); io[0].bufuse -= n; if(io[0].bs + io[1].bufuse <= io[1].bs && count != 1) { @@ -375,7 +374,7 @@ int main(int argc, char *argv[]) { if (Io_write(&io[1])->bufuse == t && !noerror && io[1].error == 0) { - Io_write(&io[1]); /* second chance */ + (void)Io_write(&io[1]); /* second chance */ } assert(io[1].error == 0 || io[1].bufuse == t); @@ -392,15 +391,15 @@ int main(int argc, char *argv[]) { } if (0 < io[1].bufuse /* && io[1].bufuse < t */) { - fprintf(stderr, "%s: Partial write:\n\t", program_name); - fprintio(stderr, fmt, io); + (void)fprintf(stderr, "%s: Partial write:\n\t", program_name); + (void)fprintio(stderr, fmt, io); if(!noerror) { count = 1; } } } } - fprintio(stderr, fmt, io); + (void)fprintio(stderr, fmt, io); for (i = 0; i < (sizeof io) / (sizeof *io); ++i) { if (io[i].error) { return oserr(io[i].fn, io[i].error); } From 162c6411b3a8313b83e6c032111d8667aada14ba Mon Sep 17 00:00:00 2001 From: DTB Date: Mon, 29 Jul 2024 11:08:30 -0600 Subject: [PATCH 75/84] mm(1): remove terminate macro --- src/mm.c | 43 ++++++++----------------------------------- 1 file changed, 8 insertions(+), 35 deletions(-) diff --git a/src/mm.c b/src/mm.c index d148446..a9c45b3 100644 --- a/src/mm.c +++ b/src/mm.c @@ -88,25 +88,6 @@ oserr(char *s, char *r) { return EX_OSERR; } -/* Hijacks i and j from main and destructs the files[2] struct used by main by - * closing its files and freeing its files and names arrays, returning retval - * from main. */ -#define terminate \ - for (i = 0; i < 2; ++i) { \ - for (j = 0; j < files[i].s; ++j) { \ - if ( \ - files[i].files[j] != stdin \ - && files[i].files[j] != stdout \ - && files[i].files[j] != stderr \ - ) { \ - fclose(files[i].files[j]); \ - } \ - } \ - free(files[i].files); \ - free(files[i].names); \ - } \ - return retval - static int usage(char *argv0) { (void)fprintf( @@ -163,8 +144,7 @@ int main(int argc, char *argv[]) { break; } - retval = oserr(program_name, "-e"); - terminate; + return oserr(program_name, "-e"); case 'i': if ( (strcmp(optarg, "-") == 0 @@ -172,8 +152,7 @@ int main(int argc, char *argv[]) { || Files_open(&files[0], optarg) != NULL ) { break; } - retval = oserr(program_name, optarg); - terminate; + return oserr(program_name, optarg); case 'o': if ( (strcmp(optarg, "-") == 0 @@ -190,27 +169,21 @@ int main(int argc, char *argv[]) { } } - retval = oserr(program_name, optarg); - terminate; + return oserr(program_name, optarg); case 'n': if (signal(SIGINT, SIG_IGN) != SIG_ERR) { break; } - retval = oserr(program_name, "-n"); - terminate; + return oserr(program_name, "-n"); case 'u': k = 1; break; default: - retval = usage(program_name); - terminate; + return usage(program_name); } } } - if (optind != argc) { - retval = usage(program_name); - terminate; - } + if (optind != argc) { return usage(program_name); } files[0].s += files[0].s == 0; files[1].s += files[1].s == 0; @@ -258,11 +231,11 @@ int main(int argc, char *argv[]) { files[1].names[k] = files[1].names[k+1]; } - if(--files[1].s == 0) { terminate; } + if(--files[1].s == 0) { return retval; } } } } } - terminate; + return retval; } From 5545846c92f310bbb74e70c184f2b467e9fea701 Mon Sep 17 00:00:00 2001 From: DTB Date: Mon, 29 Jul 2024 11:10:17 -0600 Subject: [PATCH 76/84] dj(1): fix fprintio signature --- src/dj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dj.c b/src/dj.c index 1d12844..cb8b1db 100644 --- a/src/dj.c +++ b/src/dj.c @@ -118,7 +118,7 @@ oserr(char *e, int n) { /* Prints statistics regarding the use of dj, particularly partially and * completely read and written records. */ -static void +static int fprintio(FILE *stream, char *fmt, struct Io io[2]) { return fprintf( stream, From 7b930363bf7bfc0ea429dbe80a5697b830b1fab7 Mon Sep 17 00:00:00 2001 From: DTB Date: Mon, 29 Jul 2024 11:12:02 -0600 Subject: [PATCH 77/84] npc(1): fix syntax errors --- src/npc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/npc.c b/src/npc.c index b35aba4..7ef760a 100644 --- a/src/npc.c +++ b/src/npc.c @@ -25,7 +25,7 @@ char *program_name = "npc"; static int -ioerr(char *argv0, int err) { +ioerr(char *argv0) { perror(argv0); return EX_IOERR; @@ -68,7 +68,7 @@ int main(int argc, char *argv[]) { break; case '\n': if (showend && fputc('$', stdout) == EOF) { - return ioerr(argv[0]); } + return ioerr(argv[0]); } default: if (c >= ' ' || c == '\n' || (!showtab && c == '\t')) { From c554b96722634d09cf8441fdac065efa4e1971c6 Mon Sep 17 00:00:00 2001 From: DTB Date: Mon, 29 Jul 2024 11:13:58 -0600 Subject: [PATCH 78/84] swab(1): fix type errors --- src/swab.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/swab.rs b/src/swab.rs index 771d352..dd63587 100644 --- a/src/swab.rs +++ b/src/swab.rs @@ -75,20 +75,20 @@ fn main() -> ExitCode { if let Err(e) = output.write(&right) .and_then(|_| output.write(&left)) { err(&argv[0], e); - break EX_IOERR // write error + break ExitCode::from(EX_IOERR as u8) // write error } }, Ok(v) => { // partial read; partially write if let Err(e) = output.write(&buf[..v]) { err(&argv[0], e); - break EX_IOERR // write error + break ExitCode::from(EX_IOERR as u8) // write error } }, Err(e) if e.kind() == ErrorKind::Interrupted && force => continue, Err(e) => { err(&argv[0], e); - break EX_IOERR // read error (or signal) + break ExitCode::from(EX_IOERR as u8) // read error (or signal) } } } From a7b27f0d6ad57fa65e71306a44d7f76cbe795de5 Mon Sep 17 00:00:00 2001 From: DTB Date: Mon, 29 Jul 2024 11:14:48 -0600 Subject: [PATCH 79/84] strcmp(1): interpret all retvals --- src/strcmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strcmp.c b/src/strcmp.c index 16ec3ca..7f5f0ed 100644 --- a/src/strcmp.c +++ b/src/strcmp.c @@ -26,7 +26,7 @@ int main(int argc, char *argv[]) { int i; if (argc < 3) { - fprintf( + (void)fprintf( stderr, "Usage: %s string string...\n", argv[0] == NULL ? program_name : argv[0] From 7e347bebdf124fa9d10c65944aacef272b3f8d2d Mon Sep 17 00:00:00 2001 From: DTB Date: Mon, 29 Jul 2024 11:30:41 -0600 Subject: [PATCH 80/84] mm(1): interpret retvals --- src/mm.c | 83 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/src/mm.c b/src/mm.c index a9c45b3..56b8c95 100644 --- a/src/mm.c +++ b/src/mm.c @@ -82,8 +82,7 @@ Files_append(struct Files *files, FILE *file, char *name) { * appropriate for an OS error. */ static int oserr(char *s, char *r) { - - fprintf(stderr, "%s: %s: %s\n", s, r, strerror(errno)); + (void)fprintf(stderr, "%s: %s: %s\n", s, r, strerror(errno)); return EX_OSERR; } @@ -100,11 +99,7 @@ usage(char *argv0) { } int main(int argc, char *argv[]) { - int c; struct Files files[2]; /* {read, write} */ - size_t i; - size_t j; - size_t k; /* loop index but also unbuffer status */ int retval; /* Initializes the files structs with their default values, standard @@ -112,39 +107,41 @@ int main(int argc, char *argv[]) { * these initial values will be overwritten, so to, say, use mm(1) * equivalently to tee(1p), -o - will need to be specified before * additional files to ensure standard output is still written. */ - for (i = 0; i < 2; ++i) { + for (size_t i = 0; i < 2; ++i) { files[i].a = 0; files[i].s = 0; files[i].mode = fmode[i]; files[i].files = NULL; files[i].names = NULL; - Files_append( - &files[i], - i == 0 ? stdin : stdout, - i == 0 ? stdin_name : stdout_name - ); + if (Files_append( + &files[i], + i == 0 ? stdin : stdout, + i == 0 ? stdin_name : stdout_name + ) == NULL) { + return oserr(program_name, i == 0 ? stdin_name : stdout_name); + } files[i].s = 0; } - k = 0; - if (argc > 0) { + int c; + char unbuffered = 0; + program_name = argv[0]; while ((c = getopt(argc, argv, "aehi:no:u")) != -1) { - switch (c){ + switch (c) { case 'a': /* "rb+" -> "ab" */ files[1].mode[0] = 'a'; files[1].mode[2] = '\0'; break; case 'e': - if (Files_append(&files[1], stderr, stderr_name) != NULL) { - break; + if (Files_append(&files[1], stderr, stderr_name) == NULL) { + return oserr(program_name, stderr_name); } - - return oserr(program_name, "-e"); + break; case 'i': if ( (strcmp(optarg, "-") == 0 @@ -171,16 +168,28 @@ int main(int argc, char *argv[]) { return oserr(program_name, optarg); case 'n': - if (signal(SIGINT, SIG_IGN) != SIG_ERR) { break; } + if (signal(SIGINT, SIG_IGN) == SIG_ERR) { + return oserr(program_name, "-n"); + } - return oserr(program_name, "-n"); - case 'u': - k = 1; break; - default: - return usage(program_name); + case 'u': unbuffered = 1; break; + default: return usage(program_name); } } + + if (unbuffered) { /* Unbuffer files. */ + for ( + size_t i = 0; + i < files[0].s; + setvbuf(files[0].files[i++], NULL, _IONBF, 0) + ); + for ( + size_t i = 0; + i < files[1].s; + setvbuf(files[1].files[i++], NULL, _IONBF, 0) + ); + } } if (optind != argc) { return usage(program_name); } @@ -188,26 +197,18 @@ int main(int argc, char *argv[]) { files[0].s += files[0].s == 0; files[1].s += files[1].s == 0; - /* Unbuffer files. */ - if (k) { - for ( - i = 0; i < files[0].s; setvbuf(files[0].files[i++], NULL, _IONBF, 0) - ); - for ( - i = 0; i < files[1].s; setvbuf(files[1].files[i++], NULL, _IONBF, 0) - ); - } retval = EX_OK; /* Actual program loop. */ - for (i = 0; i < files[0].s; ++i) { /* iterate ins */ + for (size_t i = 0; i < files[0].s; ++i) { /* iterate ins */ + int c; + while ((c = getc(files[0].files[i])) != EOF) { /* iterate chars */ - for (j = 0; j < files[1].s; ++j) { /* iterate outs */ - if (putc(c, files[1].files[j]) == EOF) { - /* notebook's full */ + for (size_t j = 0; j < files[1].s; ++j) { /* iterate outs */ + if (putc(c, files[1].files[j]) == EOF) { /* notebook's full */ retval = EX_IOERR; - fprintf( + (void)fprintf( stderr, "%s: %s: %s\n", program_name, @@ -216,7 +217,7 @@ int main(int argc, char *argv[]) { ); if (fclose(files[1].files[j]) == EOF) { - fprintf( + (void)fprintf( stderr, "%s: %s: %s\n", program_name, @@ -226,7 +227,7 @@ int main(int argc, char *argv[]) { } /* massage out the tense muscle */ - for(k = j--; k < files[1].s - 1; ++k){ + for(size_t k = j--; k < files[1].s - 1; ++k){ files[1].files[k] = files[1].files[k+1]; files[1].names[k] = files[1].names[k+1]; } From 8d23c7fbac378570ee3b24afd3340517e547e342 Mon Sep 17 00:00:00 2001 From: DTB Date: Mon, 29 Jul 2024 13:43:52 -0600 Subject: [PATCH 81/84] dj(1): better ASV formatting and comments --- src/dj.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/dj.c b/src/dj.c index cb8b1db..17f406c 100644 --- a/src/dj.c +++ b/src/dj.c @@ -49,10 +49,6 @@ struct Io { int fl; /* file opening flags */ }; -/* To be assigned to main:fmt and used with printio(). */ -static char *fmt_asv = "%d\037%d\036%d\037%d\035%d\036%d\034"; -static char *fmt_human = "%d+%d > %d+%d; %d > %d\n"; - static char *stdin_name = ""; static char *stdout_name = ""; @@ -132,6 +128,18 @@ fprintio(FILE *stream, char *fmt, struct Io io[2]) { ); } +/* To be assigned to main:fmt and used with printio(). */ +static char *fmt_asv = + "%d" /* io[0].rec */ "\037" /* ASCII US */ + "%d" /* io[0].prec */ "\036" /* ASCII RS */ + "%d" /* io[1].rec */ "\037" /* ASCII US */ + "%d" /* io[1].prec */ "\035" /* ASCII GS */ + "%d" /* io[0].bytes */ "\036" /* ASCII RS */ + "%d" /* io[1].bytes */ "\034" /* ASCII FS */ + "\n" +; +static char *fmt_human = "%d+%d > %d+%d; %d > %d\n"; + /* Parses the string s to an integer, returning either the integer or in the * case of an error a negative integer. This is used for argument parsing * (e.g. -B [int]) in dj and no negative integer would be valid anyway. */ From 6c2b7b68fd503e75f86129b0ab238cad7e148695 Mon Sep 17 00:00:00 2001 From: emma Date: Mon, 29 Jul 2024 14:38:33 -0600 Subject: [PATCH 82/84] dj(1): more better comments --- src/dj.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/dj.c b/src/dj.c index 17f406c..d6f5fde 100644 --- a/src/dj.c +++ b/src/dj.c @@ -20,6 +20,7 @@ #include /* assert(3) */ #include /* errno */ #include /* open(2) */ +#include /* bool */ #include /* fprintf(3), stderr */ #include /* malloc(3), strtol(3), size_t */ #include /* memcpy(3), memmove(3), memset(3) */ @@ -28,8 +29,6 @@ * optarg, optind, STDIN_FILENO, STDOUT_FILENO */ #include /* S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR */ -extern int errno; - char *program_name = "dj"; /* dj uses two structures that respectively correspond to the reading and @@ -62,6 +61,7 @@ static int write_flags = O_WRONLY | O_CREAT; /* Macro to check if fd is stdin or stdout */ #define fdisstd(fd) ((fd) == STDIN_FILENO || (fd) == STDOUT_FILENO) +/* Completes one Io block read */ static struct Io * Io_read(struct Io *io) { int t; @@ -84,6 +84,7 @@ Io_read(struct Io *io) { return io; } +/* Completes one Io block write */ static struct Io * Io_write(struct Io *io) { int t; @@ -168,16 +169,16 @@ usage(char *argv0) { int main(int argc, char *argv[]) { int align; /* low 8b used, negative if no alignment is being done */ int count; /* -1 if dj(1) runs until no more reads are possible */ - char *fmt; /* == fmt_asv (default) or fmt_human (-H) */ - size_t i; /* side of io being modified */ - char noerror; /* 0=exits (default) 1=retries on partial reads or writes */ + char *fmt; /* set to fmt_asv (default) or fmt_human (-H) */ + size_t i; /* side of io (in or out) being modified */ + bool retry; /* false if exits on partial reads or writes */ struct Io io[2 /* { in, out } */]; /* Set defaults. */ align = -1; count = -1; fmt = fmt_asv; - noerror = 0; + retry = 0; for (i = 0; i < (sizeof io) / (sizeof *io); ++i) { io[i].bs = 1024 /* 1 KiB */; /* GNU dd(1) default; POSIX says 512B */ io[i].bufuse = 0; @@ -218,8 +219,9 @@ int main(int argc, char *argv[]) { } } - return oserr(optarg, errno); /* break; */ - case 'n': noerror = 1; break; /* retry failed reads once */ + return oserr(optarg, errno); + /* UNREACHABLE */ + case 'n': retry = 1; break; /* retry failed reads once */ case 'H': fmt = fmt_human; break; /* human-readable output */ case 'a': /* input buffer padding */ if (optarg[0] == '\0' || optarg[1] == '\0') { @@ -233,12 +235,12 @@ int main(int argc, char *argv[]) { if (c == 'c' && (count = parse(optarg)) >= 0) { break; } i = (c >= 'A' && c <= 'Z'); - c |= 0x20; /* 0b 0010 0000 (ASCII make lowercase) */ + c |= 0x20; /* 0b 0010 0000 (ASCII) make lowercase */ - if ( + if ( /* if -b or -s is parsed out correctly */ (c == 'b' && (io[i].bs = parse(optarg)) > 0) || (c == 's' && (io[i].seek = parse(optarg)) >= 0) - ) { break; } + ) { break; } /* don't error */ /* FALLTHROUGH */ default: @@ -277,7 +279,7 @@ int main(int argc, char *argv[]) { (t = io[1].bufuse = MIN(io[1].bs, io[1].seek)) /* saturate block */ ); - if (Io_write(&io[1])->bufuse == t && !noerror && io[1].error == 0) { + if (Io_write(&io[1])->bufuse == t && !retry && io[1].error == 0) { (void)Io_write(&io[1]); /* second chance */ } @@ -286,7 +288,7 @@ int main(int argc, char *argv[]) { if (io[1].bufuse == t) { break; } /* all writes failed! */ } - io[1].bufuse = 0; + io[1].bufuse = 0; /* reset after hard seek */ if (io[1].seek > 0) { /* hard seeking failed */ (void)fprintio(stderr, fmt, io); @@ -309,7 +311,7 @@ int main(int argc, char *argv[]) { } t = io[0].bufuse; - if (Io_read(&io[0])->bufuse == t && !noerror && io[0].error == 0) { + if (Io_read(&io[0])->bufuse == t && !retry && io[0].error == 0) { (void)Io_read(&io[0]); /* second chance */ } @@ -321,7 +323,7 @@ int main(int argc, char *argv[]) { (void)fprintf(stderr, "%s: Partial read:\n\t", program_name); (void)fprintio(stderr, fmt, io); - if (!noerror) { count = 1; } + if (!retry) { count = 1; } if (align >= 0) { /* fill the rest of the ibuf with padding */ @@ -380,7 +382,7 @@ int main(int argc, char *argv[]) { t = io[1].bufuse; if (Io_write(&io[1])->bufuse == t - && !noerror + && !retry && io[1].error == 0) { (void)Io_write(&io[1]); /* second chance */ } @@ -402,7 +404,7 @@ int main(int argc, char *argv[]) { (void)fprintf(stderr, "%s: Partial write:\n\t", program_name); (void)fprintio(stderr, fmt, io); - if(!noerror) { count = 1; } + if(!retry) { count = 1; } } } } From fd13a7f1899922e60a25a8504b39c50d6c2e78f8 Mon Sep 17 00:00:00 2001 From: DTB Date: Mon, 29 Jul 2024 14:43:21 -0600 Subject: [PATCH 83/84] swab(1): fix imports to be consistent --- src/swab.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/swab.rs b/src/swab.rs index dd63587..f4abc9d 100644 --- a/src/swab.rs +++ b/src/swab.rs @@ -24,12 +24,11 @@ use std::{ }; extern crate getopt; -use getopt::GetOpt; - extern crate sysexits; -use sysexits::{ EX_IOERR, EX_OK, EX_USAGE }; - extern crate strerror; + +use getopt::GetOpt; +use sysexits::{ EX_IOERR, EX_OK, EX_USAGE }; use strerror::StrError; fn err(s: &str, e: Error) { eprintln!("{}: {}", s, e.strerror()); } From 6bbccb3776da30be99b97753e1edbfe6939dac7c Mon Sep 17 00:00:00 2001 From: DTB Date: Mon, 29 Jul 2024 21:14:45 -0600 Subject: [PATCH 84/84] fop(1): fix minor optind bug, add some comments --- src/fop.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/fop.rs b/src/fop.rs index bbca85e..9f547b1 100644 --- a/src/fop.rs +++ b/src/fop.rs @@ -33,7 +33,7 @@ use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE }; fn main() { let argv = args().collect::>(); let mut d = '\u{1E}'.to_string(); /* ASCII record separator */ - let mut optind = 0; + let mut optind = 1; let usage = format!( "Usage: {} [-d delimiter] index command [args...]", @@ -54,6 +54,12 @@ fn main() { }; } + /* parse the specified index as a number we can use */ + let index = argv[optind].parse::().unwrap_or_else(|e| { + eprintln!("{}: {}: {}", argv[0], argv[1], e); + exit(EX_DATAERR); + }); + /* index of the argv[0] for the operator command */ let command_arg = optind as usize + 1; @@ -63,12 +69,7 @@ fn main() { exit(EX_USAGE); }); - /* parse the specified index as a number we can use */ - let index = argv[optind].parse::().unwrap_or_else(|e| { - eprintln!("{}: {}: {}", argv[0], argv[1], e); - exit(EX_DATAERR); - }); - + /* read entire standard input into memory */ let mut buf = String::new(); if let Err(e) = stdin().read_to_string(&mut buf) { eprintln!("{}: {}", argv[0], e.strerror());