OSSP CVS Repository

ossp - Difference in ossp-pkg/cfg/cfg_syn.c versions 1.1 and 1.2
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/cfg/cfg_syn.c 1.1 -> 1.2

--- 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;
+}
+

CVSTrac 2.0.1