mirror of
1
0
Fork 0
ped/src/ped.c

498 lines
8.3 KiB
C

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include "ped.h"
#include "types.h"
#include<dlfcn.h>
int main(int argc, char** args)
{
/* Make sure we have only two arguments */
if(argc == 2)
{
/* Get the filename */
char* filename = *(args+1);
/* Create a new session */
struct Session* session = newSession(filename);
if(session)
{
/* Open the editor */
newEditor(session);
/* Free the session */
free(session);
}
}
else
{
printf("Too many args, or missing a file.\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
void ttyPut(struct Session* session, char byte)
{
output(&byte, 1);
/* Check if the byte if not a line feed */
if(byte != 10)
{
session->teletype->cursorX++;
}
/* If the byte is a linefeed */
else if(byte == 10)
{
session->teletype->cursorY++;
}
else if(byte == 13)
{
session->teletype->cursorX = 0;
}
}
/**
* Moves us back to the beginning of the terminal
*/
void goHome(struct Session* session)
{
/* Move up */
while(session->teletype->cursorY)
{
char seq[3] = {27, 91, 65};
output(seq, 3);
session->teletype->cursorY--;
}
/* tty put carriage return */
ttyPut(session, 13);
}
/**
* Moves the tty cursor to session->fileX and session->fileY
*/
void moveToFilePos(struct Session* session)
{
unsigned int i = 0;
/* Move editor cursor to x-offset */
i = 0;
while(i < session->fileX)
{
session->teletype->cursorX++;
char seq[3] = {27,91,67};
output(seq, 3);
i++;
}
/* Move editor cursor to y-offset */
i = 0;
while(i < session->fileY)
{
char seq[3] = {27,91,66};
output(seq, 3);
session->teletype->cursorY++;
i++;
}
}
/**
* Draws the header line
*/
void statusDraw(struct Session* session)
{
/* General counter */
unsigned int i = 0;
/* This moves y and x back to 0,0 back up */
goHome(session);
/* Get the length of the status line */
unsigned int statusLength = strlen(session->status);
char* statusLine = session->status;
while(i< statusLength)
{
char byte = *(statusLine+i);
ttyPut(session, byte);
i++;
}
/* Move us down */
ttyPut(session, 10);
/* Slam that carriage back */
ttyPut(session, 13);
}
void loadPlugins()
{
}
void runDrawPlugins(struct Session* session)
{
/* TODO: This is to load zifty, this should be a loop form a file */
void* dynObjHandle = dlopen("zifty.o", RTLD_NOW);
void (*funcPtr)(struct Session*) = dlsym(dynObjHandle, "dispatch");
funcPtr(session);
}
void redraw(struct Session* session)
{
/* Run all plugins that run on draw */
runDrawPlugins(session);
/* Draw the status line */
statusDraw(session);
/* Move cursor back home */
char cr = 13;
/* Write all the buffer data */
unsigned int i = 0;
while(i < session->size)
{
char byte = *(session->data+i);
if(byte == 10)
{
output("\n",1);
output("\r",1);
session->teletype->cursorX=0;
session->teletype->cursorY++;
}
else
{
ttyPut(session, *(session->data+i));
}
i++;
}
/* First we go home and down a line */
goHome(session);
ttyPut(session, 10);
/* Applies the file cursor position to the tty */
moveToFilePos(session);
}
void initialDisplay(struct Session* session)
{
unsigned int i = 0;
while(i < session->size)
{
char byte = *(session->data+i);
/* If the file contains a new line */
if(byte == 10)
{
/**
* If the file contains a new line
* then we move down and back.
*
* And increment cursor for file.
*/
// ttyPut(session, 10);
// ttyPut(session, 13);
session->fileY++;
session->fileX = 0;
}
else
{
// ttyPut(session, byte);
session->fileX++;
}
i++;
}
}
unsigned int map(struct Session* session)
{
char* dataBuffer = session->data;
unsigned int dataBufferLength = session->size;
unsigned int lineFeeds = session->fileY;
unsigned int lfOccs = lineFeeds;
unsigned int i = 0;
while(i < session->size && lfOccs)
{
char byte = *(session->data+i);
if(byte == 10)
{
lfOccs--;
}
i++;
}
return i;
}
void newEditor(struct Session* session)
{
/* Setup the tty */
startTTY();
initialDisplay(session);
/* Output the file as of now */
redraw(session);
/* Update the tty's dimensions */
updateDimensions(session->teletype);
/* Debugging */
//debugTTY(open("/dev/pts/18",O_RDWR), session->teletype);
//output("hello world", strlen("hello world"));
while(session->isActive)
{
char s;
s=getChar();
if (s == 17)
{
session->isActive = 0;
}
/* Control */
else if(s == 27)
{
/* Arrow keys */
s=getChar();
if(s == 91)
{
s=getChar();
char seq[3];
/* Up arrow */
if(s == 65)
{
if(session->fileY)
{
session->fileY--;
}
}
/* Down arrow */
else if (s == 66)
{
session->fileY++;
}
/* Right arrow */
else if(s == 67)
{
seq[0] = 27;
seq[1] = 91;
seq[2] = 67;
session->fileX++;
}
/* Left arrow */
else if (s == 68)
{
seq[0] = 27;
seq[1] = 91;
seq[2] = 68;
/* Only move cursor back if we not at home */
if(session->fileX)
{
session->fileX--;
}
}
// output(seq, 3);
//continue;
}
}
/* Ctrl+D is command key */
else if(s == 4)
{
char* str = malloc(20);
*str = 0;
unsigned int i = 0;
while(1)
{
s=getChar();
if(s==4)
{
break;
}
else
{
strncat(str, &s, 1);
}
i++;
if(i==20)
{
str=realloc(str, i+20);
i=0;
}
}
//output(str,strlen(str));
if(strlen(str) > 0)
{
runCommand(str, session);
}
free(str);
}
else
{
/* `newLineAfterOffset` is the offset to the character after `\n` */
unsigned int newLineAfterOffset = map(session);
/* `finalOffset` is the new line offset with file cursor */
unsigned int finalOffset = newLineAfterOffset+session->fileX;
/**
* If the final linear address is greater-then
* or equal to the current size we must then
* expand the buffer.
*/
if(finalOffset >= session->size)
{
/* Increase the size by fFInal-session->size */
session->size = finalOffset+session->fileX;
}
else
{
}
/* Set data at current position */
*(session->data+finalOffset) = s;
/* TODO: As we type position increases */
session->fileX++;
//session->teletype->cursorX++;
//strncat(session->data, &s, 1);
}
//printf("%c\n",s);
// char* l = malloc(20);
// sprintf(l, "%u", s);
// output(l, strlen(l));
// output(&s, 1);
/* Update the tty's dimensions */
updateDimensions(session->teletype);
//debugTTY(open("/dev/pts/18",O_RDWR), session->teletype);
/* Redraw */
redraw(session);
}
char* bye = "\nBye mate!\n";
output(bye, strlen(bye));
/* Clean up commands */
/* Restore tty settings */
stopTTY();
}
struct TTY* newTTY()
{
struct TTY* tty = malloc(sizeof(struct TTY));
updateDimensions(tty);
return tty;
}
struct Session* newSession(char* filename)
{
/* Allocate the session */
struct Session* session = malloc(sizeof(struct Session));
/* Make sure it allocated */
if(session)
{
/* Open the file */
int fd = open(filename, O_CREAT|O_RDWR);
if(fd >= 0)
{
/* Set the file descriptor */
session->fd = fd;
/* Set name */
session->name = filename;
/* Get the stat struct */
struct stat statStruct;
/* Fill stat struct */
fstat(fd, &statStruct);
/* Set the initial size */
session->size = statStruct.st_size;
/* Allocate initial space for buffer */
/* TODO: Remove and be dynamic */
session->data = malloc(session->size+69);
/* Set the initial characters */
read(fd, session->data, session->size);
char* temp = malloc(session->size+1);
strncpy(temp, session->data, session->size);
//printf("%s", temp);
/* TODO: Use xy :: Set initial position to 0 */
//session->fileX = session->size;
session->fileX = 0;
session->fileY = 0;
//session->fileY = linefeedCount(session->data, session->size);
/* Set the tty */
session->teletype = newTTY();
//session->teletype->cursorX = session->fileX;
/* Set the session to active */
session->isActive = 1;
/* On success, return the pointer to the session */
return session;
}
/* On successful malloc, but file failure */
free(session);
}
/* On error */
return 0;
}