#include #include #include #include #include /** * Uso: paste [OPÇÃO]... [ARQUIVO]... * Escreve linhas constituídas das linhas sequencialmente correspondentes de * cada ARQUIVO, separadas por tabulações, para a saída padrão. * * Se ARQUIVO não for especificado ou for -, lê a entrada padrão. * * Argumentos obrigatórios para opções longas também o são para opções curtas. * -d, --delimiters=LISTA reutiliza caracteres da LISTA em vez de tabulações * -s, --serial cola um arquivo por vez em de todos em paralelo * -z, --zero-terminated delimitador de linha é NULO, não nova linha * --help mostra esta ajuda e sai * --version mostra informação da versão e sai * * Página de ajuda do GNU coreutils: * Relate erros de tradução para * Documentação completa em * ou disponível localmente via: info "(coreutils) paste invocation" */ FILE *openstream(FILE *file, char *str) { file = stdin; if (strcmp(str, "-") != 0) file = fopen(str, "r"); if (!file) { perror(str); exit(EXIT_FAILURE); } 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]; 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'; eofstr[i] = '1'; if (is_endoffiles(eofstr)) continue; } if (i < argc-1) buffer[strcspn(buffer, "\n")] = sep; printf("%s", buffer); } } 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; }