1
0
src/homepage/knowledge/cat/cat.c

107 lines
2.5 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STDIN_NAME "<stdin>"
#define STDOUT_NAME "<stdout>"
/* these are the predicted errors that could occur */
enum error_type{
FILE_ACCESS,
FILE_CLOSE,
FILE_WRITE
};
/* this is an error function that will print to standard error the error that
* occurred in the program and exit */
void
error(enum error_type type, char *argv0, char *file_name){
switch(type){
case FILE_ACCESS:
fprintf(stderr, "%s: %s: cannot open file\n", argv0, file_name);
break;
case FILE_CLOSE:
fprintf(stderr, "%s: %s: cannot close file\n", argv0, file_name);
break;
case FILE_WRITE:
fprintf(stderr, "%s: %s: cannot write to file\n", argv0, file_name);
break;
}
exit(1);
}
/* print input to output, returns 0 if successful and 1 if unsuccessful */
int
file_copy(FILE *input, FILE *output){
char c;
while((c = getc(input)) != EOF)
if(putc(c, output) == EOF)
return 1;
return 0;
}
int
main(int argc, char *argv[]){
/* the name of the file being printed (for diagnostics) */
char *file_name;
/* allocate this ahead of time */
char *stdin_file_name = STDIN_NAME;
/* the file pointer of the file being printed */
FILE *input;
/* this will always be stdout */
FILE *output = stdout;
int i;
/* whether or not options are being parsed */
int parsing_opts = 1;
/* usage with 0 arguments - print standard input to standard output */
if(argc == 1 && file_copy(stdin, stdout))
error(FILE_WRITE, argv[0], STDOUT_NAME);
else if(argc == 1)
return 0;
for(i = 1; i < argc; ++i){
/* parsing options */
/* after `--`, interpret `--`, `-`, and `-u` as literal
* filenames */
if(parsing_opts && !strcmp(argv[i], "--")){
parsing_opts = 0;
continue;
/* ignore `-u` if still parsing options */
}else if(parsing_opts && !strcmp(argv[i], "-u"))
continue;
/* take `-` to mean standard input if still parsing options */
else if(parsing_opts && !strcmp(argv[i], "-")){
file_name = stdin_file_name;
input = stdin;
/* non-option; open the file and make sure file_name points to
* the right string */
}else{
file_name = argv[i];
input = fopen(file_name, "r");
if(input == NULL)
error(FILE_ACCESS, argv[0], file_name);
}
/* print input to output */
if(file_copy(input, output))
error(FILE_WRITE, argv[0], STDOUT_NAME);
/* close input file if it's not stdin */
if(input != stdin && fclose(input))
error(FILE_CLOSE, argv[0], file_name);
}
/* exit successfully */
return 0;
}