--- /dev/null
+/*
+ * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of the University of California, Berkeley nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS AND 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 <math.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
+#include <netinet/in.h>
+
+#include <cmdline_parse.h>
+#include <cmdline_parse_num.h>
+#include <cmdline_parse_string.h>
+#include <cmdline.h>
+
+
+
+/**********************************************************/
+/* operations on float */
+
+/* this structure is filled when cmd_float is parsed successfully */
+struct cmd_float_result {
+ float a;
+ cmdline_fixed_string_t op;
+ float b;
+};
+
+/* function called when cmd_float is parsed successfully */
+static void cmd_float_parsed(void *parsed_result, struct cmdline *cl, void *data)
+{
+ struct cmd_float_result *cmd = (struct cmd_float_result *) parsed_result;
+ float res=0.;
+
+ switch(cmd->op[0]) {
+ case '+': res = cmd->a + cmd->b; break;
+ case '-': res = cmd->a - cmd->b; break;
+ case '*': res = cmd->a * cmd->b; break;
+ case '/': res = cmd->a / cmd->b; break;
+ default: break;
+ }
+ cmdline_printf(cl, "%f\n", res);
+}
+
+cmdline_parse_token_num_t cmd_float_a = TOKEN_NUM_INITIALIZER(struct cmd_float_result, a, FLOAT);
+cmdline_parse_token_string_t cmd_float_op = TOKEN_STRING_INITIALIZER(struct cmd_float_result, op, "+#-#*#/");
+cmdline_parse_token_num_t cmd_float_b = TOKEN_NUM_INITIALIZER(struct cmd_float_result, b, FLOAT);
+
+cmdline_parse_inst_t cmd_float = {
+ .f = cmd_float_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = "Operation on float (ex: '2 + 5.4')",
+ .tokens = { /* token list, NULL terminated */
+ (void *)&cmd_float_a,
+ (void *)&cmd_float_op,
+ (void *)&cmd_float_b,
+ NULL,
+ },
+};
+
+
+/**********************************************************/
+/* operations trigo */
+
+/* this structure is filled when cmd_trigo is parsed successfully */
+struct cmd_trigo_result {
+ cmdline_fixed_string_t op;
+ float a;
+};
+
+/* function called when cmd_trigo is parsed successfully */
+static void cmd_trigo_parsed(void *parsed_result, struct cmdline *cl, void *data)
+{
+ struct cmd_trigo_result *cmd = (struct cmd_trigo_result *) parsed_result;
+ float res=0.;
+
+ if (!strcmp(cmd->op, "sin")) {
+ res = sin(cmd->a);
+ }
+
+ else if (!strcmp(cmd->op, "cos")) {
+ res = cos(cmd->a);
+ }
+
+ else if (!strcmp(cmd->op, "tan")) {
+ res = tan(cmd->a);
+ }
+
+ cmdline_printf(cl, "%f\n", res);
+}
+
+cmdline_parse_token_string_t cmd_trigo_op = TOKEN_STRING_INITIALIZER(struct cmd_trigo_result, op, "sin#tan#cos");
+cmdline_parse_token_num_t cmd_trigo_a = TOKEN_NUM_INITIALIZER(struct cmd_trigo_result, a, FLOAT);
+
+cmdline_parse_inst_t cmd_trigo = {
+ .f = cmd_trigo_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = "Trigonometric operations (ex: 'sin 2.03')",
+ .tokens = { /* token list, NULL terminated */
+ (void *)&cmd_trigo_op,
+ (void *)&cmd_trigo_a,
+ NULL,
+ },
+};
+
+
+/**********************************************************/
+/* Help */
+
+/* this structure is filled when cmd_help is parsed successfully */
+struct cmd_help_result {
+ cmdline_fixed_string_t arg0;
+};
+
+/* function called when cmd_help is parsed successfully */
+static void cmd_help_parsed(void *parsed_result, struct cmdline *cl, void *data)
+{
+ cmdline_printf(cl, "== Simple calculator program ==\n"
+ "You can do simple operations on floats, like '1 + 3'\n"
+ "or '4.4 * 2.' (space is important).\n"
+ "Some trigonometric operations are available, like\n"
+ "'sin 4.5'.\n");
+}
+
+cmdline_parse_token_string_t cmd_help_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_help_result, arg0, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = "Display help",
+ .tokens = { /* token list, NULL terminated */
+ (void *)&cmd_help_arg0,
+ NULL,
+ },
+};
+
+
+
+
+/**********************************************************/
+/**********************************************************/
+/****** CONTEXT (list of instruction) */
+
+/* in progmem */
+cmdline_parse_ctx_t main_ctx = {
+ .name = "main",
+ .insts = {
+ &cmd_float,
+ &cmd_trigo,
+ &cmd_help,
+ NULL,
+ },
+};
+
--- /dev/null
+/*
+ * Copyright (c) 2011, Olivier MATZ <zer0@droids-corp.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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of the University of California, Berkeley nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS AND 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 <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <inttypes.h>
+#include <ctype.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <termios.h>
+#include <netinet/in.h>
+
+#include <cmdline_rdline.h>
+#include <cmdline_parse.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+
+#include <event.h>
+
+extern cmdline_parse_ctx_t main_ctx[];
+
+/*** main */
+
+static void
+evt_server_input(int s, short event, void *arg)
+{
+ struct cmdline *cl = arg;
+ struct event *evt = cl->opaque;
+ char buf[2048];
+ int n;
+
+ n = read(s, buf, sizeof(buf));
+ if (n < 0) {
+ event_del(evt);
+ free(evt);
+ cmdline_free(cl);
+ return;
+ }
+
+ if (cmdline_in(cl, buf, n) < 0) {
+ event_del(evt);
+ free(evt);
+ cmdline_free(cl);
+ return;
+ }
+}
+
+static void
+evt_server_new_connection(int s, short event, void *arg)
+{
+ struct cmdline *cl;
+ struct event *evt;
+
+ /* create a new cmdline instance for this connection */
+ cl = cmdline_accept(main_ctx, "example> ", s);
+
+ /* allocate a new event for this incomming connection */
+ evt = malloc(sizeof(struct event));
+ if (evt == NULL) {
+ cmdline_free(cl);
+ return;
+ }
+
+ cl->opaque = evt;
+ event_set(evt, cl->s_in, EV_READ | EV_PERSIST, evt_server_input, cl);
+ event_add(evt, NULL);
+}
+
+
+int main(void)
+{
+ struct event listen_evt;
+ int s;
+
+ printf("Listening on port 1234\n");
+
+ /* initializa libevent */
+ event_init();
+
+ /* open a tcp server on port 1234 */
+ s = cmdline_tcpv4_listen(INADDR_ANY, 1234);
+ event_set(&listen_evt, s, EV_READ | EV_PERSIST,
+ evt_server_new_connection, NULL);
+ event_add(&listen_evt, NULL);
+
+ /* libevent main loop */
+ event_dispatch();
+
+ return 0;
+}
+
+