summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAn-Cheng Huang <ancheng@vyatta.com>2010-11-11 19:15:28 -0800
committerAn-Cheng Huang <ancheng@vyatta.com>2010-11-11 19:15:28 -0800
commit91eb09a12a040795a2aca06de050b4507af93790 (patch)
treeec99bf559a02e8e31cd1dbeac6e08ac4ead0202f
parent0f5de703f7641cf583b907c047df98b1014d5653 (diff)
downloadvyatta-cfg-91eb09a12a040795a2aca06de050b4507af93790.tar.gz
vyatta-cfg-91eb09a12a040795a2aca06de050b4507af93790.zip
continue config parser work
* add parser to package build. * add prefix, error handling, etc. * fix handling of empty and 1-char values in lex. * add API function.
-rw-r--r--.gitignore3
-rw-r--r--Makefile.am13
-rw-r--r--src/cparse/cparse.hpp27
-rw-r--r--src/cparse/cparse.ypp26
-rw-r--r--src/cparse/cparse_lex.l86
5 files changed, 109 insertions, 46 deletions
diff --git a/.gitignore b/.gitignore
index 3b1ed39..44d745e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,5 +41,8 @@ libtool
/src/cli_parse.c
/src/cli_parse.h
/src/cli_val.c
+/src/cparse/cparse.cpp
+/src/cparse/cparse.h
+/src/cparse/cparse_lex.c
/tools/rl_passwd
diff --git a/Makefile.am b/Makefile.am
index c0520b9..5d30019 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -18,6 +18,12 @@ completion_SCRIPTS = etc/bash_completion.d/20vyatta-cfg
initd_SCRIPTS = etc/init.d/vyatta-router
dhcphook_SCRIPTS = scripts/vyatta-dhclient-hook
+src/cparse/cparse.cpp: src/cparse/cparse.ypp src/cparse/cparse_def.h
+ bison -p cparse_ --defines=src/cparse/cparse.h -o $@ $<
+
+src/cparse/cparse_lex.c: src/cparse/cparse_lex.l src/cparse/cparse.cpp
+ flex -P cparse_ -o $@ $<
+
lib_LTLIBRARIES = src/libvyatta-cfg.la
src_libvyatta_cfg_la_LIBADD = /usr/lib/libglib-2.0.la
src_libvyatta_cfg_la_LIBADD += /usr/lib/libgio-2.0.la
@@ -35,7 +41,11 @@ src_libvyatta_cfg_la_SOURCES += src/cstore/cstore-varref.cpp
src_libvyatta_cfg_la_SOURCES += src/cstore/unionfs/cstore-unionfs.cpp
src_libvyatta_cfg_la_SOURCES += src/cnode/cnode.cpp
src_libvyatta_cfg_la_SOURCES += src/cnode/cnode-algorithm.cpp
+src_libvyatta_cfg_la_SOURCES += src/cparse/cparse.cpp
+src_libvyatta_cfg_la_SOURCES += src/cparse/cparse_lex.c
CLEANFILES = src/cli_parse.c src/cli_parse.h src/cli_def.c src/cli_val.c
+CLEANFILES += src/cparse/cparse.cpp src/cparse/cparse.h
+CLEANFILES += src/cparse/cparse_lex.c
LDADD = src/libvyatta-cfg.la
LDADD += /usr/lib/libglib-2.0.la
@@ -53,6 +63,9 @@ vnincdir = $(vincludedir)/cnode
vninc_HEADERS = src/cnode/cnode.hpp
vninc_HEADERS += src/cnode/cnode-algorithm.hpp
+vpincdir = $(vincludedir)/cparse
+vpinc_HEADERS = src/cparse/cparse.hpp
+
sbin_PROGRAMS = src/priority
sbin_PROGRAMS += src/my_commit
sbin_PROGRAMS += src/exe_action
diff --git a/src/cparse/cparse.hpp b/src/cparse/cparse.hpp
new file mode 100644
index 0000000..478af7b
--- /dev/null
+++ b/src/cparse/cparse.hpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 Vyatta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CPARSE_HPP_
+#define _CPARSE_HPP_
+
+namespace cparse {
+
+int parse_file(FILE *fin);
+
+} // namespace cparse
+
+#endif /* _CPARSE_HPP_ */
+
diff --git a/src/cparse/cparse.ypp b/src/cparse/cparse.ypp
index eef3d13..eb2ab12 100644
--- a/src/cparse/cparse.ypp
+++ b/src/cparse/cparse.ypp
@@ -1,16 +1,22 @@
-/* bison -v -t --defines=cparse.h -o cparse.cpp cparse.ypp */
%{
-#include <stdio.h>
+#include <cstdio>
+
+#include "cparse.hpp"
#include "cparse_def.h"
+// stuff from lex
extern "C" {
-int yylex();
+extern int cparse_lineno;
+extern char *cparse_text;
+int cparse_lex();
+void cparse_set_in(FILE *fin);
}
-void
-yyerror(const char *s)
+static void
+cparse_error(const char *s)
{
- printf("%s\n", s);
+ printf("Invalid config file (%s): error at line %d, text [%s]\n",
+ s, cparse_lineno, cparse_text);
}
int level = 0;
@@ -19,7 +25,7 @@ char *ncomment = NULL;
char *nname = NULL;
char *nval = NULL;
-void
+static void
print_node()
{
int i = 0;
@@ -47,6 +53,7 @@ print_node()
%token COMMENT
%token LEFTB
%token RIGHTB
+%token SYNTAX_ERROR
%%
@@ -93,8 +100,9 @@ comment: COMMENT
%%
int
-main()
+cparse::parse_file(FILE *fin)
{
- return yyparse();
+ cparse_set_in(fin);
+ return cparse_parse();
}
diff --git a/src/cparse/cparse_lex.l b/src/cparse/cparse_lex.l
index 3bdb7f0..167e2af 100644
--- a/src/cparse/cparse_lex.l
+++ b/src/cparse/cparse_lex.l
@@ -1,4 +1,3 @@
-/* flex -o cparse_lex.c cparse_lex.l */
/* definitions */
%x sComment
%x sID
@@ -16,35 +15,44 @@ SPACE ([[:space:]]{-}[\n])
#define STR_BUF_INC 4096
-int line_number = 0;
-int node_deactivated = 0;
-char *str_buf = NULL;
-char *out_buf = NULL;
-char *str_ptr = NULL;
-size_t str_buf_len = 0;
+static int node_deactivated = 0;
+static char *str_buf = NULL;
+static char *out_buf = NULL;
+static char *str_ptr = NULL;
+static size_t str_buf_len = 0;
-void
-append_str(char *text)
+static void
+prepare_buffers(size_t add_len)
{
- size_t tlen = strlen(text);
size_t slen = str_ptr - str_buf;
- if (!str_buf || (slen + tlen) >= str_buf_len) {
- str_buf_len += STR_BUF_INC;
- str_buf = realloc(str_buf, str_buf_len);
- out_buf = realloc(out_buf, str_buf_len);
- if (!str_buf || !out_buf) {
- printf("realloc failed\n");
- exit(1);
- }
- str_ptr = str_buf + slen;
+ if (str_buf && (slen + add_len) < str_buf_len) {
+ // nothing to do
+ return;
+ }
+
+ str_buf_len += STR_BUF_INC;
+ str_buf = realloc(str_buf, str_buf_len);
+ out_buf = realloc(out_buf, str_buf_len);
+ if (!str_buf || !out_buf) {
+ printf("realloc failed\n");
+ exit(1);
}
+ str_ptr = str_buf + slen;
+}
+
+static void
+append_str(char *text)
+{
+ size_t tlen = strlen(text);
+ prepare_buffers(tlen);
strcpy(str_ptr, text);
str_ptr += tlen;
}
-void
+static void
set_ret_str()
{
+ prepare_buffers(0);
*str_ptr = 0;
strcpy(out_buf, str_buf);
str_ptr = str_buf;
@@ -59,21 +67,21 @@ set_ret_str()
}
<sComment>[^*\n]* {
- append_str(yytext);
+ append_str(cparse_text);
}
<sComment>\*[^/] {
- append_str(yytext);
+ append_str(cparse_text);
}
<sComment>\n {
- append_str(yytext);
- ++line_number;
+ append_str(cparse_text);
+ ++cparse_lineno;
}
<sComment>"*/" {
set_ret_str();
- yylval.str = strdup(out_buf);
+ cparse_lval.str = strdup(out_buf);
BEGIN(INITIAL);
return COMMENT;
}
@@ -91,15 +99,15 @@ set_ret_str()
}
<INITIAL>{ID} {
- yylval.str = strdup(yytext);
- yylval.deactivated = node_deactivated;
+ cparse_lval.str = strdup(cparse_text);
+ cparse_lval.deactivated = node_deactivated;
node_deactivated = 0;
BEGIN(sID);
return NODE;
}
<sID>:?{SPACE}+[^{\n] {
- unput(yytext[yyleng - 1]);
+ unput(cparse_text[cparse_leng - 1]);
BEGIN(sValue);
}
@@ -112,7 +120,7 @@ set_ret_str()
}
<sID>\n {
- ++line_number;
+ ++cparse_lineno;
BEGIN(INITIAL);
}
@@ -126,29 +134,29 @@ set_ret_str()
}
<sQStr>[^\"\\\n]+ {
- append_str(yytext);
+ append_str(cparse_text);
}
<sQStr>\\. {
- char tmp[2] = { yytext[1], 0 };
+ char tmp[2] = { cparse_text[1], 0 };
append_str(tmp);
}
<sQStr>\n {
- append_str(yytext);
- ++line_number;
+ append_str(cparse_text);
+ ++cparse_lineno;
}
<sQStr>\" {
set_ret_str();
- yylval.str = strdup(out_buf);
+ cparse_lval.str = strdup(out_buf);
BEGIN(sValue);
return VALUE;
}
-<sValue>[^{"[:space:]][^{[:space:]]+ {
+<sValue>[^{"[:space:]][^{[:space:]]* {
/* unquoted string */
- yylval.str = strdup(yytext);
+ cparse_lval.str = strdup(cparse_text);
return VALUE;
}
@@ -158,10 +166,14 @@ set_ret_str()
}
<sValue>\n {
- ++line_number;
+ ++cparse_lineno;
BEGIN(INITIAL);
}
+<*>. {
+ return SYNTAX_ERROR;
+}
+
%%
/* code */