commit 283b2dd167101436795984f257f59b0161e102d4 Author: anon <anon@anon.anon> Date: Fri Mar 1 22:05:18 2024 +0100 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0bc4eca --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.gdb_history +fu-shell +*.yy.* +*.o +*.out diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d2673e8 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +CXXFLAGS := --std=c++17 -ggdb +LDLIBS := $$(pkg-config --cflags --libs readline) -lboost_system + +%.yy.c: %.l + flex -o $@ --header-file=$*.yy.h $< + +%.yy.o: %.yy.c + ${COMPILE.c} $< -o $@ + +%.o: %.cpp + ${COMPILE.cpp} $< -o $@ + +main: lisp_balance.yy.o main.o + ${LINK.cpp} -o fu-shell $+ ${LDLIBS} + +clean: + rm *.o diff --git a/lisp_balance.h b/lisp_balance.h new file mode 100644 index 0000000..47707df --- /dev/null +++ b/lisp_balance.h @@ -0,0 +1,9 @@ +#ifndef LISP_BANALNCE_H +#define LISP_BANALNCE_H +// Return values: +enum { + FULL = 0, // the provided statement seems complete + PARTIAL, // the provided statement is not closed + BROKEN, // the provided is all fucked'n'shieet +}; +#endif diff --git a/lisp_balance.l b/lisp_balance.l new file mode 100644 index 0000000..d241fc4 --- /dev/null +++ b/lisp_balance.l @@ -0,0 +1,53 @@ +%{ + #include "lisp_balance.h" + static int paren_stack = 0; + + static char * lb_input; + static int len; + static int offset; + + void lb_set_input(char * const s) { + lb_input = s; + len = strlen(lb_input); + offset = len; + } + + #define YY_INPUT(buf, result, max_size) { \ + int cpi = (offset && offset > max_size) ? max_size : offset; \ + memcpy(buf, lb_input+(len-offset), cpi); \ + result = cpi; \ + offset = (cpi > offset) ? 0 : offset - cpi; \ + } +%} + +%option noyywrap +%option nodefault + +%x LITERAL +%% +<INITIAL>{ +\( { ++paren_stack; } +\) { + if (paren_stack >= 0) { + --paren_stack; + } else { + return BROKEN; + } + } +\" { BEGIN LITERAL; } +.|\n { ; } +<<EOF>> { + if (paren_stack == 0) { + return FULL; + } else { + return PARTIAL; + } + } +} + +<LITERAL>{ +\" { BEGIN INITIAL; } +.|\n { ; } +<<EOF>> { return PARTIAL; } +} +%% diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..4536ea0 --- /dev/null +++ b/main.cpp @@ -0,0 +1,123 @@ +#include <stdio.h> +#include <stdlib.h> +#include <readline/readline.h> +#include <boost/asio.hpp> + +#include "lisp_balance.h" +#include "lisp_balance.yy.h" + +using namespace boost::asio; + +#define PS1 "> " + +io_service hio_service; +ip::tcp::socket hsocket(hio_service); + +bool fu_connect() { + ip::tcp::endpoint endpoint(ip::address::from_string("127.0.0.1"), 10008); + hsocket.connect(endpoint); + + return true; +} + +char * transmit(const char * const s) { + static char reply[1024]; + try { + std::string message = s; + message = std::string() + (char)0x47 + (char)(message.size() / 256) + (char)(message.size() % 256) + message; + boost::system::error_code error; + write(hsocket, buffer(message), error); + if (error) { + throw boost::system::system_error(error); + } + + size_t reply_length = hsocket.read_some(buffer(reply), error); + if (error) { + throw boost::system::system_error(error); + } + return reply; + } catch (std::exception& e) { + puts(e.what()); + return NULL; + } +} + +int special(const char * const l) { + if (!strcmp(l, ".exit")) { + return 1; + } else if (!strcmp(l, ".connect ")) { + } else if (!strcmp(l, ".ping")) { + } + + return 0; +} + +void put_response(const char * const s) { + /* The script-fu server protocol uses leading bytes + * to communicate meta information for clients + * YYY: https://docs.gimp.org/2.10/en/gimp-filters-script-fu.html#plug-in-script-fu-console + */ + enum { + MAGIC_BYTE, + ERROR_CODE, + LEN_HIGH, + LEN_LOW, + LEADING_META_SIZE, + }; + const char * const msg = s + LEADING_META_SIZE; + + printf("high: %d low: %d", s[LEN_HIGH], s[LEN_LOW]); + + if (!s[ERROR_CODE]) { + fputs("\033[32m", stdout); + } else { + fputs("\033[31m", stdout); + } + + for (int i = 0, h = s[LEN_HIGH]; i != h; i++) { + puts("f"); + fwrite((msg + LEADING_META_SIZE) + (i*256), 256, sizeof(char), stdout); + } + fwrite(msg + (s[LEN_HIGH]*256), s[LEN_LOW], sizeof(char), stdout); + + fputs("\033[0m", stdout); +} + +bool fu_judge(const char * const input) { + bool r; + if (special(input)) { + return true; + } + + char * const cpy = strdup(input); + lb_set_input(input); + + const int p = lb_parse(); + switch (p) { + default: { + r = false; + }; + } + + put_response(transmit(input)); + free(cpy); + return r; +} + +bool fu_interpret() { + bool r; + char * input = readline(PS1); + r = fu_judge(); + + free(input); + return r; +} + +signed main() { + if (not fu_connect()) { + return 1; + } + + while(fu_interpret()) { ; } + return 0; +}