#include #include #include #include #include "editor.h" #include "log.h" void help() { printf("Usage:\n"); printf(" cmd open // opens the specified file\n"); printf(" cmd rm // deletes the specified file\n"); printf(" cmd new // creates a new empty file at the specified path\n"); printf(" cmd mv // moves the specified file to the new path\n"); printf(" cmd cp // copies the specified file to the new path\n"); printf(" cmd lenl // returns the length of the specified file in lines\n"); printf(" cmd lenc // returns the length of the specified file in chars\n"); printf(" cmd log // prints a list of all changes made to the file\n"); } int open_editor(char* filename) { initscr(); raw(); noecho(); keypad(stdscr, true); int max_y, max_x; getmaxyx(stdscr, max_y, max_x); start_color(); use_default_colors(); init_pair(1, COLOR_CYAN, -1); init_pair(2, COLOR_MAGENTA, -1); move(0, 5); Editor editor; if (strcmp(filename, "") == 0) { editor = new_editor(str_from_chars(filename)); } else { editor = editor_from(str_from_file(fopen(filename, "r")), str_from_chars(filename)); } while (true) { refresh(); int c = getch(); if (editor.editmode == true) { switch (c) { case 27: switch_mode(&editor); break; case KEY_BACKSPACE: move_cursor(&editor, -1, 0); delchar(&editor); break; case KEY_DC: delchar(&editor); break; case '\n': pressed_enter(&editor); break; case KEY_UP: move_cursor(&editor, 0, -1); break; case KEY_DOWN: move_cursor(&editor, 0, 1); break; case KEY_LEFT: move_cursor(&editor, -1, 0); break; case KEY_RIGHT: move_cursor(&editor, 1, 0); break; default: addchar(&editor, c); break; } } else { switch (c) { case 'q': endwin(); shutdown_editor(&editor); return 0; case 'i': switch_mode(&editor); break; case 'w': editor.unsaved_changes = false; save_file(&editor); // TODO: write function to save the data to a file break; default: break; } } } } // Copies a file from source to destination int copy_file(const char* source, const char* dest) { FILE* src = fopen(source, "rb"); if (src == NULL) { fprintf(stderr, "Error: Could not open source file %s\n", source); return -1; } FILE* dst = fopen(dest, "wb"); if (dst == NULL) { fclose(src); fprintf(stderr, "Error: Could not create destination file %s\n", dest); return -1; } char buffer[8192]; size_t bytes; while ((bytes = fread(buffer, 1, sizeof(buffer), src)) > 0) { if (fwrite(buffer, 1, bytes, dst) != bytes) { fclose(src); fclose(dst); fprintf(stderr, "Error: Write failed to %s\n", dest); return -1; } } fclose(src); fclose(dst); return 0; } // Counts the number of characters in a file int count_chars(const char* filename) { FILE* file = fopen(filename, "r"); if (file == NULL) { fprintf(stderr, "Error: Could not open file %s\n", filename); return -1; } int count = 0; int ch; while ((ch = fgetc(file)) != EOF) { count++; } fclose(file); return count; } // Counts the number of lines in a file int count_lines(const char* filename) { FILE* file = fopen(filename, "r"); if (file == NULL) { fprintf(stderr, "Error: Could not open file %s\n", filename); return -1; } int count = 0; int ch; int last_char = '\n'; // Handle empty files as 0 lines while ((ch = fgetc(file)) != EOF) { if (ch == '\n') { count++; } last_char = ch; } // Count last line if it doesn't end with newline if (last_char != '\n' && last_char != EOF) { count++; } fclose(file); return count; } // Command types typedef enum { CMD_OPEN, CMD_RM, CMD_NEW, CMD_MV, CMD_CP, CMD_LENL, CMD_LENC, CMD_LOG, CMD_UNKNOWN } CommandType; // Convert string to command type CommandType str_to_cmd(const char* cmd) { if (strcmp(cmd, "open") == 0) return CMD_OPEN; if (strcmp(cmd, "rm") == 0) return CMD_RM; if (strcmp(cmd, "new") == 0) return CMD_NEW; if (strcmp(cmd, "mv") == 0) return CMD_MV; if (strcmp(cmd, "cp") == 0) return CMD_CP; if (strcmp(cmd, "lenl") == 0) return CMD_LENL; if (strcmp(cmd, "lenc") == 0) return CMD_LENC; if (strcmp(cmd, "log") == 0) return CMD_LOG; return CMD_UNKNOWN; } int main(int argc, char* argv[]) { char log_fmt_string[128]; if (argc < 2) { help(); return 1; } CommandType cmd = str_to_cmd(argv[1]); if (argc == 3) { switch (cmd) { case CMD_OPEN: sprintf(log_fmt_string, "Opened File [%s]", argv[2]); open_editor(argv[2]); break; case CMD_RM: remove(argv[2]); sprintf(log_fmt_string, "Deleted File [%s]", argv[2]); break; case CMD_NEW: sprintf(log_fmt_string, "Created File [%s]", argv[2]); open_editor(argv[2]); break; case CMD_LENC: printf("%d\n", count_chars(argv[2])); break; case CMD_LENL: printf("%d\n", count_lines(argv[2])); break; default: help(); } } else if (argc == 4) { switch (cmd) { case CMD_MV: if (rename(argv[2], argv[3]) != 0) { fprintf(stderr, "Error: Failed to move file %s to %s\n", argv[2], argv[3]); } else { sprintf(log_fmt_string, "Moved file [%s] To [%s]", argv[2], argv[3]); } break; case CMD_CP: if (copy_file(argv[2], argv[3]) != 0) { fprintf(stderr, "Error: Failed to copy file %s to %s\n", argv[2], argv[3]); sprintf(log_fmt_string, "Failed to copy file [%s] To [%s]", argv[2], argv[3]); } else { sprintf(log_fmt_string, "Copied file [%s] To [%s]", argv[2], argv[3]); } break; default: help(); } } else { printf("invalid options\n"); help(); } // log output of command if (log_fmt_string[0] != '\0') { String_t str = str_from_chars(log_fmt_string); write_log(&str); str_dealloc(&str); } return 0; }