1
0

more cleanup

This commit is contained in:
dtb 2024-01-19 22:27:56 -07:00
parent cebb888918
commit 45d571233e

93
mm/mm.c
View File

@ -91,44 +91,28 @@ oserr(char *s, char *r){
return EX_OSERR; return EX_OSERR;
} }
/* Destructs the files[2] struct used by main by closing its files and freeing /* Hijacks i and j from main and destructs the files[2] struct used by main by
* its files and names arrays. Returns the destructed files. */ /* closing its files and freeing its files and names arrays, returning retval
static struct Files * * from main. */
terminate(struct Files *files){ #define terminate \
size_t i; for(i = 0; i < 2; ++i){ \
size_t j; for(j = 0; j < files[i].s; ++j) \
if(files[i].files[j] != stdin \
for(i = 0; i < 2; ++i){ && files[i].files[j] != stdout \
for(j = 0; j < files[i].s; ++j) && files[i].files[j] != stderr) \
if(files[i].files[j] != stdin fclose(files[i].files[j]); \
&& files[i].files[j] != stdout free(files[i].files); \
&& files[i].files[j] != stderr) free(files[i].names); \
fclose(files[i].files[j]); } \
free(files[i].files); return retval
free(files[i].names);
}
return files;
}
int main(int argc, char *argv[]){ int main(int argc, char *argv[]){
int c; int c;
struct Files files[2]; /* {read, write} */
size_t i; size_t i;
size_t j; size_t j;
size_t k; size_t k; /* loop index but also unbuffer status */
struct Files files[2]; /* {read, write} */ int retval;
int s; /* scratch variable */
/* The simple invocation (without given arguments) requires no memory
* allocations or use of the files structs and is therefore treated as
* a special case. To do the same with all bells and whistles call
* $ mm -i - -o - */
if(argc < 2){ /* simple invocation */
while((c = getc(stdin)) != EOF)
if(putc(c, stdout) == EOF)
return 1;
return 0;
}
/* Initializes the files structs with their default values, standard /* Initializes the files structs with their default values, standard
* input and standard output. If an input or an output is specified * input and standard output. If an input or an output is specified
@ -146,7 +130,7 @@ int main(int argc, char *argv[]){
files[i].s = 0; files[i].s = 0;
} }
s = 0; /* Refers to whether or not files will be unbuffered. */ k = 0;
while((c = getopt(argc, argv, "aehi:no:u")) != -1) while((c = getopt(argc, argv, "aehi:no:u")) != -1)
switch(c){ switch(c){
@ -158,16 +142,16 @@ int main(int argc, char *argv[]){
if(Files_append(&files[1], stderr, stderr_name) if(Files_append(&files[1], stderr, stderr_name)
!= NULL) != NULL)
break; break;
terminate(files); retval = oserr(argv[0], "-e");
return oserr(argv[0], "-e"); terminate;
case 'i': case 'i':
if((strcmp(optarg, "-") == 0 && Files_append(&files[0], if((strcmp(optarg, "-") == 0 && Files_append(&files[0],
stdin, stdin_name) != NULL) stdin, stdin_name) != NULL)
|| Files_open(&files[0], optarg) || Files_open(&files[0], optarg)
!= NULL) != NULL)
break; break;
terminate(files); retval = oserr(argv[0], optarg);
return oserr(argv[0], optarg); terminate;
case 'o': case 'o':
if((strcmp(optarg, "-") == 0 && Files_append(&files[1], if((strcmp(optarg, "-") == 0 && Files_append(&files[1],
stdout, stdout_name) != NULL) stdout, stdout_name) != NULL)
@ -182,29 +166,29 @@ int main(int argc, char *argv[]){
break; break;
} }
} }
terminate(files); retval = oserr(argv[0], optarg);
return oserr(argv[0], optarg);; terminate;
case 'n': case 'n':
if(signal(SIGINT, SIG_IGN) != SIG_ERR) if(signal(SIGINT, SIG_IGN) != SIG_ERR)
break; break;
terminate(files); retval = oserr(argv[0], "-n");
return oserr(argv[0], "-n"); terminate;
case 'u': case 'u':
s = 1; k = 1;
break; break;
default: default:
fprintf(stderr, "Usage: %s (-aehnu)" fprintf(stderr, "Usage: %s (-aehnu)"
" (-i [input])... (-o [output])...\n", " (-i [input])... (-o [output])...\n",
argv[0]); argv[0]);
terminate(files); retval = EX_USAGE;
return EX_USAGE; terminate;
} }
files[0].s += files[0].s == 0; files[0].s += files[0].s == 0;
files[1].s += files[1].s == 0; files[1].s += files[1].s == 0;
/* Unbuffer files. */ /* Unbuffer files. */
if(s){ for( i = 0; if(k){ for( i = 0;
i < files[0].s; i < files[0].s;
setvbuf(files[0].files[i++], NULL, _IONBF, 0)); setvbuf(files[0].files[i++], NULL, _IONBF, 0));
for( i = 0; for( i = 0;
@ -212,10 +196,7 @@ int main(int argc, char *argv[]){
setvbuf(files[1].files[i++], NULL, _IONBF, 0)); setvbuf(files[1].files[i++], NULL, _IONBF, 0));
} }
/* Reflects whether (s==0) or not (s==1) the full length of the inputs retval = 0;
* could be written to all outputs, which is the return value for main
* to maintain feature parity with tee(1p). */
s = 0;
/* Actual program loop. */ /* Actual program loop. */
for(i = 0; i < files[0].s; ++i) /* iterate ins */ for(i = 0; i < files[0].s; ++i) /* iterate ins */
@ -223,7 +204,7 @@ int main(int argc, char *argv[]){
for(j = 0; j < files[1].s; ++j) /* iterate outs */ for(j = 0; j < files[1].s; ++j) /* iterate outs */
if(putc(c, files[1].files[j]) == EOF){ if(putc(c, files[1].files[j]) == EOF){
/* notebook's full */ /* notebook's full */
s = 1; retval = 1;
if(fclose(files[1].files[j]) == EOF) if(fclose(files[1].files[j]) == EOF)
fprintf(stderr, "%s: %s: %s\n", fprintf(stderr, "%s: %s: %s\n",
program_name, program_name,
@ -236,13 +217,9 @@ int main(int argc, char *argv[]){
files[1].names[k] files[1].names[k]
= files[1].names[k+1]; = files[1].names[k+1];
} }
if(--files[i].s == 0){ if(--files[i].s == 0)
terminate(files); terminate;
return 1;
}
} }
terminate(files); terminate;
return s;
} }