more cleanup
This commit is contained in:
parent
cebb888918
commit
45d571233e
93
mm/mm.c
93
mm/mm.c
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user