added documentation, almost done with code
This commit is contained in:
+82
-81
@@ -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
@@ -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
|
||||||
|
|||||||
+134
-61
@@ -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++) {
|
||||||
// adding the line number
|
move(i - self->y_offset, 0);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
addstr(to_chars(&line_segment));
|
if (visible_start < line_len) {
|
||||||
str_dealloc(&line_segment);
|
String_t line_segment = str_slice(
|
||||||
|
&self->buffer[i],
|
||||||
|
visible_start,
|
||||||
|
visible_end
|
||||||
|
);
|
||||||
|
|
||||||
addstr("\n");
|
char* data = to_chars(&line_segment);
|
||||||
|
|
||||||
|
addstr(data);
|
||||||
|
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
@@ -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
@@ -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
|
|
||||||
|
|
||||||
+165
-17
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user