diff --git a/paste.c b/paste.c index f5eaf11..2f594df 100644 --- a/paste.c +++ b/paste.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include /** * Uso: paste [OPÇÃO]... [ARQUIVO]... * Escreve linhas constituídas das linhas sequencialmente correspondentes de @@ -20,40 +22,105 @@ * Documentação completa em * ou disponível localmente via: info "(coreutils) paste invocation" */ - -int main(int argc, char **argv) { - int i; - FILE **files = malloc((argc - 1) * sizeof(FILE *)); - char *eofcur = malloc(argc * sizeof(char *)); - char *eofend = malloc(argc * sizeof(char *)); - for (i = 0; i < argc-1; i++) { - if (strcmp(argv[i+1], "-") == 0) - files[i] = stdin; - else - files[i] = fopen(argv[i+1], "r"); - eofcur[i] = '0'; - eofend[i] = '1'; +FILE *openstream(FILE *file, char *str) { + file = stdin; + if (strcmp(str, "-") != 0) + file = fopen(str, "r"); + if (!file) { + perror(str); + exit(EXIT_FAILURE); } - char sep = '\t'; + return file; +} + +int is_endoffiles(char *list) { + for (int i = 0; list[i] != '\0'; i++) { + if (list[i] == '0') + return 0; + } + // str = "111111..."; + return 1; +} + +/** + * Abertura de arquivos em paralelo + */ +int print_parallel(char **flist, int argc, char sep) { + int i; char buffer[BUFSIZ]; - while (strcmp(eofcur, eofend) != 0) { - for (i = 0; i < argc-1; i++) { + FILE **files = malloc(argc * sizeof(FILE *)); + /** + * eofstr = "000000..." (args) + */ + char *eofstr = malloc((argc + 1) * sizeof(char *)); + for (i = 0; i < argc; i++) { + files[i] = openstream(files[i], flist[i]); + eofstr[i] = '0'; + } + while (!is_endoffiles(eofstr)) { + for (i = 0; i < argc; i++) { if (fgets(buffer, BUFSIZ, files[i]) == NULL) { strcpy(buffer, "\n"); // buffer[0] = '\n'; // buffer[1] = '\0'; - eofcur[i] = '1'; - if (strcmp(eofcur, eofend) == 0) + eofstr[i] = '1'; + if (is_endoffiles(eofstr)) continue; } - if (i < argc-2) + if (i < argc-1) buffer[strcspn(buffer, "\n")] = sep; printf("%s", buffer); } } - for (i = 0; i < argc-1; i++) { + for (i = 0; i < argc; i++) { fclose(files[i]); } return EXIT_SUCCESS; } +/** + * Abertura de arquivos serial + */ +int print_serial(char **flist, int argc, char sep) { + char buffer[BUFSIZ]; + for (int i = 0; i < argc; i++) { + FILE *stream = openstream(stream, flist[i]); + while (fgets(buffer, BUFSIZ, stream) != NULL) { + buffer[strcspn(buffer, "\n")] = sep; + printf("%s", buffer); + } + putchar('\n'); + fclose(stream); + } + return EXIT_SUCCESS; +} + +int main(int argc, char **argv) { + int opt; + char sep = '\t'; + bool mode_serial = false; + while ((opt = getopt(argc, argv, "d:s")) != -1) { + if (opt == 0) { + continue; + } + switch (opt) { + case 'd': + sep = optarg[0]; + optind++; + break; + case 's': + mode_serial = true; + break; + default: + abort(); + } + } + optind--; + if (mode_serial) { + print_serial(argv + optind, argc - optind, sep); + return EXIT_SUCCESS; + } + + print_parallel(argv + optind, argc - optind, sep); + return EXIT_SUCCESS; +}