/* * Compilar com: gcc -Wall hdoc.c messages.c -o hdoc */ #include #include #include #include #include "messages.h" typedef enum { OPT_ERROR = -1, OPT_NAME, OPT_OVERWRITE, OPT_APPEND, OPT_HELP } Option; int parse_arg(char *arg); // Trata argumentos na linha de comando int main(int argc, char **argv) { char *file = NULL; char *mode = NULL; // Verificação do número de argumentos... if (argc == 1 || argc > 3) { // Só pode haver 2 ou 3 argumentos... print_error(MSG_ARGC_ERROR); return print_usage(EXIT_FAILURE, argv[0]); } else if (argc == 2) { // Invocação com 2 argumentos... switch (parse_arg(argv[1])) { case OPT_HELP: // Imprime ajuda e termina... return print_usage(EXIT_SUCCESS, argv[0]); case OPT_NAME: // Arquivo existe? if (access(argv[1], F_OK) == 0) { // Sem opções, só arquivos novos! print_error(MSG_FILE_EXISTS); return print_usage(EXIT_FAILURE, argv[0]); } // Nome do novo arquivo... file = argv[1]; mode = "w"; break; default: // Nome do arquivo não pode começar com '-'! print_error(MSG_INVALID_ARG); return print_usage(EXIT_FAILURE, argv[0]); } } else { // Invocação com 3 argumentos... for (int i = 1; argv[i] != NULL; i++) { switch (parse_arg(argv[i])) { case OPT_NAME: // Só pode haver uma definição de nome... if (file == NULL) file = argv[i]; break; case OPT_OVERWRITE: // Só pode haver uma definição de modo... if (mode == NULL) mode = "w"; break; case OPT_APPEND: // Só pode haver uma definição de modo... if (mode == NULL) mode = "a"; break; case OPT_HELP: // Exibe ajuda e termina com sucesso... return print_usage(EXIT_SUCCESS, argv[0]); case OPT_ERROR: // Algum dos argumentos é inválido... print_error_fmt(MSG_INVALID_FMT, argv[i]); return print_usage(EXIT_FAILURE, argv[0]); } } // Tem que haver um nome e um modo depois do loop... if (file == NULL || mode == NULL) { print_error(MSG_INCORRECT_ALL); return print_usage(EXIT_FAILURE, argv[0]); } } FILE *fstr = fopen(file, mode); if (!fstr) { perror(MSG_FOPEN_ERROR); return EXIT_FAILURE; } char line[BUFSIZ]; puts(MSG_EOF_HINT); while (1) { printf(MSG_PROMPT); if (fgets(line, BUFSIZ, stdin) == NULL) break; fprintf(fstr, "%s", line); } putchar('\n'); fclose(fstr); return EXIT_SUCCESS; } int parse_arg(char *arg) { // Argumento iniciado com '-'... if (arg[0] == '-') { if (strcmp(arg, "-a") == 0) { return OPT_APPEND; } else if (strcmp(arg, "-o") == 0) { return OPT_OVERWRITE; } else if (strcmp(arg, "-h") == 0) { return OPT_HELP; } else { // Argumento inválido! return OPT_ERROR; } } // Sem traço é nome de arquivo... return OPT_NAME; }