-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoptions.c
153 lines (146 loc) · 5.15 KB
/
options.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "options.h"
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
options_t *create_options() {
options_t *options = (options_t *) malloc(sizeof(options_t));
options->delimiter = ',';
options->flags = 0;
options->stream = stdin;
options->out_stream = stdout;
return options;
}
int compare_tag(const char *input, const char *tag, const char *short_tag) {
if (strcasecmp(input, tag) == 0)
return 0;
return strcmp(input, short_tag);
}
void print_help_menu() {
printf("Usage: table [OPTION]... FILE\n");
printf("Formats FILE, or standard input, to standard output.\n");
printf("\n");
printf(" -C, --counter prefix each line of output with the line number\n");
printf(" -h, --header treats the first line as header and separates it\n");
printf(" -v, --version display the version of table\n");
printf(" -f, --frame print a frame around the output\n");
printf(" -c, --colors use colors in the output\n");
printf(" -H, --help display this help\n");
printf(" -r, --align-right align text to the right side of the frame\n");
printf(" -o, --output-file output to file instead of stdout\n");
printf(" -F, --force used to override output file if file exists\n");
printf(" -d, --delimiter delimiter char to separate fields\n");
}
OPTION_FLAGS parse_argument(char *argument) {
if (compare_tag(argument, "--help", "-H") == 0) {
return HELP;
} else if (compare_tag(argument, "--version", "-v") == 0) {
return VERSION;
} else if (compare_tag(argument, "--counter", "-C") == 0) {
return COUNTER;
} else if (compare_tag(argument, "--header", "-h") == 0) {
return HEADER;
} else if (compare_tag(argument, "--colors", "-c") == 0) {
return COLORS;
} else if (compare_tag(argument, "--frame", "-f") == 0) {
return FRAME;
} else if (compare_tag(argument, "--align-right", "-r") == 0) {
return ALIGN_RIGHT;
} else if (compare_tag(argument, "--force", "-F") == 0) {
return FORCE;
} else {
return UNKNOWN;
}
}
int check_color_capability() {
char *term = getenv("TERM");
if (term == NULL) {
return 0;
}
if (strcmp(term, "xterm-256color") == 0) {
return 1;
}
return 0;
}
options_t *parse_options(int argc, char *argv[]) {
char *out_file = NULL;
options_t *options = create_options();
for (int i = 1; i < argc; ++i) {
char *argument = argv[i];
if (compare_tag(argument, "--delimiter", "-d") == 0) {
if (i >= argc - 1) {
fprintf(stderr, "Error: %s can no be used as last argument.\n", argument);
continue;
}
if (argv[i + 1][1] != 0) {
fprintf(stderr, "Error: Delimiter can not be longer then 1 char.\n");
continue;
}
options->delimiter = argv[i + 1][0];
i++;
continue;
}
if (compare_tag(argument, "--output-file", "-o") == 0) {
if (i >= argc - 1) {
fprintf(stderr, "Error: %s can no be used as last argument.\n", argument);
continue;
}
if (out_file != NULL) {
fprintf(stderr, "Error: Only 1 output file can be specified\n");
continue;
}
out_file = argv[i + 1];
i++;
continue;
}
OPTION_FLAGS parsed = parse_argument(argument);
if (parsed & UNKNOWN) {
if (access(argument, R_OK) == 0) {
if (options->stream != stdin) {
fprintf(stderr, "Error: Only one input file can be specified.\n");
exit(1);
}
options->stream = fopen(argument, "r");
continue;
}
printf("Unknown option: %s\n", argument);
options->flags |= HELP;
continue;
}
options->flags |= parsed;
}
if (out_file != NULL) {
if (strcasecmp(out_file, "stdout") == 0) {
options->out_stream = stdout;
} else if (strcasecmp(out_file, "stderr") == 0) {
options->out_stream = stderr;
} else if (access(out_file, F_OK) == 0) {
if (options->flags & FORCE) {
options->out_stream = fopen(out_file, "w");
} else {
fprintf(stderr, "Error: File exits and --force was not set defaulting to stdout\n");
}
} else {
FILE *file = fopen(out_file, "w");
if (file == NULL) {
fprintf(stderr, "Error: Failed to create file defaulting to stdout\n");
} else {
options->out_stream = file;
}
}
}
if (check_color_capability()) {
options->flags |= COLORS;
}
return options;
}
void options_free(options_t *options) {
if (options->stream != stdin) {
fclose(options->stream);
}
if (options->out_stream != stdout && options->out_stream != stderr) {
fclose(options->out_stream);
}
free(options);
}