Skip to content

Commit

Permalink
Restructure to enable supporting stdin case
Browse files Browse the repository at this point in the history
  • Loading branch information
Ampretuzo committed May 1, 2021
1 parent eee45d2 commit 850428a
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 52 deletions.
114 changes: 63 additions & 51 deletions initial-reverse/reverse.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,81 @@
#define fsame(stat1, stat2) (stat1.st_dev == stat2.st_dev && stat1.st_ino == stat2.st_ino)


/* TODO: Error handling where applicable
void reverse_seekable(FILE *in, FILE *out, FILE *err) {
char *line = NULL;
size_t line_len = 0;
fpos_t fpos_start;

fseek(in, 0, SEEK_END);

while (true) {
fgetpos(in, &fpos_start);
getline(&line, &line_len, in);
fprintf(out, "%s", line);
fsetpos(in, &fpos_start);

fseek(in, -1, SEEK_CUR);
if (ftell(in) <= 0) {
return;
}
bool last_char = true;
while (true) {
if (ftell(in) <= 0) {
break;
}
int c = fgetc(in);
if (!last_char && c == '\n') {
break;
}
last_char = false;
fseek(in, -2, SEEK_CUR);
}
}
}

void reverse(FILE *in, FILE *out, FILE *err) {
fprintf(err, "TODO");
}


/* TODO: Error handling where applicable (+ file closing and memory freeing)
*/
int main(int argc, char *argv[]) {
if (argc < 2 || argc > 3) {
fprintf(stderr, "usage: reverse input [output]\n");
if (argc > 3) {
fprintf(stderr, "usage: reverse [input] [output]\n");
return 1;
}

if (argc == 1) {
reverse(stdin, stdout, stderr);
return 0;
}

char *input_filename;
char *output_filename;
FILE *input_file;
FILE *out;

input_filename = argv[1];
input_file = fopen(input_filename, "r");
if (!input_file) {
fprintf(stderr, "reverse: cannot open file '%s'\n", input_filename);
return 1;
}

if (argc == 2) {
reverse_seekable(input_file, stdout, stderr);
return 0;
}

if (argc > 2) {
if (argc == 3) {
char *output_filename;
FILE *out;
struct stat input_stat;
struct stat output_stat;

output_filename = argv[2];

if(stat(input_filename, &input_stat)) {
fprintf(stderr, "reverse: cannot open file '%s'\n", input_filename);
fprintf(stderr, "reverse: cannot stat file '%s'\n", input_filename);
return 1;
}
if(!stat(output_filename, &output_stat)) {
Expand All @@ -35,56 +89,14 @@ int main(int argc, char *argv[]) {
return 1;
}
}
}

input_file = fopen(input_filename, "r");
if (!input_file) {
fprintf(stderr, "reverse: cannot open file '%s'\n", input_filename);
return 1;
}

out = stdout;
if (output_filename) {
out = fopen(output_filename, "w");
if (!out) {
fprintf(stderr, "reverse: cannot open file '%s'\n", output_filename);
return 1;
}
reverse_seekable(input_file, out, stderr);
return 0;
}

char *line = NULL;
size_t line_len = 0;
fpos_t fpos_start;

// Actual program:

fseek(input_file, 0, SEEK_END);

while (true) {
fgetpos(input_file, &fpos_start);
getline(&line, &line_len, input_file);
fprintf(out, "%s", line);
fsetpos(input_file, &fpos_start);

// Position at the start of the previous line
fseek(input_file, -1, SEEK_CUR);
if (ftell(input_file) <= 0) {
return 0;
}
bool last_char = true;
while (true) {
if (ftell(input_file) <= 0) {
break;
}
int tmp = fgetc(input_file);
if (!last_char && tmp == '\n') {
break;
}
last_char = false;
fseek(input_file, -2, SEEK_CUR);
}
}

return 0;
}

2 changes: 1 addition & 1 deletion initial-reverse/tests/1.err
Original file line number Diff line number Diff line change
@@ -1 +1 @@
usage: reverse input [output]
usage: reverse [input] [output]

0 comments on commit 850428a

Please sign in to comment.