[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[COMMITTED] poked: Add auto-completion channel
From: |
Mohammad-Reza Nabipoor |
Subject: |
[COMMITTED] poked: Add auto-completion channel |
Date: |
Tue, 22 Mar 2022 20:25:32 +0430 |
2022-03-22 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
* poked/usock.h (USOCK_CHAN_IN_AUTOCMPL): New macro.
(USOCK_CHAN_OUT_AUTOCMPL): Likewise.
* poked/poked.c (AUTOCMPL_IDENT): New macro.
(AUTOCMPL_IOS): Likewise.
(struct bufb): New struct for byte buffer.
(bufb_init): New function.
(bufb_realloc): Likewise.
(bufb_append): Likewise.
(bufb_free): Likewise.
(poked_compile): New function. Move all compilation logic to this
function.
(main): Add auto-completion channel.
---
Auto-completion:
- Input channel: 3
- Output channel: 5
- Spec:
var AUTOCMPL_IDENT = 1UB,
AUTOCMPL_IOS = 2UB;
type AutoCmpl_Input_Payload = struct
{
byte cmd in [AUTOCMPL_IDENT, AUTOCMPL_IOS];
string txt;
};
type AutoCmpl_Output_Payload = struct
{
byte kind in [AUTOCMPL_IDENT, AUTOCMPL_IOS];
string[] candidates;
};
Regards,
Mohammad-Reza
ChangeLog | 15 +++
poked/poked.c | 317 +++++++++++++++++++++++++++++++++++++-------------
poked/usock.h | 2 +
3 files changed, 253 insertions(+), 81 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 73572766..dba44a84 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2022-03-22 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
+
+ * poked/usock.h (USOCK_CHAN_IN_AUTOCMPL): New macro.
+ (USOCK_CHAN_OUT_AUTOCMPL): Likewise.
+ * poked/poked.c (AUTOCMPL_IDENT): New macro.
+ (AUTOCMPL_IOS): Likewise.
+ (struct bufb): New struct for byte buffer.
+ (bufb_init): New function.
+ (bufb_realloc): Likewise.
+ (bufb_append): Likewise.
+ (bufb_free): Likewise.
+ (poked_compile): New function. Move all compilation logic to this
+ function.
+ (main): Add auto-completion channel.
+
2022-03-22 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
* libpoke/libpoke.c (struct _pk_compiler): Add auto completion
diff --git a/poked/poked.c b/poked/poked.c
index 91fa5a3e..e8a36fbe 100644
--- a/poked/poked.c
+++ b/poked/poked.c
@@ -54,6 +54,9 @@ static void poked_free (void);
#define VUCMD_FILTER 4
#define VUCMD_FINISH 5
+#define AUTOCMPL_IDENT 1
+#define AUTOCMPL_IOS 2
+
static uint8_t termout_chan = USOCK_CHAN_OUT_OUT;
static uint32_t termout_cmdkind = OUTCMD_TXT;
@@ -152,6 +155,148 @@ iteration_end (struct usock *srv, uint64_t n_iteration)
#define iteration_send private_
+//--- byte buffer
+
+struct bufb
+{
+ unsigned char *mem;
+ unsigned char *end;
+ unsigned char *cur;
+};
+
+static int
+bufb_init (struct bufb *b, unsigned char *mem, size_t nelem)
+{
+ if (mem == NULL)
+ return NOK;
+ b->mem = mem;
+ b->end = mem + nelem;
+ b->cur = mem;
+ return OK;
+}
+
+static int
+bufb_realloc (struct bufb *b, size_t nelem)
+{
+ unsigned char *p
+ = (unsigned char *)realloc (b->mem, nelem * sizeof (unsigned char));
+
+ if (p == NULL)
+ return NOK;
+ b->cur = p + (b->cur - b->mem);
+ b->mem = p;
+ b->end = p + nelem;
+ return OK;
+}
+
+static int
+bufb_append (struct bufb *b, void *data, size_t len)
+{
+ size_t brem = b->end - b->cur;
+
+ if (brem < len)
+ {
+ size_t blen = b->cur - b->mem;
+ size_t cap = blen + len + 64;
+
+ if (bufb_realloc (b, cap) != OK)
+ return NOK;
+ }
+ memcpy (b->cur, data, len);
+ b->cur += len;
+ return OK;
+}
+
+static void
+bufb_free (struct bufb *b)
+{
+ if (b && b->mem)
+ {
+ free (b->mem);
+ memset (b, 0, sizeof (*b));
+ }
+}
+
+//---
+
+static int
+poked_compile (const char *src, uint8_t chan, int *poked_restart_p,
+ int *done_p)
+{
+ int ok = 0;
+ pk_val exc;
+
+ switch (chan)
+ {
+ case USOCK_CHAN_IN_CODE:
+ {
+ if (pk_compile_buffer (pkc, src, NULL, &exc) == PK_OK)
+ {
+ if (exc != PK_NULL)
+ (void)pk_call (pkc, pk_decl_val (pkc, "poked_ehandler"), NULL,
+ NULL, 1, exc);
+ else
+ ok = 1;
+ }
+ }
+ break;
+ case USOCK_CHAN_IN_CMD:
+ {
+ pk_val val;
+
+ if (pk_compile_statement (pkc, src, NULL, &val, &exc) == PK_OK)
+ {
+ if (exc != PK_NULL)
+ (void)pk_call (pkc, pk_decl_val (pkc, "poked_ehandler"), NULL,
+ NULL, 1, exc);
+ else if (val != PK_NULL)
+ {
+ ok = 1;
+ termout_eval ();
+ pk_print_val (pkc, val, &exc);
+ termout_restore ();
+ }
+ (void)pk_call (pkc,
+ pk_decl_val (pkc, "__poked_run_after_cmd_hooks"),
+ NULL, &exc, 0);
+ if (exc != PK_NULL)
+ (void)pk_call (pkc, pk_decl_val (pkc, "poked_ehandler"), NULL,
+ NULL, 1, exc);
+ }
+ }
+ break;
+ default:
+ assert (0 && "impossible");
+ }
+ if (pk_int_value (pk_decl_val (pkc, "__poked_restart_p")))
+ {
+ *poked_restart_p = 1;
+ return ok;
+ }
+ if (pk_int_value (pk_decl_val (pkc, "__poked_exit_p")))
+ {
+ *done_p = 1;
+ return ok;
+ }
+ if (pk_int_value (pk_decl_val (pkc, "__vu_do_p")))
+ {
+ const char *filt = pk_string_str (pk_decl_val (pkc, "__vu_filter"));
+
+ usock_out (srv, USOCK_CHAN_OUT_VU, VUCMD_FILTER, filt,
+ strlen (filt) + 1);
+ usock_out (srv, USOCK_CHAN_OUT_VU, VUCMD_CLEAR, "", 1);
+ termout_vu_append ();
+ (void)pk_call (pkc, pk_decl_val (pkc, "__vu_dump"), NULL, &exc, 0);
+ assert (exc == PK_NULL);
+ termout_restore ();
+ usock_out (srv, USOCK_CHAN_OUT_VU, VUCMD_FINISH, "", 1);
+ }
+ if (pk_int_value (pk_decl_val (pkc, "__poked_chan_send_p")))
+ poked_buf_send ();
+
+ return ok;
+}
+
//--- command line options
static void
@@ -240,9 +385,8 @@ main (int argc, char *argv[])
pthread_t th;
pthread_attr_t thattr;
- struct usock_buf *inbuf;
void *ret;
- int done_p = 0;
+ int poked_restart_p;
uint64_t n_iteration;
poked_options_init (argc, argv);
@@ -259,112 +403,123 @@ main (int argc, char *argv[])
printf ("socket_path %s\n\n", poked_options.socket_path);
poked_restart:
+ poked_restart_p = 0;
n_iteration = 0;
poked_init ();
- while (!done_p)
+ while (1)
{
- char *src;
- size_t srclen;
- int ok;
- pk_val exc;
+ struct usock_buf *inbuf;
inbuf = usock_in (srv);
for (; inbuf; inbuf = usock_buf_free (inbuf))
{
- src = (char *)usock_buf_data (inbuf, &srclen);
- if (srclen == 0)
- {
- printf ("srclen == 0\n");
- continue;
- }
-
- if (poked_options.debug_p)
- printf ("< '%.*s'\n", (int)srclen, src);
-
- n_iteration++;
- iteration_begin (srv, n_iteration);
+ int done_p = 0;
+ uint8_t chan = usock_buf_tag (inbuf) & 0x7f;
- ok = 0;
- switch (usock_buf_tag (inbuf) & 0x7f)
+ switch (chan)
{
case USOCK_CHAN_IN_CODE:
+ case USOCK_CHAN_IN_CMD:
{
- if (pk_compile_buffer (pkc, src, NULL, &exc) == PK_OK)
+ char *src;
+ size_t srclen;
+
+ src = (char *)usock_buf_data (inbuf, &srclen);
+ if (srclen == 0)
{
- if (exc != PK_NULL)
- (void)pk_call (pkc, pk_decl_val (pkc, "poked_ehandler"),
- NULL, NULL, 1, exc);
- else
- ok = 1;
+ if (poked_options.debug_p)
+ printf ("srclen == 0\n");
+ goto eol;
+ }
+ if (poked_options.debug_p)
+ printf ("< '%.*s'\n", (int)srclen, src);
+ n_iteration++;
+ iteration_begin (srv, n_iteration);
+ poked_compile (src, chan, &poked_restart_p, &done_p);
+ iteration_end (srv, n_iteration);
+ if (poked_restart_p)
+ {
+ usock_buf_free_chain (inbuf);
+ poked_free ();
+ goto poked_restart;
+ }
+ if (done_p)
+ {
+ usock_buf_free_chain (inbuf);
+ goto done;
}
}
break;
- case USOCK_CHAN_IN_CMD:
+ case USOCK_CHAN_IN_AUTOCMPL:
{
- pk_val val;
-
- if (pk_compile_statement (pkc, src, NULL, &val, &exc) == PK_OK)
+ struct bufb b;
+ char *candidate;
+ unsigned char *data;
+ size_t data_len;
+ unsigned char cmd;
+
+ data = usock_buf_data (inbuf, &data_len);
+ if (data_len == 0)
{
- if (exc != PK_NULL)
- (void)pk_call (pkc, pk_decl_val (pkc, "poked_ehandler"),
- NULL, NULL, 1, exc);
- else if (val != PK_NULL)
+ if (poked_options.debug_p)
+ printf ("data_len == 0 in auto-completion channel\n");
+ goto eol;
+ }
+ if (bufb_init (&b, malloc (1024), 1024) != OK)
+ err (1, "bufb_init() failed");
+
+#define BAPPEND(str) \
+ do \
+ { \
+ if (bufb_append (&b, (str), strlen (str) + 1) != OK) \
+ err (1, "bufb_append() failed"); \
+ } \
+ while (0)
+
+ cmd = data[0];
+ if (cmd == AUTOCMPL_IDENT || cmd == AUTOCMPL_IOS)
+ {
+ const char *ident = (const char *)data + 1;
+ size_t blen;
+
+#define FUNC \
+ (cmd == AUTOCMPL_IDENT ? pk_completion_function : pk_ios_completion_function)
+
+ if ((candidate = FUNC (pkc, ident, 0)) != NULL)
{
- ok = 1;
- termout_eval ();
- pk_print_val (pkc, val, &exc);
- termout_restore ();
+ BAPPEND (candidate);
+ while ((candidate = FUNC (pkc, ident, 1)) != NULL)
+ BAPPEND (candidate);
}
- (void)pk_call (
- pkc,
- pk_decl_val (pkc, "__poked_run_after_cmd_hooks"),
- NULL, &exc, 0);
- if (exc != PK_NULL)
- (void)pk_call (pkc,
- pk_decl_val (pkc, "poked_ehandler"),
- NULL, NULL, 1, exc);
+ blen = b.cur - b.mem;
+ if (blen)
+ usock_out (srv, USOCK_CHAN_OUT_AUTOCMPL, cmd, b.mem,
+ blen);
+ else
+ /* empty payload. */
+ usock_out (srv, USOCK_CHAN_OUT_AUTOCMPL, cmd, "", 1);
+#undef FUNC
}
+ else
+ {
+ if (poked_options.debug_p)
+ printf ("unknown completion command\n");
+ }
+#undef BAPPEND
+ bufb_free (&b);
}
break;
default:
- fprintf (stderr, "unsupported input channel\n");
- goto eol;
- }
-
- if (pk_int_value (pk_decl_val (pkc, "__poked_restart_p")))
- {
- poked_free ();
- goto poked_restart;
- }
- if (pk_int_value (pk_decl_val (pkc, "__poked_exit_p")))
- {
- done_p = 1;
- break;
+ if (poked_options.debug_p)
+ printf ("unsupported input channel\n");
}
- if (pk_int_value (pk_decl_val (pkc, "__vu_do_p")))
- {
- const char *filt
- = pk_string_str (pk_decl_val (pkc, "__vu_filter"));
-
- usock_out (srv, USOCK_CHAN_OUT_VU, VUCMD_FILTER, filt,
- strlen (filt) + 1);
- usock_out (srv, USOCK_CHAN_OUT_VU, VUCMD_CLEAR, "", 1);
- termout_vu_append ();
- (void)pk_call (pkc, pk_decl_val (pkc, "__vu_dump"), NULL, &exc,
- 0);
- assert (exc == PK_NULL);
- termout_restore ();
- usock_out (srv, USOCK_CHAN_OUT_VU, VUCMD_FINISH, "", 1);
- }
- if (pk_int_value (pk_decl_val (pkc, "__poked_chan_send_p")))
- poked_buf_send ();
-
- eol:
- iteration_end (srv, n_iteration);
+ /* end-of-loop */
+ eol:;
}
}
- poked_free ();
+done:
+ poked_free ();
usock_done (srv);
pthread_join (th, &ret);
pthread_attr_destroy (&thattr);
diff --git a/poked/usock.h b/poked/usock.h
index a2341d97..9030d5da 100644
--- a/poked/usock.h
+++ b/poked/usock.h
@@ -26,10 +26,12 @@
// (Channel is a 7-bit unsigned number)
#define USOCK_CHAN_IN_CODE 0x01
#define USOCK_CHAN_IN_CMD 0x02
+#define USOCK_CHAN_IN_AUTOCMPL 0x03
#define USOCK_CHAN_OUT_OUT 0x01
#define USOCK_CHAN_OUT_VU 0x02
#define USOCK_CHAN_OUT_DISASM 0x03
#define USOCK_CHAN_OUT_TREEVU 0x04
+#define USOCK_CHAN_OUT_AUTOCMPL 0x05
struct usock;
--
2.35.1
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [COMMITTED] poked: Add auto-completion channel,
Mohammad-Reza Nabipoor <=