--- cfg_syn.c 2002/07/03 13:25:34 1.1
+++ cfg_syn.c 2002/07/04 14:51:21 1.2
@@ -28,11 +28,14 @@
** cfg_syn.c: syntax parsing
*/
+#include <stdio.h>
+
#include "cfg.h"
#include "cfg_grid.h"
#include "cfg_node.h"
#include "cfg_fmt.h"
#include "cfg_syn.h"
+#include "cfg_buf.h"
/* prototypes for Flex-generated scanner */
extern int cfg_syn_lex_init(void *);
@@ -43,10 +46,18 @@
extern int cfg_syn_parse(void *);
/* build a node tree according to a textual specification */
-cfg_rc_t cfg_syn(cfg_t *cfg, cfg_node_t **node, char *err_buf, size_t err_len, const char *input)
+cfg_rc_t cfg_syn_import(
+ cfg_t *cfg,
+ cfg_node_t **node,
+ const char *input,
+ char *err_buf, size_t err_len)
{
cfg_syn_ctx_t ctx;
void *yyscan;
+
+ /* argument sanity checking */
+ if (node == NULL || input == NULL)
+ return CFG_ERR_ARG;
/* initialize scanner */
cfg_syn_lex_init(&yyscan);
@@ -147,3 +158,118 @@
return;
}
+typedef struct {
+ cfg_buf_t *buf;
+ int indent;
+} export_t;
+
+static void export_format(export_t *ctx, char *fmt, ...)
+{
+ int i;
+ char *cp;
+ va_list ap;
+ char *str;
+
+ va_start(ap, fmt);
+ if ((str = cfg_fmt_vasprintf(fmt, ap)) == NULL)
+ return;
+ while ((cp = strchr(str, '\n')) != NULL) {
+ cfg_buf_format(ctx->buf, "%.*s", cp-str+1, str);
+ for (i = 0; i < ctx->indent; i++)
+ cfg_buf_format(ctx->buf, " ");
+ str = cp+1;
+ }
+ if (str[0] != '\0')
+ cfg_buf_format(ctx->buf, "%s", str);
+ free(str);
+ va_end(ap);
+ return;
+}
+
+static void export_indent(export_t *ctx, int n)
+{
+ if (n > 0) {
+ while (n > 0) {
+ n--;
+ ctx->indent++;
+ cfg_buf_format(ctx->buf, " ");
+ }
+ }
+ else {
+ while (n < 0 && ctx->indent > 0) {
+ n++;
+ ctx->indent--;
+ cfg_buf_resize(ctx->buf, -4);
+ }
+ }
+}
+
+static void export_token(export_t *ctx, const char *token)
+{
+ if (strcspn(token, " {};\\") != strlen(token))
+ export_format(ctx, "\"%s\"", token);
+ else
+ export_format(ctx, "%s", token);
+ return;
+}
+
+static void export_node(export_t *ctx, cfg_node_t *node)
+{
+ cfg_node_type_t type;
+ cfg_node_t *node2;
+ cfg_rc_t rc;
+ char *token;
+
+ rc = cfg_node_get(node, CFG_NODE_ATTR_TYPE, &type);
+ if (type == CFG_NODE_TYPE_SEQ) {
+ export_format(ctx, "{\n");
+ export_indent(ctx, 1);
+ cfg_node_goto(node, CFG_NODE_GOTO_CHILD1, &node2);
+ while (node2 != NULL) {
+ export_node(ctx, node2);
+ cfg_node_goto(node2, CFG_NODE_GOTO_RBROTH, &node2);
+ }
+ export_indent(ctx, -1);
+ export_format(ctx, "}");
+ }
+ else if (type == CFG_NODE_TYPE_DIR) {
+ cfg_node_goto(node, CFG_NODE_GOTO_CHILD1, &node2);
+ while (node2 != NULL) {
+ export_node(ctx, node2);
+ cfg_node_goto(node2, CFG_NODE_GOTO_RBROTH, &node2);
+ if (node2 != NULL)
+ export_format(ctx, " ");
+ }
+ export_format(ctx, ";\n");
+ }
+ else if (type == CFG_NODE_TYPE_TOK) {
+ cfg_node_get(node, CFG_NODE_ATTR_TOKEN, &token);
+ if (token != NULL)
+ export_token(ctx, token);
+ else
+ export_format(ctx, "<?>");
+ }
+ return;
+}
+
+cfg_rc_t cfg_syn_export(
+ cfg_t *cfg,
+ cfg_node_t *node,
+ char **output)
+{
+ cfg_buf_t *buf;
+ cfg_rc_t rc;
+ export_t ctx;
+
+ if (node == NULL || output == NULL)
+ return CFG_ERR_ARG;
+ if ((rc = cfg_buf_create(&buf)) != CFG_OK)
+ return rc;
+ ctx.buf = buf;
+ ctx.indent = 0;
+ export_node(&ctx, node);
+ cfg_buf_content(buf, output, NULL, NULL);
+ cfg_buf_destroy(buf);
+ return CFG_OK;
+}
+
|