added documentation, almost done with code

This commit is contained in:
FantasyPvP
2024-12-03 09:47:13 +00:00
parent af08485d27
commit ad96bcc0c8
6 changed files with 619 additions and 807 deletions
+82 -81
View File
@@ -7,36 +7,35 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
typedef struct { typedef struct String {
uint32_t size, capacity; uint32_t size, capacity;
char* data; char* data;
} String_t; } String_t;
String_t str_with_capacity(int capacity) { int str_len(String_t* s) {
String_t s; return (int)s->size;
/// allocate memory for 'capacity' chars
s.data = (char*)calloc(capacity, sizeof(char));
s.size = 0;
s.capacity = capacity;
return s;
} }
String_t str_from_chars(const char* string) { char* to_chars(String_t* s) {
String_t s; // allocate buffer with null terminator
char* buffer = (char*)calloc(s->size + 1, sizeof(char));
for (int i = 0; i < s->size; i++) {
buffer[i] = s->data[i];
}
buffer[s->size] = '\0';
return buffer;
}
s.data = (char*)calloc(strlen(string), sizeof(char)); String_t str_with_capacity(int capacity) {
strcpy(s.data, string); String_t s;
s.size = strlen(string); s.data = (char*)calloc(capacity, sizeof(char));
s.capacity = strlen(string); s.size = 0;
s.capacity = capacity;
return s; return s;
} }
String_t str_from_slice(const char* string, int len) { String_t str_from_slice(const char* string, int len) {
String_t s; String_t s;
s.data = (char*)calloc(len, sizeof(char)); s.data = (char*)calloc(len, sizeof(char));
strncpy(s.data, string, len); strncpy(s.data, string, len);
s.size = len; s.size = len;
@@ -44,27 +43,26 @@ String_t str_from_slice(const char* string, int len) {
return s; return s;
} }
String_t str_from_chars(const char* string) {
return str_from_slice(string, strlen(string));
}
String_t str_new() { String_t str_new() {
return str_with_capacity(1); return str_with_capacity(1);
} }
int str_dealloc(String_t* self) { int str_dealloc(String_t* self) {
free(self->data); free(self->data);
return 0; return 0;
} }
int str_push(String_t* self, char c) { int str_push(String_t* self, char c) {
// check size < capacity
if (self->size < self->capacity) { if (self->size < self->capacity) {
self->data[self->size] = c; self->data[self->size] = c;
self->size++; self->size++;
return 0; return 0;
} }
// reallocate to add capacity for an extra char
int newcap = self->capacity + sizeof(char); int newcap = self->capacity + sizeof(char);
self->data = (char*)realloc(self->data, newcap); self->data = (char*)realloc(self->data, newcap);
self->data[self->size] = c; self->data[self->size] = c;
@@ -75,41 +73,57 @@ int str_push(String_t* self, char c) {
int str_push_str(String_t* self, char* c) { int str_push_str(String_t* self, char* c) {
if (self->size + strlen(c) >= self->capacity) { if (self->size + strlen(c) >= self->capacity) {
self->capacity = ( self->size + strlen(c) ) * sizeof(char); self->capacity = (self->size + strlen(c)) * sizeof(char);
self->data = (char*)realloc(self->data, self->capacity); self->data = (char*)realloc(self->data, self->capacity);
for (int i = 0; i < strlen(c); i++) {
self->data[self->size + i] = c[i];
}
self->size = self->capacity;
} }
for (int i = 0; i < strlen(c); i++) {
self->data[self->size + i] = c[i];
}
self->size = self->capacity;
return 0;
} }
String_t str_from_file(FILE* file) { String_t str_from_file(FILE* file) {
if (file == NULL) { if (file == NULL) {
return str_new(); return str_new();
} }
char buffer[64]; char buffer[64];
String_t string = str_new(); String_t string = str_new();
while (fgets(buffer, sizeof(buffer), file) != NULL) { while (fgets(buffer, sizeof(buffer), file) != NULL) {
str_push_str(&string, buffer); str_push_str(&string, buffer);
} }
fclose(file); fclose(file);
return string; return string;
} }
int str_to_file(String_t* self, FILE* file) {
char* data = to_chars(self);
if (fprintf(file, "%s\n", data) == -1) {
free(data);
return -1;
}
free(data);
return 0;
}
String_t str_clone(String_t* self) {
String_t clone;
clone.size = self->size;
clone.capacity = self->capacity;
clone.data = (char*)malloc(clone.capacity);
memcpy(clone.data, self->data, clone.capacity);
return clone;
}
char str_pop(String_t* self) { char str_pop(String_t* self) {
if (self->size == 0) { if (self->size == 0) {
return '\0'; return '\0';
} }
self->size--; self->size--;
char c = self->data[self->size]; return self->data[self->size];
return c;
} }
int str_insert(String_t* self, int index, char c) { int str_insert(String_t* self, int index, char c) {
@@ -117,6 +131,10 @@ int str_insert(String_t* self, int index, char c) {
return -1; return -1;
} }
self->size++; self->size++;
if (self->size > self->capacity) {
self->capacity = (self->size) * sizeof(char);
self->data = (char*)realloc(self->data, self->capacity);
}
for (int i = self->size - 1; i > index; i--) { for (int i = self->size - 1; i > index; i--) {
self->data[i] = self->data[i - 1]; self->data[i] = self->data[i - 1];
} }
@@ -135,22 +153,16 @@ int str_remove(String_t* self, int index) {
return 0; return 0;
} }
/// splits a string into an array of strings based on a delimiter
String_t* str_split(String_t* self, int* res_len, char c) { String_t* str_split(String_t* self, int* res_len, char c) {
char* string = self->data; char* string = self->data;
String_t* elements = NULL;
// find the number of lines in the file
bool flag = false; bool flag = false;
*res_len = 0; *res_len = 0;
for (int i = 0; i < strlen(string); i++) {
// Count number of splits
for (int i = 0; i < self->size; i++) {
if (string[i] == c) { if (string[i] == c) {
// if (flag) { // this condition was here so that empty strings would be ignore
(*res_len)++; (*res_len)++;
flag = false; flag = false;
// }
} else { } else {
flag = true; flag = true;
} }
@@ -159,20 +171,17 @@ String_t* str_split(String_t* self, int* res_len, char c) {
(*res_len)++; (*res_len)++;
} }
// allocate memory for an array of pointers to each line String_t* elements = (String_t*)malloc((*res_len) * sizeof(String_t));
elements = (String_t*)malloc((*res_len) * sizeof(String_t));
int i = 0; int i = 0;
flag = false; flag = false;
char* start = string; char* start = string;
char* end = string; char* end = string;
char* string_end = string + self->size;
while (*end != '\0') { while (end < string_end) {
if (*end == c) { if (*end == c) {
// if (flag) {
elements[i] = str_from_slice(start, end - start); elements[i] = str_from_slice(start, end - start);
i++; i++;
// }
end++; end++;
start = end; start = end;
flag = false; flag = false;
@@ -180,12 +189,10 @@ String_t* str_split(String_t* self, int* res_len, char c) {
end++; end++;
flag = true; flag = true;
} }
} if (flag) { }
if (flag) {
elements[i] = str_from_slice(start, end - start); elements[i] = str_from_slice(start, end - start);
} }
// returns an array of String_t
return elements; return elements;
} }
@@ -209,38 +216,32 @@ String_t* str_lines(String_t* self, int* numlines) {
String_t str_slice(String_t* s, int start, int end) { String_t str_slice(String_t* s, int start, int end) {
String_t s2; String_t s2;
if (start < 0) start = 0;
if (end > s->size) end = s->size;
// if the range is invalid, we return an empty string
if (start >= end || start >= s->size) {
s2.size = 0;
s2.capacity = 1;
s2.data = (char*)calloc(1, sizeof(char));
return s2;
}
s2.size = end - start; s2.size = end - start;
s2.capacity = s2.size; s2.capacity = s2.size;
s2.data = (char*)calloc(s2.size, sizeof(char)); s2.data = (char*)calloc(s2.size, sizeof(char));
// if the allocation fails we return a zero sized string
if (s2.data == NULL) {
s2.size = 0;
s2.capacity = 0;
return s2;
}
for (int i = 0; i < s2.size; i++) { for (int i = 0; i < s2.size; i++) {
s2.data[i] = s->data[start + i]; s2.data[i] = s->data[start + i];
} }
return s2; return s2;
} }
int str_len(String_t* s) {
return s->size;
}
char* to_chars(String_t* s) {
return s->data;
}
// int main() {
// String_t s = str_from_chars("hello\nworld\neeeee\notherline\n");
// str_remove(&s, 10);
// str_insert(&s, 10, 'h');
// printf("%s\n", to_chars(&s));
// int linen = 0;
// String_t* lines = str_lines(&s, &linen);
// for (int i=0; i < linen; i++) {
// printf("%s", to_chars(&lines[i]));
// }
// str_dealloc(&s);
// return 0;
// }
+161 -14
View File
@@ -2,44 +2,191 @@
#define DYNSTR_H #define DYNSTR_H
#include <stdio.h> #include <stdio.h>
typedef struct { /**
int size; * Custom String type that stores an array of characters
int capacity; */
typedef struct String {
uint32_t size, capacity;
char* data; char* data;
} String_t; } String_t;
/**
* Creates a new string with the specified initial capacity.
* The string will be empty but can hold up to capacity characters
* without requiring reallocation.
*
* @param capacity Initial capacity in bytes
* @return A new String_t structure with allocated memory
*/
String_t str_with_capacity(int capacity); String_t str_with_capacity(int capacity);
/**
* Creates a new string from a null-terminated character array.
*
* @param string Null-terminated source string
* @return A new String_t containing a copy of the input string
*/
String_t str_from_chars(char* string); String_t str_from_chars(char* string);
/**
* Creates a new string from a character array slice.
* Allocates new memory and copies the specified number of characters.
*
* @param string Source character array
* @param len Number of characters to copy
* @return A new String_t containing the copied characters
*/
String_t str_from_slice(char* string, int len); String_t str_from_slice(char* string, int len);
/**
* Merges two strings into a new string.
* The resulting string contains s1's contents followed by s2's contents.
*
* @param s1 Pointer to the first String_t
* @param s2 Pointer to the second String_t
* @return A new String_t containing the merged contents
*/
String_t str_merge(String_t* s1, String_t* s2); String_t str_merge(String_t* s1, String_t* s2);
/**
* Creates a new string by reading from a file.
* Reads the file line by line and concatenates all lines.
*
* @param file Pointer to an open FILE
* @return A new String_t containing the file's contents
*/
String_t str_from_file(FILE* file); String_t str_from_file(FILE* file);
int str_push_str(String_t* string, char* other); /**
* Creates a new empty string with minimal capacity.
*
* @return A new empty String_t with capacity of 1 byte
*/
String_t str_new(); String_t str_new();
String_t* str_lines(String_t* self, int* numlines); /**
* Returns a clone of the string.
* This allocates new memory that must be freed
* @param self Pointer to the String_t to clone
*/
String_t str_clone();
/**
* Creates a new string containing a slice of an existing string.
* The slice includes characters from start index up to (but not including) end index.
*
* @param s Pointer to the source String_t
* @param start Starting index (inclusive)
* @param end Ending index (exclusive)
* @return A new String_t containing the specified slice
*/
String_t str_slice(String_t* s, int start, int end); String_t str_slice(String_t* s, int start, int end);
// String_t* str_split(String_t* self, int* res_len, char c); /**
* Splits a string into lines based on newline characters.
* Convenience wrapper around str_split that uses '\n' as delimiter.
*
* @param self Pointer to the String_t to split
* @param numlines Pointer to store the number of resulting lines
* @return Array of String_t structures, one per line
*/
String_t* str_lines(String_t* self, int* numlines);
void str_push(String_t* s, char c); /**
* Splits a string into an array of strings based on a delimiter.
* Each occurrence of the delimiter creates a new string.
*
* @param self Pointer to the String_t to split
* @param res_len Pointer to store the number of resulting strings
* @param c Delimiter character
* @return Array of String_t structures, must be freed by caller
*/
String_t* str_split(String_t* self, int* res_len, char c);
/**
* Removes and returns the last character in the string.
*
* @param self Pointer to the String_t to modify
* @return The removed character, or '\0' if string is empty
*/
char str_pop(String_t* s); char str_pop(String_t* s);
void str_insert(String_t* s, int index, char c); /**
* Returns a pointer to the underlying character array.
void str_remove(String_t* s, int index); * Note: The returned pointer is still owned by the String_t structure.
*
int str_dealloc(String_t* s); * @param s Pointer to the String_t structure
* @return Pointer to the null-terminated character array
*/
char* to_chars(String_t* s); char* to_chars(String_t* s);
/**
* Writes the string's contents to a file.
* Appends a newline character after writing the string.
*
* @param self Pointer to the String_t to write
* @param file Pointer to an open FILE
* @return 0 on success, -1 on failure
*/
int str_to_file(String_t* self, FILE* file);
/**
* Appends a null-terminated string to the end of the string.
* Automatically reallocates if more capacity is needed.
*
* @param self Pointer to the String_t to modify
* @param c Null-terminated string to append
* @return 0 on success
*/
int str_push_str(String_t* string, char* other);
/**
* Deallocates the memory used by a string.
* Must be called when the string is no longer needed to prevent memory leaks.
*
* @param self Pointer to the String_t to deallocate
* @return 0 on success
*/
int str_dealloc(String_t* s);
/**
* Returns the current length of the string.
*
* @param s Pointer to the String_t structure
* @return The number of characters in the string
*/
int str_len(String_t* s); int str_len(String_t* s);
/**
* Inserts a character at the specified index.
* Shifts existing characters right to make room.
* Automatically reallocates if more capacity is needed.
*
* @param self Pointer to the String_t to modify
* @param index Position to insert the character
* @param c Character to insert
* @return 0 on success, -1 if index is out of bounds
*/
void str_insert(String_t* s, int index, char c);
/**
* Removes the character at the specified index.
* Shifts remaining characters left to fill the gap.
*
* @param self Pointer to the String_t to modify
* @param index Position of character to remove
* @return 0 on success, -1 if index is out of bounds
*/
void str_remove(String_t* s, int index);
/**
* Appends a single character to the end of the string.
* Automatically reallocates if more capacity is needed.
*
* @param self Pointer to the String_t to modify
* @param c Character to append
* @return 0 on success
*/
void str_push(String_t* s, char c);
#endif #endif
+135 -62
View File
@@ -3,8 +3,12 @@
#include "dynstr.h" #include "dynstr.h"
#include <ncurses.h> #include <ncurses.h>
#define min(x, y) ((x) < (y) ? (x) : (y))
#define max(x, y) ((x) > (y) ? (x) : (y))
typedef struct { typedef struct {
uint32_t lines; uint32_t lines;
uint32_t capacity;
uint32_t buffer_line; uint32_t buffer_line;
uint32_t buffer_col; uint32_t buffer_col;
uint32_t y_offset; uint32_t y_offset;
@@ -12,6 +16,8 @@ typedef struct {
bool unsaved_changes; bool unsaved_changes;
bool editmode; bool editmode;
String_t* buffer; String_t* buffer;
String_t* original;
String_t filename;
} Editor; } Editor;
void add_toolbar(Editor* self) { void add_toolbar(Editor* self) {
@@ -22,7 +28,7 @@ void add_toolbar(Editor* self) {
// add an entry for the current mode // add an entry for the current mode
move(max_y - 1, 0); move(max_y - 1, 0);
char mode[8]; char mode[9];
snprintf(mode, 9, "[%6s]", self->editmode ? "Insert" : "Normal"); snprintf(mode, 9, "[%6s]", self->editmode ? "Insert" : "Normal");
addstr(mode); addstr(mode);
@@ -40,80 +46,94 @@ void add_toolbar(Editor* self) {
attroff(COLOR_PAIR(1)); attroff(COLOR_PAIR(1));
} }
#define min(x, y) ((x) < (y) ? (x) : (y))
void refresh_buffer(Editor* self) { void refresh_buffer(Editor* self) {
move(0, 0); move(0, 0);
clear(); clear();
// get the screen size so we can figure out where to place characters // get the screen size so we can figure out where to place characters
int max_x, max_y; int max_x, max_y;
getmaxyx(stdscr, max_y, max_x); getmaxyx(stdscr, max_y, max_x);
max_y--; // Reserve bottom line for toolbar
// Ensure y_offset is valid
if (self->buffer_line >= self->y_offset + max_y) {
self->y_offset = self->buffer_line - max_y + 1;
}
if (self->buffer_line < self->y_offset) {
self->y_offset = self->buffer_line;
}
// Display visible lines
for (size_t i = self->y_offset; i < self->lines && i < self->y_offset + max_y; i++) { for (size_t i = self->y_offset; i < self->lines && i < self->y_offset + max_y; i++) {
move(i - self->y_offset, 0);
// adding the line number // adding the line number
attron(COLOR_PAIR(1)); attron(COLOR_PAIR(1));
char line_no[6]; char line_no[6];
snprintf(line_no, 6, "%-6d", i + 1); snprintf(line_no, 6, "%-4d]", i + 1);
addstr(line_no); addstr(line_no);
attroff(COLOR_PAIR(1)); attroff(COLOR_PAIR(1));
// refreshing the text for the line // Only try to display the line if it's within bounds
String_t line_segment = str_slice( if (i < self->lines) {
&self->buffer[i], // Calculate visible portion of line
self->x_offset, int visible_start = self->x_offset;
min(str_len(&self->buffer[i]), self->x_offset + max_x - 5) int line_len = str_len(&self->buffer[i]);
); int visible_end = min(line_len, self->x_offset + max_x - 5);
if (visible_start < line_len) {
String_t line_segment = str_slice(
&self->buffer[i],
visible_start,
visible_end
);
addstr(to_chars(&line_segment)); char* data = to_chars(&line_segment);
str_dealloc(&line_segment);
addstr(data);
addstr("\n"); str_dealloc(&line_segment);
free(data);
}
}
} }
add_toolbar(self); add_toolbar(self);
move(self->buffer_line - self->y_offset, self->buffer_col + 5 - self->x_offset); // Ensure cursor position is valid
int cursor_y = self->buffer_line - self->y_offset;
int cursor_x = self->buffer_col - self->x_offset + 5;
// Clamp cursor position to screen bounds
cursor_y = min(max(cursor_y, 0), max_y - 1);
cursor_x = min(max(cursor_x, 5), max_x - 1);
move(cursor_y, cursor_x);
} }
void move_cursor_on_screen(Editor* editor, int x, int y) { void move_cursor_on_screen(Editor* editor, int x, int y) {
add_toolbar(editor);
int newx = x + 5; // account for the line number
int max_x, max_y; int max_x, max_y;
getmaxyx(stdscr, max_y, max_x); getmaxyx(stdscr, max_y, max_x);
max_y--; // Reserve bottom line for toolbar
max_x -= 5; // Account for line number margin
bool flag = false; // Adjust x_offset if cursor would be off screen
if (x + 5 >= max_x + editor->x_offset) {
while (newx + 3 > max_x + editor->x_offset) { editor->x_offset = x - max_x + 6;
editor->x_offset += 1; }
flag = true; if (x < editor->x_offset) {
editor->x_offset = x;
} }
while (newx - 3 < editor->x_offset) { // Adjust y_offset if cursor would be off screen
editor->x_offset -= 1; if (y >= max_y + editor->y_offset) {
flag = true; editor->y_offset = y - max_y + 1;
}
if (y < editor->y_offset) {
editor->y_offset = y;
} }
while (y + 3 > max_y + editor->y_offset) { refresh_buffer(editor);
editor->y_offset += 1;
flag = true;
}
while (y - 3 < editor->y_offset) {
editor->y_offset -= 1;
flag = true;
}
if (flag) {
refresh_buffer(editor);
}
move(y - editor->y_offset, newx - editor->x_offset);
} }
void switch_mode(Editor* self) { void switch_mode(Editor* self) {
@@ -125,7 +145,6 @@ void newline(Editor* self) {
move(self->buffer_line, 0); move(self->buffer_line, 0);
char line_no[6]; char line_no[6];
snprintf(line_no, 6, "%-6d", self->buffer_line + 1); snprintf(line_no, 6, "%-6d", self->buffer_line + 1);
fprintf(stderr, "ln: %d, col: %d", self->buffer_line, self->buffer_col);
// add the line number // add the line number
attron(COLOR_PAIR(1)); attron(COLOR_PAIR(1));
@@ -134,7 +153,7 @@ void newline(Editor* self) {
move_cursor_on_screen(self, self->buffer_col, self->buffer_line); move_cursor_on_screen(self, self->buffer_col, self->buffer_line);
} }
Editor editor_from(String_t input_string) { Editor editor_from(String_t input_string, String_t filename) {
Editor e; Editor e;
e.lines = 0; e.lines = 0;
e.buffer_line = 0; e.buffer_line = 0;
@@ -143,24 +162,46 @@ Editor editor_from(String_t input_string) {
e.x_offset = 0; e.x_offset = 0;
e.editmode = false; e.editmode = false;
e.unsaved_changes = false; e.unsaved_changes = false;
e.filename = filename;
int linenum = 0; int linenum = 0;
e.buffer = str_lines(&input_string, &linenum); e.buffer = str_lines(&input_string, &linenum);
e.lines = (size_t)linenum; e.lines = (uint32_t)linenum;
e.capacity = e.lines;
str_dealloc(&input_string); str_dealloc(&input_string);
refresh_buffer(&e); refresh_buffer(&e);
return e; return e;
} }
Editor new_editor() { Editor new_editor(String_t filename) {
return editor_from(str_new()); return editor_from(str_new(), filename);
}
int save_file(Editor* self) {
char* name = to_chars(&self->filename);
// writes the content line by line to the file
FILE* file = fopen(name, "w");
for (size_t i = 0; i < self->lines; i++) {
if (str_to_file(&self->buffer[i], file) == -1) {
free(name);
fprintf(stderr, "Error writing to file\n");
return -1;
}
}
free(name);
fclose(file);
return 0;
} }
void move_cursor(Editor* self, int x, int y) { void move_cursor(Editor* self, int x, int y) {
if (y != 0 if (y != 0
&& (int)(self->buffer_line) + y >= 0 && (int)(self->buffer_line) + y >= 0
&& self->buffer_line + y <= self->lines) && self->buffer_line + y < self->lines)
{ {
// move the cursor up or down // move the cursor up or down
self->buffer_line += y; self->buffer_line += y;
@@ -174,17 +215,19 @@ void move_cursor(Editor* self, int x, int y) {
self->buffer_line -= 1; self->buffer_line -= 1;
self->buffer_col = str_len(&self->buffer[self->buffer_line]); self->buffer_col = str_len(&self->buffer[self->buffer_line]);
} }
} else if (self->buffer_col + x > str_len(&self->buffer[self->buffer_line])) { } else if (x != 0 && self->buffer_line < self->lines) {
// moving the cursor off the right hand side of the line int line_width = str_len(&self->buffer[self->buffer_line]);
if (self->buffer_line < self->lines) { if (self->buffer_col + x > line_width) {
self->buffer_col = 0; // moving the cursor off the right hand side of the line
self->buffer_line += 1; if (self->buffer_line + 1 < self->lines) {
self->buffer_col = 0;
self->buffer_line += 1;
}
} else {
// moving the cursor left or right in any other case
self->buffer_col += x;
} }
} else if (x != 0) {
// moving the cursor left or right in any other case
self->buffer_col += x;
} }
fprintf(stderr, "ln: %d, col: %d xoff: %d yoff: %d\n", self->buffer_line, self->buffer_col, self->x_offset, self->y_offset);
move_cursor_on_screen(self, self->buffer_col, self->buffer_line); move_cursor_on_screen(self, self->buffer_col, self->buffer_line);
} }
@@ -197,12 +240,22 @@ void delchar(Editor* self) {
return; return;
} }
// obtain string objects that reference the old lines.
String_t old_curr_line = self->buffer[self->buffer_line];
String_t old_next_line = self->buffer[self->buffer_line + 1];
// assign the new line
self->buffer[self->buffer_line] = str_merge(&self->buffer[self->buffer_line], &self->buffer[self->buffer_line + 1]); self->buffer[self->buffer_line] = str_merge(&self->buffer[self->buffer_line], &self->buffer[self->buffer_line + 1]);
// deallocate the memory for the old lines
str_dealloc(&old_curr_line);
str_dealloc(&old_next_line);
for (size_t i = self->buffer_line + 2; i < self->lines; i++) { for (size_t i = self->buffer_line + 2; i < self->lines; i++) {
self->buffer[i - 1] = self->buffer[i]; self->buffer[i - 1] = self->buffer[i];
} }
// replace the last line
self->buffer[self->lines - 1] = str_new(); self->buffer[self->lines - 1] = str_new();
self->lines--; self->lines--;
refresh_buffer(self); refresh_buffer(self);
@@ -219,7 +272,11 @@ void pressed_enter(Editor* self) {
// allocate memory immediately since we know a new line is being added // allocate memory immediately since we know a new line is being added
self->lines++; self->lines++;
self->buffer = realloc(self->buffer, sizeof(String_t) * (self->lines));
while (self->lines > self->capacity) {
self->capacity++;
}
self->buffer = (String_t*)realloc(self->buffer, sizeof(String_t) * (self->capacity));
if (self->buffer_line == self->lines -1) { if (self->buffer_line == self->lines -1) {
// if at end of file add an empty line // if at end of file add an empty line
@@ -230,6 +287,8 @@ void pressed_enter(Editor* self) {
self->buffer[i] = self->buffer[i - 1]; self->buffer[i] = self->buffer[i - 1];
} }
String_t old_line = self->buffer[self->buffer_line];
self->buffer[self->buffer_line + 1] = str_slice( self->buffer[self->buffer_line + 1] = str_slice(
&self->buffer[self->buffer_line], &self->buffer[self->buffer_line],
self->buffer_col, self->buffer_col,
@@ -241,6 +300,8 @@ void pressed_enter(Editor* self) {
0, 0,
self->buffer_col self->buffer_col
); );
str_dealloc(&old_line);
} }
// refresh the screen with the new data // refresh the screen with the new data
refresh_buffer(self); refresh_buffer(self);
@@ -257,7 +318,12 @@ void addchar(Editor* self, char c) {
// reallocate self->buffer to be 1 larger // reallocate self->buffer to be 1 larger
self->lines++; self->lines++;
self->buffer = realloc(self->buffer, sizeof(String_t) * (self->lines));
while (self->lines > self->capacity) {
self->capacity++;
}
self->buffer = (String_t*)realloc(self->buffer, sizeof(String_t) * (self->capacity));
// allocate the memory space for the new line and add it to the buffer // allocate the memory space for the new line and add it to the buffer
self->buffer[self->buffer_line] = str_new(); self->buffer[self->buffer_line] = str_new();
@@ -269,7 +335,14 @@ void addchar(Editor* self, char c) {
move_cursor(self, 1, 0); move_cursor(self, 1, 0);
} }
void shutdown_editor(Editor* self) {
for (size_t i = 0; i < self->capacity; i++) {
str_dealloc(&self->buffer[i]);
}
str_dealloc(&self->filename);
free(self->buffer);
}
String_t* to_string(Editor* self) { String_t* to_string(Editor* self) {
} }
+75 -2
View File
@@ -1,8 +1,13 @@
#include "dynstr.h" #include "dynstr.h"
#include <stdint.h> #include <stdint.h>
/**
* maintains the state of a text editor, including the text buffer,
* cursor position, and various editor settings.
*/
typedef struct { typedef struct {
uint32_t lines; uint32_t lines;
uint32_t capacity;
uint32_t buffer_line; uint32_t buffer_line;
uint32_t buffer_col; uint32_t buffer_col;
uint32_t y_offset; uint32_t y_offset;
@@ -10,16 +15,84 @@ typedef struct {
bool unsaved_changes; bool unsaved_changes;
bool editmode; bool editmode;
String_t* buffer; String_t* buffer;
String_t* original;
String_t filename;
} Editor; } Editor;
Editor new_editor(); /**
* Creates a new editor instance from a filename
*
* @param filename The name of the file to open
* @return Editor A new editor instance initialized with the file's content
*/
Editor new_editor(String_t filename);
Editor editor_from(String_t input_string); /**
* Creates a new editor instance from an input string
*
* @param input_string initial editor content
* @param filename name of the file being edited
* @return an instance of the editor
*/
Editor editor_from(String_t input_string, String_t filename);
/**
* Moves the cursor in the editor (relative to it's current position)
*
* @param self Pointer to the editor instance
* @param x Horizontal movement (negative for left, positive for right)
* @param y Vertical movement (negative for up, positive for down)
*/
void move_cursor(Editor* self, int x, int y); void move_cursor(Editor* self, int x, int y);
/**
* Deletes the character before the cursor
*
* @param self Pointer to the editor instance
*/
void delchar(Editor* self); void delchar(Editor* self);
/**
* Adds a character at the cursor position
*
* @param self Pointer to the editor instance
* @param c The character to add
*/
void addchar(Editor* self, char c); void addchar(Editor* self, char c);
/**
* Handles the enter key press, creating a new line
*
* @param self Pointer to the editor instance
*/
void pressed_enter(Editor* self); void pressed_enter(Editor* self);
/**
* Toggles between edit and command mode
*
* @param self Pointer to the editor instance
*/
void switch_mode(Editor* self); void switch_mode(Editor* self);
/**
* Cleans up and frees resources used by the editor
*
* @param self Pointer to the editor instance
*/
void shutdown_editor(Editor* self);
/**
* Saves the current buffer content to the file
*
* @param self Pointer to the editor instance
* @return int Returns 0 on success, non-zero on failure
*/
int save_file(Editor* self);
/**
* Converts the editor's buffer content to a String_t type
*
* @param self Pointer to the editor instance
* @return String_t* Pointer to a string containing the buffer content
*/
String_t* to_string(Editor* self); String_t* to_string(Editor* self);
-630
View File
@@ -1,630 +0,0 @@
starting editor openiing file somecode.cln: 1, col: 0 xoff: 0 yoff: 0
ln: 2, col: 0 xoff: 0 yoff: 0
ln: 3, col: 0 xoff: 0 yoff: 0
ln: 4, col: 0 xoff: 0 yoff: 0
ln: 5, col: 0 xoff: 0 yoff: 0
ln: 6, col: 0 xoff: 0 yoff: 0
ln: 7, col: 0 xoff: 0 yoff: 0
ln: 8, col: 0 xoff: 0 yoff: 0
ln: 9, col: 0 xoff: 0 yoff: 0
ln: 10, col: 0 xoff: 0 yoff: 0
ln: 11, col: 0 xoff: 0 yoff: 0
ln: 12, col: 0 xoff: 0 yoff: 0
ln: 13, col: 0 xoff: 0 yoff: 0
ln: 14, col: 0 xoff: 0 yoff: 0
ln: 15, col: 0 xoff: 0 yoff: 0
ln: 16, col: 0 xoff: 0 yoff: 0
ln: 17, col: 0 xoff: 0 yoff: 0
ln: 18, col: 0 xoff: 0 yoff: 0
ln: 19, col: 0 xoff: 0 yoff: 0
ln: 20, col: 0 xoff: 0 yoff: 0
ln: 21, col: 0 xoff: 0 yoff: 0
ln: 22, col: 0 xoff: 0 yoff: 0
ln: 23, col: 0 xoff: 0 yoff: 0
ln: 24, col: 0 xoff: 0 yoff: 0
ln: 25, col: 0 xoff: 0 yoff: 0
ln: 26, col: 0 xoff: 0 yoff: 0
ln: 27, col: 0 xoff: 0 yoff: 0
ln: 28, col: 0 xoff: 0 yoff: 0
ln: 29, col: 0 xoff: 0 yoff: 0
ln: 30, col: 0 xoff: 0 yoff: 0
ln: 31, col: 0 xoff: 0 yoff: 0
ln: 32, col: 0 xoff: 0 yoff: 0
ln: 33, col: 0 xoff: 0 yoff: 0
ln: 34, col: 0 xoff: 0 yoff: 0
ln: 35, col: 0 xoff: 0 yoff: 0
ln: 36, col: 0 xoff: 0 yoff: 0
ln: 37, col: 0 xoff: 0 yoff: 0
ln: 38, col: 0 xoff: 0 yoff: 0
ln: 39, col: 0 xoff: 0 yoff: 0
ln: 40, col: 0 xoff: 0 yoff: 0
ln: 41, col: 0 xoff: 0 yoff: 0
ln: 42, col: 0 xoff: 0 yoff: 0
ln: 43, col: 0 xoff: 0 yoff: 0
ln: 44, col: 0 xoff: 0 yoff: 0
ln: 45, col: 0 xoff: 0 yoff: 0
ln: 46, col: 0 xoff: 0 yoff: 0
ln: 47, col: 0 xoff: 0 yoff: 0
ln: 48, col: 0 xoff: 0 yoff: 0
ln: 49, col: 0 xoff: 0 yoff: 0
ln: 50, col: 0 xoff: 0 yoff: 0
ln: 51, col: 0 xoff: 0 yoff: 0
ln: 52, col: 0 xoff: 0 yoff: 0
ln: 53, col: 0 xoff: 0 yoff: 0
ln: 54, col: 0 xoff: 0 yoff: 0
ln: 55, col: 0 xoff: 0 yoff: 0
ln: 56, col: 0 xoff: 0 yoff: 0
ln: 57, col: 0 xoff: 0 yoff: 0
ln: 58, col: 0 xoff: 0 yoff: 0
ln: 59, col: 0 xoff: 0 yoff: 0
ln: 60, col: 0 xoff: 0 yoff: 0
ln: 61, col: 0 xoff: 0 yoff: 0
ln: 62, col: 0 xoff: 0 yoff: 0
ln: 63, col: 0 xoff: 0 yoff: 1
ln: 64, col: 0 xoff: 0 yoff: 2
ln: 65, col: 0 xoff: 0 yoff: 3
ln: 66, col: 0 xoff: 0 yoff: 4
ln: 67, col: 0 xoff: 0 yoff: 5
ln: 68, col: 0 xoff: 0 yoff: 6
ln: 69, col: 0 xoff: 0 yoff: 7
ln: 70, col: 0 xoff: 0 yoff: 8
ln: 71, col: 0 xoff: 0 yoff: 9
ln: 72, col: 0 xoff: 0 yoff: 10
ln: 73, col: 0 xoff: 0 yoff: 11
ln: 74, col: 0 xoff: 0 yoff: 12
ln: 75, col: 0 xoff: 0 yoff: 13
ln: 76, col: 0 xoff: 0 yoff: 14
ln: 77, col: 0 xoff: 0 yoff: 15
ln: 78, col: 0 xoff: 0 yoff: 16
ln: 79, col: 0 xoff: 0 yoff: 17
ln: 80, col: 0 xoff: 0 yoff: 18
ln: 81, col: 0 xoff: 0 yoff: 19
ln: 82, col: 0 xoff: 0 yoff: 20
ln: 83, col: 0 xoff: 0 yoff: 21
ln: 84, col: 0 xoff: 0 yoff: 22
ln: 85, col: 0 xoff: 0 yoff: 23
ln: 86, col: 0 xoff: 0 yoff: 24
ln: 87, col: 0 xoff: 0 yoff: 25
ln: 88, col: 0 xoff: 0 yoff: 26
ln: 89, col: 0 xoff: 0 yoff: 27
ln: 90, col: 0 xoff: 0 yoff: 28
ln: 91, col: 0 xoff: 0 yoff: 29
ln: 92, col: 0 xoff: 0 yoff: 30
ln: 93, col: 0 xoff: 0 yoff: 31
ln: 94, col: 0 xoff: 0 yoff: 32
ln: 95, col: 0 xoff: 0 yoff: 33
ln: 96, col: 0 xoff: 0 yoff: 34
ln: 97, col: 0 xoff: 0 yoff: 35
ln: 98, col: 0 xoff: 0 yoff: 36
ln: 99, col: 0 xoff: 0 yoff: 37
ln: 100, col: 0 xoff: 0 yoff: 38
ln: 101, col: 0 xoff: 0 yoff: 39
ln: 102, col: 0 xoff: 0 yoff: 40
ln: 103, col: 0 xoff: 0 yoff: 41
ln: 104, col: 0 xoff: 0 yoff: 42
ln: 105, col: 0 xoff: 0 yoff: 43
ln: 106, col: 0 xoff: 0 yoff: 44
ln: 107, col: 0 xoff: 0 yoff: 45
ln: 108, col: 0 xoff: 0 yoff: 46
ln: 109, col: 0 xoff: 0 yoff: 47
ln: 110, col: 0 xoff: 0 yoff: 48
ln: 111, col: 0 xoff: 0 yoff: 49
ln: 112, col: 0 xoff: 0 yoff: 50
ln: 113, col: 0 xoff: 0 yoff: 51
ln: 114, col: 0 xoff: 0 yoff: 52
ln: 115, col: 0 xoff: 0 yoff: 53
ln: 116, col: 0 xoff: 0 yoff: 54
ln: 117, col: 0 xoff: 0 yoff: 55
ln: 118, col: 0 xoff: 0 yoff: 56
ln: 119, col: 0 xoff: 0 yoff: 57
ln: 120, col: 0 xoff: 0 yoff: 58
ln: 121, col: 0 xoff: 0 yoff: 59
ln: 122, col: 0 xoff: 0 yoff: 60
ln: 123, col: 0 xoff: 0 yoff: 61
ln: 124, col: 0 xoff: 0 yoff: 62
ln: 125, col: 0 xoff: 0 yoff: 63
ln: 126, col: 0 xoff: 0 yoff: 64
ln: 127, col: 0 xoff: 0 yoff: 65
ln: 128, col: 0 xoff: 0 yoff: 66
ln: 129, col: 0 xoff: 0 yoff: 67
ln: 130, col: 0 xoff: 0 yoff: 68
ln: 131, col: 0 xoff: 0 yoff: 69
ln: 132, col: 0 xoff: 0 yoff: 70
ln: 133, col: 0 xoff: 0 yoff: 71
ln: 134, col: 0 xoff: 0 yoff: 72
ln: 135, col: 0 xoff: 0 yoff: 73
ln: 136, col: 0 xoff: 0 yoff: 74
ln: 137, col: 0 xoff: 0 yoff: 75
ln: 138, col: 0 xoff: 0 yoff: 76
ln: 139, col: 0 xoff: 0 yoff: 77
ln: 140, col: 0 xoff: 0 yoff: 78
ln: 141, col: 0 xoff: 0 yoff: 79
ln: 142, col: 0 xoff: 0 yoff: 80
ln: 143, col: 0 xoff: 0 yoff: 81
ln: 144, col: 0 xoff: 0 yoff: 82
ln: 145, col: 0 xoff: 0 yoff: 83
ln: 146, col: 0 xoff: 0 yoff: 84
ln: 147, col: 0 xoff: 0 yoff: 85
ln: 148, col: 0 xoff: 0 yoff: 86
ln: 149, col: 0 xoff: 0 yoff: 87
ln: 150, col: 0 xoff: 0 yoff: 88
ln: 151, col: 0 xoff: 0 yoff: 89
ln: 152, col: 0 xoff: 0 yoff: 90
ln: 153, col: 0 xoff: 0 yoff: 91
ln: 154, col: 0 xoff: 0 yoff: 92
ln: 155, col: 0 xoff: 0 yoff: 93
ln: 156, col: 0 xoff: 0 yoff: 94
ln: 157, col: 0 xoff: 0 yoff: 95
ln: 158, col: 0 xoff: 0 yoff: 96
ln: 159, col: 0 xoff: 0 yoff: 97
ln: 160, col: 0 xoff: 0 yoff: 98
ln: 161, col: 0 xoff: 0 yoff: 99
ln: 162, col: 0 xoff: 0 yoff: 100
ln: 163, col: 0 xoff: 0 yoff: 101
ln: 164, col: 0 xoff: 0 yoff: 102
ln: 165, col: 0 xoff: 0 yoff: 103
ln: 164, col: 0 xoff: 0 yoff: 104
ln: 163, col: 0 xoff: 0 yoff: 104
ln: 162, col: 0 xoff: 0 yoff: 104
ln: 161, col: 0 xoff: 0 yoff: 104
ln: 160, col: 0 xoff: 0 yoff: 104
ln: 159, col: 0 xoff: 0 yoff: 104
ln: 158, col: 0 xoff: 0 yoff: 104
ln: 157, col: 0 xoff: 0 yoff: 104
ln: 156, col: 0 xoff: 0 yoff: 104
ln: 155, col: 0 xoff: 0 yoff: 104
ln: 154, col: 0 xoff: 0 yoff: 104
ln: 153, col: 0 xoff: 0 yoff: 104
ln: 152, col: 0 xoff: 0 yoff: 104
ln: 151, col: 0 xoff: 0 yoff: 104
ln: 150, col: 0 xoff: 0 yoff: 104
ln: 149, col: 0 xoff: 0 yoff: 104
ln: 148, col: 0 xoff: 0 yoff: 104
ln: 147, col: 0 xoff: 0 yoff: 104
ln: 146, col: 0 xoff: 0 yoff: 104
ln: 145, col: 0 xoff: 0 yoff: 104
ln: 144, col: 0 xoff: 0 yoff: 104
ln: 143, col: 0 xoff: 0 yoff: 104
ln: 142, col: 0 xoff: 0 yoff: 104
ln: 141, col: 0 xoff: 0 yoff: 104
ln: 140, col: 0 xoff: 0 yoff: 104
ln: 139, col: 0 xoff: 0 yoff: 104
ln: 138, col: 0 xoff: 0 yoff: 104
ln: 137, col: 0 xoff: 0 yoff: 104
ln: 136, col: 0 xoff: 0 yoff: 104
ln: 135, col: 0 xoff: 0 yoff: 104
ln: 134, col: 0 xoff: 0 yoff: 104
ln: 133, col: 0 xoff: 0 yoff: 104
ln: 132, col: 0 xoff: 0 yoff: 104
ln: 131, col: 0 xoff: 0 yoff: 104
ln: 130, col: 0 xoff: 0 yoff: 104
ln: 129, col: 0 xoff: 0 yoff: 104
ln: 128, col: 0 xoff: 0 yoff: 104
ln: 127, col: 0 xoff: 0 yoff: 104
ln: 126, col: 0 xoff: 0 yoff: 104
ln: 125, col: 0 xoff: 0 yoff: 104
ln: 124, col: 0 xoff: 0 yoff: 104
ln: 123, col: 0 xoff: 0 yoff: 104
ln: 122, col: 0 xoff: 0 yoff: 104
ln: 121, col: 0 xoff: 0 yoff: 104
ln: 120, col: 0 xoff: 0 yoff: 104
ln: 119, col: 0 xoff: 0 yoff: 104
ln: 118, col: 0 xoff: 0 yoff: 104
ln: 117, col: 0 xoff: 0 yoff: 104
ln: 116, col: 0 xoff: 0 yoff: 104
ln: 115, col: 0 xoff: 0 yoff: 104
ln: 114, col: 0 xoff: 0 yoff: 104
ln: 113, col: 0 xoff: 0 yoff: 104
ln: 112, col: 0 xoff: 0 yoff: 104
ln: 111, col: 0 xoff: 0 yoff: 104
ln: 110, col: 0 xoff: 0 yoff: 104
ln: 109, col: 0 xoff: 0 yoff: 104
ln: 108, col: 0 xoff: 0 yoff: 104
ln: 107, col: 0 xoff: 0 yoff: 104
ln: 106, col: 0 xoff: 0 yoff: 104
ln: 105, col: 0 xoff: 0 yoff: 103
ln: 104, col: 0 xoff: 0 yoff: 102
ln: 103, col: 0 xoff: 0 yoff: 101
ln: 102, col: 0 xoff: 0 yoff: 100
ln: 101, col: 0 xoff: 0 yoff: 99
ln: 100, col: 0 xoff: 0 yoff: 98
ln: 99, col: 0 xoff: 0 yoff: 97
ln: 98, col: 0 xoff: 0 yoff: 96
ln: 97, col: 0 xoff: 0 yoff: 95
ln: 96, col: 0 xoff: 0 yoff: 94
ln: 97, col: 0 xoff: 0 yoff: 93
ln: 98, col: 0 xoff: 0 yoff: 93
ln: 99, col: 0 xoff: 0 yoff: 93
ln: 100, col: 0 xoff: 0 yoff: 93
ln: 101, col: 0 xoff: 0 yoff: 93
ln: 102, col: 0 xoff: 0 yoff: 93
ln: 103, col: 0 xoff: 0 yoff: 93
ln: 104, col: 0 xoff: 0 yoff: 93
ln: 105, col: 0 xoff: 0 yoff: 93
ln: 106, col: 0 xoff: 0 yoff: 93
ln: 107, col: 0 xoff: 0 yoff: 93
ln: 108, col: 0 xoff: 0 yoff: 93
ln: 109, col: 0 xoff: 0 yoff: 93
ln: 110, col: 0 xoff: 0 yoff: 93
ln: 111, col: 0 xoff: 0 yoff: 93
ln: 112, col: 0 xoff: 0 yoff: 93
ln: 113, col: 0 xoff: 0 yoff: 93
ln: 114, col: 0 xoff: 0 yoff: 93
ln: 115, col: 0 xoff: 0 yoff: 93
ln: 116, col: 0 xoff: 0 yoff: 93
ln: 117, col: 0 xoff: 0 yoff: 93
ln: 118, col: 0 xoff: 0 yoff: 93
ln: 119, col: 0 xoff: 0 yoff: 93
ln: 120, col: 0 xoff: 0 yoff: 93
ln: 121, col: 0 xoff: 0 yoff: 93
ln: 122, col: 0 xoff: 0 yoff: 93
ln: 123, col: 0 xoff: 0 yoff: 93
ln: 124, col: 0 xoff: 0 yoff: 93
ln: 125, col: 0 xoff: 0 yoff: 93
ln: 126, col: 0 xoff: 0 yoff: 93
ln: 127, col: 0 xoff: 0 yoff: 93
ln: 128, col: 0 xoff: 0 yoff: 93
ln: 129, col: 0 xoff: 0 yoff: 93
ln: 130, col: 0 xoff: 0 yoff: 93
ln: 131, col: 0 xoff: 0 yoff: 93
ln: 132, col: 0 xoff: 0 yoff: 93
ln: 133, col: 0 xoff: 0 yoff: 93
ln: 134, col: 0 xoff: 0 yoff: 93
ln: 135, col: 0 xoff: 0 yoff: 93
ln: 136, col: 0 xoff: 0 yoff: 93
ln: 137, col: 0 xoff: 0 yoff: 93
ln: 138, col: 0 xoff: 0 yoff: 93
ln: 139, col: 0 xoff: 0 yoff: 93
ln: 140, col: 0 xoff: 0 yoff: 93
ln: 141, col: 0 xoff: 0 yoff: 93
ln: 142, col: 0 xoff: 0 yoff: 93
ln: 143, col: 0 xoff: 0 yoff: 93
ln: 144, col: 0 xoff: 0 yoff: 93
ln: 145, col: 0 xoff: 0 yoff: 93
ln: 146, col: 0 xoff: 0 yoff: 93
ln: 147, col: 0 xoff: 0 yoff: 93
ln: 148, col: 0 xoff: 0 yoff: 93
ln: 149, col: 0 xoff: 0 yoff: 93
ln: 150, col: 0 xoff: 0 yoff: 93
ln: 151, col: 0 xoff: 0 yoff: 93
ln: 152, col: 0 xoff: 0 yoff: 93
ln: 153, col: 0 xoff: 0 yoff: 93
ln: 154, col: 0 xoff: 0 yoff: 93
ln: 155, col: 0 xoff: 0 yoff: 93
ln: 156, col: 0 xoff: 0 yoff: 94
ln: 157, col: 0 xoff: 0 yoff: 95
ln: 158, col: 0 xoff: 0 yoff: 96
ln: 159, col: 0 xoff: 0 yoff: 97
ln: 160, col: 0 xoff: 0 yoff: 98
ln: 161, col: 0 xoff: 0 yoff: 99
ln: 162, col: 0 xoff: 0 yoff: 100
ln: 163, col: 0 xoff: 0 yoff: 101
ln: 164, col: 0 xoff: 0 yoff: 102
ln: 165, col: 0 xoff: 0 yoff: 103
ln: 166, col: 0 xoff: 0 yoff: 104
ln: 167, col: 0 xoff: 0 yoff: 105
ln: 168, col: 0 xoff: 0 yoff: 106
ln: 169, col: 0 xoff: 0 yoff: 107
ln: 170, col: 0 xoff: 0 yoff: 108
ln: 171, col: 0 xoff: 0 yoff: 109
ln: 172, col: 0 xoff: 0 yoff: 110
ln: 173, col: 0 xoff: 0 yoff: 111
ln: 174, col: 0 xoff: 0 yoff: 112
ln: 175, col: 0 xoff: 0 yoff: 113
ln: 176, col: 0 xoff: 0 yoff: 114
ln: 177, col: 0 xoff: 0 yoff: 115
ln: 178, col: 0 xoff: 0 yoff: 116
ln: 179, col: 0 xoff: 0 yoff: 117
ln: 180, col: 0 xoff: 0 yoff: 118
ln: 181, col: 0 xoff: 0 yoff: 119
ln: 182, col: 0 xoff: 0 yoff: 120
ln: 183, col: 0 xoff: 0 yoff: 121
ln: 184, col: 0 xoff: 0 yoff: 122
ln: 185, col: 0 xoff: 0 yoff: 123
ln: 186, col: 0 xoff: 0 yoff: 124
ln: 187, col: 0 xoff: 0 yoff: 125
ln: 188, col: 0 xoff: 0 yoff: 126
ln: 189, col: 0 xoff: 0 yoff: 127
ln: 190, col: 0 xoff: 0 yoff: 128
ln: 191, col: 0 xoff: 0 yoff: 129
ln: 192, col: 0 xoff: 0 yoff: 130
ln: 193, col: 0 xoff: 0 yoff: 131
ln: 194, col: 0 xoff: 0 yoff: 132
ln: 195, col: 0 xoff: 0 yoff: 133
ln: 196, col: 0 xoff: 0 yoff: 134
ln: 197, col: 0 xoff: 0 yoff: 135
ln: 198, col: 0 xoff: 0 yoff: 136
ln: 199, col: 0 xoff: 0 yoff: 137
ln: 200, col: 0 xoff: 0 yoff: 138
ln: 201, col: 0 xoff: 0 yoff: 139
ln: 202, col: 0 xoff: 0 yoff: 140
ln: 203, col: 0 xoff: 0 yoff: 141
ln: 204, col: 0 xoff: 0 yoff: 142
ln: 205, col: 0 xoff: 0 yoff: 143
ln: 206, col: 0 xoff: 0 yoff: 144
ln: 207, col: 0 xoff: 0 yoff: 145
ln: 208, col: 0 xoff: 0 yoff: 146
ln: 209, col: 0 xoff: 0 yoff: 147
ln: 210, col: 0 xoff: 0 yoff: 148
ln: 211, col: 0 xoff: 0 yoff: 149
ln: 212, col: 0 xoff: 0 yoff: 150
ln: 213, col: 0 xoff: 0 yoff: 151
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 212, col: 0 xoff: 0 yoff: 152
ln: 211, col: 0 xoff: 0 yoff: 152
ln: 210, col: 0 xoff: 0 yoff: 152
ln: 211, col: 0 xoff: 0 yoff: 152
ln: 212, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 212, col: 0 xoff: 0 yoff: 152
ln: 211, col: 0 xoff: 0 yoff: 152
ln: 210, col: 0 xoff: 0 yoff: 152
ln: 209, col: 0 xoff: 0 yoff: 152
ln: 208, col: 0 xoff: 0 yoff: 152
ln: 207, col: 0 xoff: 0 yoff: 152
ln: 208, col: 0 xoff: 0 yoff: 152
ln: 209, col: 0 xoff: 0 yoff: 152
ln: 210, col: 0 xoff: 0 yoff: 152
ln: 209, col: 0 xoff: 0 yoff: 152
ln: 208, col: 0 xoff: 0 yoff: 152
ln: 207, col: 0 xoff: 0 yoff: 152
ln: 208, col: 0 xoff: 0 yoff: 152
ln: 209, col: 0 xoff: 0 yoff: 152
ln: 210, col: 0 xoff: 0 yoff: 152
ln: 209, col: 0 xoff: 0 yoff: 152
ln: 208, col: 0 xoff: 0 yoff: 152
ln: 207, col: 0 xoff: 0 yoff: 152
ln: 208, col: 0 xoff: 0 yoff: 152
ln: 209, col: 0 xoff: 0 yoff: 152
ln: 210, col: 0 xoff: 0 yoff: 152
ln: 211, col: 0 xoff: 0 yoff: 152
ln: 212, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 213, col: 0 xoff: 0 yoff: 152
ln: 212, col: 0 xoff: 0 yoff: 152
ln: 211, col: 0 xoff: 0 yoff: 152
ln: 210, col: 0 xoff: 0 yoff: 152
ln: 209, col: 0 xoff: 0 yoff: 152
ln: 208, col: 0 xoff: 0 yoff: 152
ln: 207, col: 0 xoff: 0 yoff: 152
ln: 206, col: 0 xoff: 0 yoff: 152
ln: 205, col: 0 xoff: 0 yoff: 152
ln: 204, col: 0 xoff: 0 yoff: 152
ln: 203, col: 0 xoff: 0 yoff: 152
ln: 202, col: 0 xoff: 0 yoff: 152
ln: 201, col: 0 xoff: 0 yoff: 152
ln: 200, col: 0 xoff: 0 yoff: 152
ln: 199, col: 0 xoff: 0 yoff: 152
ln: 198, col: 0 xoff: 0 yoff: 152
ln: 197, col: 0 xoff: 0 yoff: 152
ln: 196, col: 0 xoff: 0 yoff: 152
ln: 195, col: 0 xoff: 0 yoff: 152
ln: 194, col: 0 xoff: 0 yoff: 152
ln: 193, col: 0 xoff: 0 yoff: 152
ln: 192, col: 0 xoff: 0 yoff: 152
ln: 191, col: 0 xoff: 0 yoff: 152
ln: 190, col: 0 xoff: 0 yoff: 152
ln: 189, col: 0 xoff: 0 yoff: 152
ln: 188, col: 0 xoff: 0 yoff: 152
ln: 187, col: 0 xoff: 0 yoff: 152
ln: 186, col: 0 xoff: 0 yoff: 152
ln: 185, col: 0 xoff: 0 yoff: 152
ln: 184, col: 0 xoff: 0 yoff: 152
ln: 183, col: 0 xoff: 0 yoff: 152
ln: 182, col: 0 xoff: 0 yoff: 152
ln: 181, col: 0 xoff: 0 yoff: 152
ln: 180, col: 0 xoff: 0 yoff: 152
ln: 179, col: 0 xoff: 0 yoff: 152
ln: 178, col: 0 xoff: 0 yoff: 152
ln: 177, col: 0 xoff: 0 yoff: 152
ln: 176, col: 0 xoff: 0 yoff: 152
ln: 175, col: 0 xoff: 0 yoff: 152
ln: 174, col: 0 xoff: 0 yoff: 152
ln: 173, col: 0 xoff: 0 yoff: 152
ln: 172, col: 0 xoff: 0 yoff: 152
ln: 171, col: 0 xoff: 0 yoff: 152
ln: 170, col: 0 xoff: 0 yoff: 152
ln: 169, col: 0 xoff: 0 yoff: 152
ln: 168, col: 0 xoff: 0 yoff: 152
ln: 167, col: 0 xoff: 0 yoff: 152
ln: 166, col: 0 xoff: 0 yoff: 152
ln: 165, col: 0 xoff: 0 yoff: 152
ln: 164, col: 0 xoff: 0 yoff: 152
ln: 163, col: 0 xoff: 0 yoff: 152
ln: 162, col: 0 xoff: 0 yoff: 152
ln: 161, col: 0 xoff: 0 yoff: 152
ln: 160, col: 0 xoff: 0 yoff: 152
ln: 159, col: 0 xoff: 0 yoff: 152
ln: 158, col: 0 xoff: 0 yoff: 152
ln: 157, col: 0 xoff: 0 yoff: 152
ln: 156, col: 0 xoff: 0 yoff: 152
ln: 155, col: 0 xoff: 0 yoff: 152
ln: 154, col: 0 xoff: 0 yoff: 152
ln: 153, col: 0 xoff: 0 yoff: 151
ln: 152, col: 0 xoff: 0 yoff: 150
ln: 151, col: 0 xoff: 0 yoff: 149
ln: 150, col: 0 xoff: 0 yoff: 148
ln: 149, col: 0 xoff: 0 yoff: 147
ln: 148, col: 0 xoff: 0 yoff: 146
ln: 147, col: 0 xoff: 0 yoff: 145
ln: 146, col: 0 xoff: 0 yoff: 144
ln: 145, col: 0 xoff: 0 yoff: 143
ln: 144, col: 0 xoff: 0 yoff: 142
ln: 143, col: 0 xoff: 0 yoff: 141
ln: 142, col: 0 xoff: 0 yoff: 140
ln: 141, col: 0 xoff: 0 yoff: 139
ln: 140, col: 0 xoff: 0 yoff: 138
ln: 139, col: 0 xoff: 0 yoff: 137
ln: 138, col: 0 xoff: 0 yoff: 136
ln: 137, col: 0 xoff: 0 yoff: 135
ln: 136, col: 0 xoff: 0 yoff: 134
ln: 135, col: 0 xoff: 0 yoff: 133
ln: 134, col: 0 xoff: 0 yoff: 132
ln: 133, col: 0 xoff: 0 yoff: 131
ln: 132, col: 0 xoff: 0 yoff: 130
ln: 131, col: 0 xoff: 0 yoff: 129
ln: 130, col: 0 xoff: 0 yoff: 128
ln: 129, col: 0 xoff: 0 yoff: 127
ln: 128, col: 0 xoff: 0 yoff: 126
ln: 127, col: 0 xoff: 0 yoff: 125
ln: 126, col: 0 xoff: 0 yoff: 124
ln: 125, col: 0 xoff: 0 yoff: 123
ln: 124, col: 0 xoff: 0 yoff: 122
ln: 123, col: 0 xoff: 0 yoff: 121
ln: 122, col: 0 xoff: 0 yoff: 120
ln: 121, col: 0 xoff: 0 yoff: 119
ln: 120, col: 0 xoff: 0 yoff: 118
ln: 119, col: 0 xoff: 0 yoff: 117
ln: 118, col: 0 xoff: 0 yoff: 116
ln: 117, col: 0 xoff: 0 yoff: 115
ln: 116, col: 0 xoff: 0 yoff: 114
ln: 115, col: 0 xoff: 0 yoff: 113
ln: 114, col: 0 xoff: 0 yoff: 112
ln: 113, col: 0 xoff: 0 yoff: 111
ln: 112, col: 0 xoff: 0 yoff: 110
ln: 111, col: 0 xoff: 0 yoff: 109
ln: 110, col: 0 xoff: 0 yoff: 108
ln: 109, col: 0 xoff: 0 yoff: 107
ln: 108, col: 0 xoff: 0 yoff: 106
ln: 107, col: 0 xoff: 0 yoff: 105
ln: 106, col: 0 xoff: 0 yoff: 104
ln: 105, col: 0 xoff: 0 yoff: 103
ln: 104, col: 0 xoff: 0 yoff: 102
ln: 103, col: 0 xoff: 0 yoff: 101
ln: 102, col: 0 xoff: 0 yoff: 100
ln: 101, col: 0 xoff: 0 yoff: 99
ln: 100, col: 0 xoff: 0 yoff: 98
ln: 99, col: 0 xoff: 0 yoff: 97
ln: 98, col: 0 xoff: 0 yoff: 96
ln: 97, col: 0 xoff: 0 yoff: 95
ln: 96, col: 0 xoff: 0 yoff: 94
ln: 95, col: 0 xoff: 0 yoff: 93
ln: 94, col: 0 xoff: 0 yoff: 92
ln: 93, col: 0 xoff: 0 yoff: 91
ln: 92, col: 0 xoff: 0 yoff: 90
ln: 91, col: 0 xoff: 0 yoff: 89
ln: 90, col: 0 xoff: 0 yoff: 88
ln: 89, col: 0 xoff: 0 yoff: 87
ln: 88, col: 0 xoff: 0 yoff: 86
ln: 87, col: 0 xoff: 0 yoff: 85
ln: 86, col: 0 xoff: 0 yoff: 84
ln: 85, col: 0 xoff: 0 yoff: 83
ln: 84, col: 0 xoff: 0 yoff: 82
ln: 83, col: 0 xoff: 0 yoff: 81
ln: 82, col: 0 xoff: 0 yoff: 80
ln: 81, col: 0 xoff: 0 yoff: 79
ln: 80, col: 0 xoff: 0 yoff: 78
ln: 79, col: 0 xoff: 0 yoff: 77
ln: 78, col: 0 xoff: 0 yoff: 76
ln: 77, col: 0 xoff: 0 yoff: 75
ln: 76, col: 0 xoff: 0 yoff: 74
ln: 75, col: 0 xoff: 0 yoff: 73
ln: 74, col: 0 xoff: 0 yoff: 72
ln: 73, col: 0 xoff: 0 yoff: 71
ln: 72, col: 0 xoff: 0 yoff: 70
ln: 71, col: 0 xoff: 0 yoff: 69
ln: 70, col: 0 xoff: 0 yoff: 68
ln: 69, col: 0 xoff: 0 yoff: 67
ln: 68, col: 0 xoff: 0 yoff: 66
ln: 67, col: 0 xoff: 0 yoff: 65
ln: 66, col: 0 xoff: 0 yoff: 64
ln: 65, col: 0 xoff: 0 yoff: 63
ln: 64, col: 0 xoff: 0 yoff: 62
ln: 63, col: 0 xoff: 0 yoff: 61
ln: 62, col: 0 xoff: 0 yoff: 60
ln: 61, col: 0 xoff: 0 yoff: 59
ln: 60, col: 0 xoff: 0 yoff: 58
ln: 59, col: 0 xoff: 0 yoff: 57
ln: 58, col: 0 xoff: 0 yoff: 56
ln: 57, col: 0 xoff: 0 yoff: 55
ln: 56, col: 0 xoff: 0 yoff: 54
ln: 55, col: 0 xoff: 0 yoff: 53
ln: 54, col: 0 xoff: 0 yoff: 52
ln: 53, col: 0 xoff: 0 yoff: 51
ln: 52, col: 0 xoff: 0 yoff: 50
ln: 51, col: 0 xoff: 0 yoff: 49
ln: 50, col: 0 xoff: 0 yoff: 48
ln: 49, col: 0 xoff: 0 yoff: 47
ln: 48, col: 0 xoff: 0 yoff: 46
ln: 47, col: 0 xoff: 0 yoff: 45
ln: 46, col: 0 xoff: 0 yoff: 44
ln: 45, col: 0 xoff: 0 yoff: 43
ln: 44, col: 0 xoff: 0 yoff: 42
ln: 43, col: 0 xoff: 0 yoff: 41
ln: 42, col: 0 xoff: 0 yoff: 40
ln: 41, col: 0 xoff: 0 yoff: 39
ln: 40, col: 0 xoff: 0 yoff: 38
ln: 39, col: 0 xoff: 0 yoff: 37
ln: 38, col: 0 xoff: 0 yoff: 36
ln: 37, col: 0 xoff: 0 yoff: 35
ln: 36, col: 0 xoff: 0 yoff: 34
ln: 35, col: 0 xoff: 0 yoff: 33
ln: 34, col: 0 xoff: 0 yoff: 32
ln: 33, col: 0 xoff: 0 yoff: 31
ln: 32, col: 0 xoff: 0 yoff: 30
ln: 31, col: 0 xoff: 0 yoff: 29
ln: 30, col: 0 xoff: 0 yoff: 28
ln: 29, col: 0 xoff: 0 yoff: 27
ln: 28, col: 0 xoff: 0 yoff: 26
ln: 27, col: 0 xoff: 0 yoff: 25
ln: 26, col: 0 xoff: 0 yoff: 24
ln: 25, col: 0 xoff: 0 yoff: 23
ln: 24, col: 0 xoff: 0 yoff: 22
ln: 23, col: 0 xoff: 0 yoff: 21
ln: 22, col: 0 xoff: 0 yoff: 20
ln: 21, col: 0 xoff: 0 yoff: 19
ln: 20, col: 0 xoff: 0 yoff: 18
ln: 19, col: 0 xoff: 0 yoff: 17
ln: 18, col: 0 xoff: 0 yoff: 16
ln: 17, col: 0 xoff: 0 yoff: 15
ln: 16, col: 0 xoff: 0 yoff: 14
ln: 15, col: 0 xoff: 0 yoff: 13
ln: 14, col: 0 xoff: 0 yoff: 12
ln: 13, col: 0 xoff: 0 yoff: 11
ln: 12, col: 0 xoff: 0 yoff: 10
ln: 11, col: 0 xoff: 0 yoff: 9
ln: 10, col: 0 xoff: 0 yoff: 8
ln: 9, col: 0 xoff: 0 yoff: 7
ln: 8, col: 0 xoff: 0 yoff: 6
ln: 7, col: 0 xoff: 0 yoff: 5
ln: 6, col: 0 xoff: 0 yoff: 4
ln: 5, col: 0 xoff: 0 yoff: 3
+166 -18
View File
@@ -6,12 +6,13 @@
void help() { void help() {
printf("Usage:\n"); printf("Usage:\n");
printf(" cmd open <path/to/file> // opens the specified file\n"); printf(" cmd open <file/path> // opens the specified file\n");
printf(" cmd rm <path/to/file> // deletes the specified file\n"); printf(" cmd rm <file/path> // deletes the specified file\n");
printf(" cmd new <path/to/file> // creates a new empty file at the specified path\n"); printf(" cmd new <file/path> // creates a new empty file at the specified path\n");
printf(" cmd mv <path/to/file> <new/path> // moves the specified file to the new path\n"); printf(" cmd mv <old/path> <new/path> // moves the specified file to the new path\n");
printf(" cmd cp <path/to/file> <new/path> // copies the specified file to the new path\n"); printf(" cmd cp <old/path> <new/path> // copies the specified file to the new path\n");
printf(" cmd len <path/to/file> // returns the length of the specified file\n"); printf(" cmd lenl <file/path> // returns the length of the specified file in lines\n");
printf(" cmd lenc <file/path> // returns the length of the specified file in chars\n");
printf(" cmd log // prints a list of all changes made to the file\n"); printf(" cmd log // prints a list of all changes made to the file\n");
} }
@@ -33,9 +34,9 @@ int open_editor(char* filename) {
Editor editor; Editor editor;
if (strcmp(filename, "") == 0) { if (strcmp(filename, "") == 0) {
editor = new_editor(); editor = new_editor(str_from_chars(filename));
} else { } else {
editor = editor_from(str_from_file(fopen(filename, "r"))); editor = editor_from(str_from_file(fopen(filename, "r")), str_from_chars(filename));
} }
while (true) { while (true) {
refresh(); refresh();
@@ -68,7 +69,6 @@ int open_editor(char* filename) {
move_cursor(&editor, 1, 0); move_cursor(&editor, 1, 0);
break; break;
default: default:
fprintf(stderr, "%d\n", c);
addchar(&editor, c); addchar(&editor, c);
break; break;
} }
@@ -76,12 +76,15 @@ int open_editor(char* filename) {
switch (c) { switch (c) {
case 'q': case 'q':
endwin(); endwin();
shutdown_editor(&editor);
return 0; return 0;
case 'i': case 'i':
switch_mode(&editor); switch_mode(&editor);
break; break;
case 'w': case 'w':
editor.unsaved_changes = false; editor.unsaved_changes = false;
save_file(&editor);
// TODO: write function to save the data to a file // TODO: write function to save the data to a file
break; break;
default: default:
@@ -91,16 +94,161 @@ int open_editor(char* filename) {
} }
} }
int main(int argc, char* argv[]) { // Copies a file from source to destination
if (argc == 1) { int copy_file(const char* source, const char* dest) {
Editor e = new_editor(); FILE* src = fopen(source, "rb");
open_editor(""); if (src == NULL) {
} else if (argc == 3) { fprintf(stderr, "Error: Could not open source file %s\n", source);
if (strcmp(argv[1], "open") == 0) { return -1;
fprintf(stderr, "starting editor openiing file %s", argv[2]);
open_editor(argv[2]);
}
} }
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; 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[]) {
if (argc < 2) {
help();
return 1;
}
CommandType cmd = str_to_cmd(argv[1]);
if (argc == 3) {
switch (cmd) {
case CMD_OPEN:
open_editor(argv[2]);
break;
case CMD_RM:
remove(argv[2]);
break;
case CMD_NEW:
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]);
}
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]);
}
break;
default:
help();
}
}
else {
printf("invalid options\n");
help();
}
return 0;
}