summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: edba65a)
raw | patch | inline | side by side (parent: edba65a)
author | Sebastian Harl <sh@tokkee.org> | |
Fri, 20 Dec 2013 23:19:45 +0000 (00:19 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Fri, 20 Dec 2013 23:19:45 +0000 (00:19 +0100) |
The idea is to implement a minimalistic parser which understands all valid
input and which is used to determine if an input line is part of an existing
command or a command on its own. This information will then be used to update
the prompt (and possibly to determine other information as well).
The scanner's YY_INPUT "method" is overwritten in order to use readline and
custom buffering for user input.
input and which is used to determine if an input line is part of an existing
command or a command on its own. This information will then be used to update
the prompt (and possibly to determine other information as well).
The scanner's YY_INPUT "method" is overwritten in order to use readline and
custom buffering for user input.
.gitignore | patch | blob | history | |
src/Makefile.am | patch | blob | history | |
src/tools/sysdb/input.c | [new file with mode: 0644] | patch | blob |
src/tools/sysdb/input.h | [new file with mode: 0644] | patch | blob |
src/tools/sysdb/main.c | patch | blob | history | |
src/tools/sysdb/scanner.l | [new file with mode: 0644] | patch | blob |
diff --git a/.gitignore b/.gitignore
index e7c950e8e2872c07894260f0099af40c0359abc9..728cb094f0920f0c155b12dddb53a6aefbc45e1b 100644 (file)
--- a/.gitignore
+++ b/.gitignore
src/liboconfig/parser.c
src/liboconfig/parser.h
src/liboconfig/scanner.c
+src/tools/sysdb/scanner.c
src/sysdb
src/sysdbd
.dirstamp
.libs
+*.a
*.la
*.lo
*.o
diff --git a/src/Makefile.am b/src/Makefile.am
index 3f5a0071081afd13a71189fb87b6900d20bf9e5e..fea709ecbdf43d4565a1c4b0c8daef2502d85eed 100644 (file)
--- a/src/Makefile.am
+++ b/src/Makefile.am
if BUILD_CLIENT
bin_PROGRAMS += sysdb
-sysdb_SOURCES = tools/sysdb/main.c include/client/sysdb.h
+# don't use strict CFLAGS for flex code
+noinst_LIBRARIES = sysdb_scanner.a
+sysdb_scanner_a_SOURCES = tools/sysdb/scanner.l
+sysdb_scanner_a_CFLAGS = -DBUILD_DATE="\"$$( date --utc '+%F %T' ) (UTC)\""
+sysdb_SOURCES = tools/sysdb/main.c include/client/sysdb.h \
+ tools/sysdb/input.c tools/sysdb/input.h
sysdb_CFLAGS = -DBUILD_DATE="\"$$( date --utc '+%F %T' ) (UTC)\"" \
$(AM_CFLAGS) @READLINE_CFLAGS@
-sysdb_LDADD = libsysdbclient.la @READLINE_LIBS@
+sysdb_LDADD = sysdb_scanner.a libsysdbclient.la @READLINE_LIBS@
endif
sysdbd_SOURCES = tools/sysdbd/main.c include/sysdb.h \
diff --git a/src/tools/sysdb/input.c b/src/tools/sysdb/input.c
--- /dev/null
+++ b/src/tools/sysdb/input.c
@@ -0,0 +1,125 @@
+/*
+ * SysDB - src/tools/sysdb/input.c
+ * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include "tools/sysdb/input.h"
+
+#include "utils/strbuf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <string.h>
+
+#if HAVE_EDITLINE_READLINE_H
+# include <editline/readline.h>
+# if HAVE_EDITLINE_HISTORY_H
+# include <editline/history.h>
+# endif
+#elif HAVE_READLINE_READLINE_H
+# include <readline/readline.h>
+# if HAVE_READLINE_HISTORY_H
+# include <readline/history.h>
+# endif
+#elif HAVE_READLINE_H
+# include <readline.h>
+# if HAVE_HISTORY_H
+# include <history.h>
+# endif
+#endif /* READLINEs */
+
+/*
+ * private helper functions
+ */
+
+static size_t
+input_readline(sdb_strbuf_t *buf)
+{
+ const char *prompt = "sysdb=> ";
+ char *line;
+
+ size_t len;
+
+ if (sdb_strbuf_len(buf))
+ prompt = "sysdb-> ";
+
+ line = readline(prompt);
+
+ if (! line)
+ return 0;
+
+ len = strlen(line);
+
+ sdb_strbuf_append(buf, line);
+ free(line);
+ return len;
+} /* input_readline */
+
+/*
+ * API
+ */
+
+ssize_t
+sdb_input_readline(sdb_input_t *input, char *buf,
+ int *n_chars, size_t max_chars)
+{
+ const char *query;
+ size_t buflen, len;
+
+ buflen = sdb_strbuf_len(input->buf);
+ len = buflen - input->tokenizer_pos;
+
+ if (! len) {
+ size_t n = input_readline(input->buf);
+ if (! n) {
+ *n_chars = 0; /* YY_NULL */
+ return 0;
+ }
+ buflen += n;
+ len += n;
+ }
+
+ query = sdb_strbuf_string(input->buf);
+
+ len = (len < max_chars) ? len : max_chars;
+ strncpy(buf, sdb_strbuf_string(input->buf) + input->tokenizer_pos, len);
+ input->tokenizer_pos += len;
+ *n_chars = (int)len;
+
+ /* XXX */
+ if (! strchr(query, (int)';'))
+ return (ssize_t)len;
+ sdb_strbuf_clear(input->buf);
+ input->tokenizer_pos = 0;
+ return (ssize_t)len;
+} /* sdb_input_readline */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
diff --git a/src/tools/sysdb/input.h b/src/tools/sysdb/input.h
--- /dev/null
+++ b/src/tools/sysdb/input.h
@@ -0,0 +1,66 @@
+/*
+ * SysDB - src/tools/sysdb/input.h
+ * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "utils/strbuf.h"
+
+#ifndef SYSDB_INPUT_H
+#define SYSDB_INPUT_H 1
+
+typedef struct {
+ sdb_strbuf_t *buf;
+
+ size_t tokenizer_pos;
+} sdb_input_t;
+
+#define SDB_INPUT_INIT { NULL, 0 }
+
+/*
+ * sdb_input_readline:
+ * This function is supposed to be used with a flex scanner's YY_INPUT. It
+ * reads input from the user using reading() and places available input in the
+ * specified buffer, returning the number of bytes in 'n_chars' (no more than
+ * 'max_chars'.
+ *
+ * Returns:
+ * - The number of newly read bytes.
+ * - A negative value in case of an error.
+ */
+ssize_t
+sdb_input_readline(sdb_input_t *input, char *buf,
+ int *n_chars, size_t max_chars);
+
+/*
+ * scanner
+ */
+
+void
+sdb_input_set(sdb_input_t *new_input);
+
+#endif /* SYSDB_INPUT_H */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
diff --git a/src/tools/sysdb/main.c b/src/tools/sysdb/main.c
index 0639e5f74829042a4e3a8532b97f6ee74d853236..d895de7184cb9bdb7cea1bf8b98db2939151e272 100644 (file)
--- a/src/tools/sysdb/main.c
+++ b/src/tools/sysdb/main.c
# include "config.h"
#endif /* HAVE_CONFIG_H */
+#include "tools/sysdb/input.h"
+
#include "client/sysdb.h"
#include "client/sock.h"
#include "utils/error.h"
# define DEFAULT_SOCKET "unix:"LOCALSTATEDIR"/run/sysdbd.sock"
#endif
+extern int yylex(void);
+
static void
exit_usage(char *name, int status)
{
const char *homedir;
char hist_file[1024] = "";
- sdb_strbuf_t *buf;
+ sdb_input_t input = SDB_INPUT_INIT;
while (42) {
int opt = getopt(argc, argv, "H:U:hV");
}
}
- buf = sdb_strbuf_create(1024);
-
- while (42) {
- const char *prompt = "sysdb=> ";
- const char *query;
- char *input;
-
- if (sdb_strbuf_len(buf))
- prompt = "sysdb-> ";
-
- input = readline(prompt);
-
- if (! input)
- break;
-
- sdb_strbuf_append(buf, input);
- free(input);
-
- query = sdb_strbuf_string(buf);
- if (! strchr(query, (int)';'))
- continue;
-
- /* XXX */
- sdb_strbuf_clear(buf);
- }
+ input.buf = sdb_strbuf_create(2048);
+ sdb_input_set(&input);
+ yylex();
if (hist_file[0] != '\0') {
errno = 0;
diff --git a/src/tools/sysdb/scanner.l b/src/tools/sysdb/scanner.l
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * SysDB - src/tools/sysdb/scanner.l
+ * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+%{
+#include "tools/sysdb/input.h"
+
+#ifdef YY_INPUT
+# undef YY_INPUT
+#endif
+#define YY_INPUT(buf, result, max_size) \
+ do { \
+ sdb_input_readline(sdb_input, (buf), &(result), (max_size)); \
+ } while (0)
+
+static sdb_input_t *sdb_input;
+%}
+
+%option interactive
+%option yylineno
+%option noyywrap
+%option verbose
+
+%%
+
+. { /* do nothing */ }
+
+%%
+
+void
+sdb_input_set(sdb_input_t *new_input)
+{
+ sdb_input = new_input;
+} /* sdb_input_set */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+