aboutsummaryrefslogtreecommitdiffstats
path: root/src/tools/vppapigen
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2017-04-24 10:46:54 -0400
committerFlorin Coras <florin.coras@gmail.com>2017-04-25 16:18:42 +0000
commit11b8dbf78af49d270a0e72abe7dea73eec30d85f (patch)
tree5c9c513483f5c468efcb64b82c03c32733dc3a77 /src/tools/vppapigen
parent45d3496f3d86ee1a930ce0ffd6ca3d1730355eb8 (diff)
"autoreply" flag: autogenerate standard xxx_reply_t messages
Change-Id: I72298aaae7d172082ece3a8edea4217c11b28d79 Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'src/tools/vppapigen')
-rw-r--r--src/tools/vppapigen/gram.y3
-rw-r--r--src/tools/vppapigen/lex.c57
-rw-r--r--src/tools/vppapigen/lex.h1
-rw-r--r--src/tools/vppapigen/node.c5
-rw-r--r--src/tools/vppapigen/node.h2
5 files changed, 65 insertions, 3 deletions
diff --git a/src/tools/vppapigen/gram.y b/src/tools/vppapigen/gram.y
index de26af8daa0..9cea602391a 100644
--- a/src/tools/vppapigen/gram.y
+++ b/src/tools/vppapigen/gram.y
@@ -38,7 +38,7 @@ void generate (YYSTYPE);
%token NAME RPAR LPAR SEMI LBRACK RBRACK NUMBER PRIMTYPE BARF
%token TPACKED DEFINE LCURLY RCURLY STRING UNION
%token HELPER_STRING COMMA
-%token NOVERSION MANUAL_PRINT MANUAL_ENDIAN TYPEONLY DONT_TRACE
+%token NOVERSION MANUAL_PRINT MANUAL_ENDIAN TYPEONLY DONT_TRACE AUTOREPLY
%%
@@ -64,6 +64,7 @@ flag:
| MANUAL_ENDIAN {$$ = $1;}
| DONT_TRACE {$$ = $1;}
| TYPEONLY {$$ = $1;}
+ | AUTOREPLY {$$ = $1;}
;
defn: DEFINE NAME LCURLY defbody RCURLY SEMI
diff --git a/src/tools/vppapigen/lex.c b/src/tools/vppapigen/lex.c
index 733942add8d..e63581433b7 100644
--- a/src/tools/vppapigen/lex.c
+++ b/src/tools/vppapigen/lex.c
@@ -27,6 +27,9 @@
#include "lex.h"
#include "node.h"
#include "tools/vppapigen/gram.h"
+#include <vppinfra/clib.h>
+#include <vppinfra/fifo.h>
+#include <vppinfra/format.h>
FILE *ifp, *ofp, *pythonfp, *jsonfp;
char *vlib_app_name = "vpp";
@@ -38,6 +41,9 @@ int current_filename_allocated;
unsigned long input_crc;
unsigned long message_crc;
int yydebug;
+char *push_input_fifo;
+char saved_ungetc_char;
+char have_ungetc_char;
/*
* lexer variable definitions
@@ -469,9 +475,50 @@ static char namebuf [MAXNAME];
static inline char
getc_char (FILE *ifp)
{
+ char rv;
+
+ if (have_ungetc_char) {
+ have_ungetc_char = 0;
+ return saved_ungetc_char;
+ }
+
+ if (clib_fifo_elts (push_input_fifo)) {
+ clib_fifo_sub1(push_input_fifo, rv);
+ return (rv & 0x7f);
+ }
return ((char)(getc(ifp) & 0x7f));
}
+u32 fe (char *fifo)
+{
+ return clib_fifo_elts (fifo);
+}
+
+static inline void
+ungetc_char (char c, FILE *ifp)
+{
+ saved_ungetc_char = c;
+ have_ungetc_char = 1;
+}
+
+void autoreply (void *np_arg)
+{
+ static u8 *s;
+ node_t *np = (node_t *)np_arg;
+ int i;
+
+ vec_reset_length (s);
+
+ s = format (0, " define %s_reply\n", (char *)(np->data[0]));
+ s = format (s, "{\n");
+ s = format (s, " u32 context;\n");
+ s = format (s, " i32 retval;\n");
+ s = format (s, "};\n");
+
+ for (i = 0; i < vec_len (s); i++)
+ clib_fifo_add1 (push_input_fifo, s[i]);
+}
+
/*
* yylex (well, yylex_1: The real yylex below does crc-hackery)
*/
@@ -595,7 +642,7 @@ static int yylex_1 (void)
return (EOF);
if (!isalnum (c) && c != '_') {
- ungetc (c, ifp);
+ ungetc_char (c, ifp);
namebuf [nameidx] = 0;
the_lexer_state = START_STATE;
return (name_check (namebuf, &yylval));
@@ -616,7 +663,7 @@ static int yylex_1 (void)
return (EOF);
if (!isdigit (c)) {
- ungetc (c, ifp);
+ ungetc_char (c, ifp);
namebuf [nameidx] = 0;
the_lexer_state = START_STATE;
yylval = (void *) atol(namebuf);
@@ -889,6 +936,7 @@ int yylex (void)
case MANUAL_ENDIAN: code = 276; break;
case TYPEONLY: code = 278; break;
case DONT_TRACE: code = 279; break;
+ case AUTOREPLY: code = 280; break;
case EOF: code = ~0; break; /* hysterical compatibility */
@@ -929,6 +977,7 @@ static struct keytab {
} keytab [] =
/* Keep the table sorted, binary search used below! */
{
+ {"autoreply", NODE_AUTOREPLY},
{"define", NODE_DEFINE},
{"dont_trace", NODE_DONT_TRACE},
{"f64", NODE_F64},
@@ -1005,6 +1054,10 @@ static int name_check (const char *s, YYSTYPE *token_value)
*token_value = (YYSTYPE) NODE_FLAG_DONT_TRACE;
return(DONT_TRACE);
+ case NODE_AUTOREPLY:
+ *token_value = (YYSTYPE) NODE_FLAG_AUTOREPLY;
+ return(AUTOREPLY);
+
case NODE_NOVERSION:
return(NOVERSION);
diff --git a/src/tools/vppapigen/lex.h b/src/tools/vppapigen/lex.h
index a0fdc735b74..275cf685a4b 100644
--- a/src/tools/vppapigen/lex.h
+++ b/src/tools/vppapigen/lex.h
@@ -24,6 +24,7 @@
extern int yylex (void);
extern void yyerror (char *);
extern int yyparse (void);
+extern void autoreply (void *);
#ifndef YYSTYPE
#define YYSTYPE void *
diff --git a/src/tools/vppapigen/node.c b/src/tools/vppapigen/node.c
index 359ac9c918d..9f234037774 100644
--- a/src/tools/vppapigen/node.c
+++ b/src/tools/vppapigen/node.c
@@ -1050,6 +1050,11 @@ YYSTYPE set_flags(YYSTYPE a1, YYSTYPE a2)
flags = (int)(uword) a1;
np->flags |= flags;
+
+ /* Generate a foo_reply_t right here */
+ if (flags & NODE_FLAG_AUTOREPLY)
+ autoreply(np);
+
return (a2);
}
/*
diff --git a/src/tools/vppapigen/node.h b/src/tools/vppapigen/node.h
index 297d603615b..65bd5d10060 100644
--- a/src/tools/vppapigen/node.h
+++ b/src/tools/vppapigen/node.h
@@ -53,6 +53,7 @@ enum node_subclass { /* WARNING: indices must match the vft... */
NODE_MANUAL_PRINT,
NODE_MANUAL_ENDIAN,
NODE_DONT_TRACE,
+ NODE_AUTOREPLY,
};
enum passid {
@@ -84,6 +85,7 @@ typedef struct node_ {
#define NODE_FLAG_MANUAL_ENDIAN (1<<1)
#define NODE_FLAG_TYPEONLY (1<<3)
#define NODE_FLAG_DONT_TRACE (1<<4)
+#define NODE_FLAG_AUTOREPLY (1<<5)
typedef struct node_vft_ {
void (*print)(struct node_ *);