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;
}
/* Destructs the files[2] struct used by main by closing its files and freeing
* its files and names arrays. Returns the destructed files. */
static struct Files *
terminate(struct Files *files){
size_t i;
size_t j;
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 files;
}
/* 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
int main(int argc, char *argv[]){
int c;
struct Files files[2]; /* {read, write} */
size_t i;
size_t j;
size_t k;
struct Files files[2]; /* {read, write} */
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;
}
size_t k; /* loop index but also unbuffer status */
int retval;
/* Initializes the files structs with their default values, standard
* 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;
}
s = 0; /* Refers to whether or not files will be unbuffered. */
k = 0;
while((c = getopt(argc, argv, "aehi:no:u")) != -1)
switch(c){
@ -158,16 +142,16 @@ int main(int argc, char *argv[]){
if(Files_append(&files[1], stderr, stderr_name)
!= NULL)
break;
terminate(files);
return oserr(argv[0], "-e");
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;
terminate(files);
return oserr(argv[0], optarg);
retval = oserr(argv[0], optarg);
terminate;
case 'o':
if((strcmp(optarg, "-") == 0 && Files_append(&files[1],
stdout, stdout_name) != NULL)
@ -182,29 +166,29 @@ int main(int argc, char *argv[]){
break;
}
}
terminate(files);
return oserr(argv[0], optarg);;
retval = oserr(argv[0], optarg);
terminate;
case 'n':
if(signal(SIGINT, SIG_IGN) != SIG_ERR)
break;
terminate(files);
return oserr(argv[0], "-n");
retval = oserr(argv[0], "-n");
terminate;
case 'u':
s = 1;
k = 1;
break;
default:
fprintf(stderr, "Usage: %s (-aehnu)"
" (-i [input])... (-o [output])...\n",
argv[0]);
terminate(files);
return EX_USAGE;
retval = EX_USAGE;
terminate;
}
files[0].s += files[0].s == 0;
files[1].s += files[1].s == 0;
/* Unbuffer files. */
if(s){ for( i = 0;
if(k){ for( i = 0;
i < files[0].s;
setvbuf(files[0].files[i++], NULL, _IONBF, 0));
for( i = 0;
@ -212,10 +196,7 @@ int main(int argc, char *argv[]){
setvbuf(files[1].files[i++], NULL, _IONBF, 0));
}
/* Reflects whether (s==0) or not (s==1) the full length of the inputs
* could be written to all outputs, which is the return value for main
* to maintain feature parity with tee(1p). */
s = 0;
retval = 0;
/* Actual program loop. */
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 */
if(putc(c, files[1].files[j]) == EOF){
/* notebook's full */
s = 1;
retval = 1;
if(fclose(files[1].files[j]) == EOF)
fprintf(stderr, "%s: %s: %s\n",
program_name,
@ -236,13 +217,9 @@ int main(int argc, char *argv[]){
files[1].names[k]
= files[1].names[k+1];
}
if(--files[i].s == 0){
terminate(files);
return 1;
}
if(--files[i].s == 0)
terminate;
}
terminate(files);
return s;
terminate;
}