Пример #1
0
static int
json_print_string(struct lyout *out, const char *text)
{
    unsigned int i, n;

    if (!text) {
        return 0;
    }

    ly_write(out, "\"", 1);
    for (i = n = 0; text[i]; i++) {
        if (text[i] < 0x20) {
            /* control character */
            n += ly_print(out, "\\u%.4X");
        } else {
            switch (text[i]) {
            case '"':
                n += ly_print(out, "\\\"");
                break;
            case '\\':
                n += ly_print(out, "\\\\");
                break;
            default:
                ly_write(out, &text[i], 1);
                n++;
            }
        }
    }
    ly_write(out, "\"", 1);

    return n + 2;
}
Пример #2
0
static int
write_iff(struct lyout *out, const struct lys_module *module, struct lys_iffeature *expr, int prefix_kind,
          int *index_e, int *index_f)
{
    int count = 0, brackets_flag = *index_e;
    uint8_t op;
    struct lys_module *mod;

    op = iff_getop(expr->expr, *index_e);
    (*index_e)++;

    switch (op) {
    case LYS_IFF_F:
        if (lys_main_module(expr->features[*index_f]->module) != lys_main_module(module)) {
            if (prefix_kind == 0) {
                count += ly_print(out, "%s:", transform_module_name2import_prefix(module,
                                  lys_main_module(expr->features[*index_f]->module)->name));
            } else if (prefix_kind == 1) {
                count += ly_print(out, "%s:", lys_main_module(expr->features[*index_f]->module)->name);
            } else if (prefix_kind == 2) {
                count += ly_print(out, "%s:", lys_main_module(expr->features[*index_f]->module)->prefix);
            } else if (prefix_kind == 3) {
                mod =  lys_main_module(expr->features[*index_f]->module);
                count += ly_print(out, "%s%s%s:", mod->name, mod->rev_size ? "@" : "", mod->rev_size ? mod->rev[0].date : "");
            }
        }
        count += ly_print(out, expr->features[*index_f]->name);
        (*index_f)++;
        break;
    case LYS_IFF_NOT:
        count += ly_print(out, "not ");
        count += write_iff(out, module, expr, prefix_kind, index_e, index_f);
        break;
    case LYS_IFF_AND:
        if (brackets_flag) {
            /* AND need brackets only if previous op was not */
            if (*index_e < 2 || iff_getop(expr->expr, *index_e - 2) != LYS_IFF_NOT) {
                brackets_flag = 0;
            }
        }
        /* falls through */
    case LYS_IFF_OR:
        if (brackets_flag) {
            count += ly_print(out, "(");
        }
        count += write_iff(out, module, expr, prefix_kind, index_e, index_f);
        count += ly_print(out, " %s ", op == LYS_IFF_OR ? "or" : "and");
        count += write_iff(out, module, expr, prefix_kind, index_e, index_f);
        if (brackets_flag) {
            count += ly_print(out, ")");
        }
    }

    return count;
}
Пример #3
0
static void
json_print_attrs(struct lyout *out, int level, const struct lyd_node *node)
{
    struct lyd_attr *attr;

    for (attr = node->attr; attr; attr = attr->next) {
        if (attr->module != node->schema->module) {
            ly_print(out, "%*s\"%s:%s\":", LEVEL, INDENT, attr->module->name, attr->name);
        } else {
            ly_print(out, "%*s\"%s\":", LEVEL, INDENT, attr->name);
        }
        json_print_string(out, attr->value ? attr->value : "");
        ly_print(out, "%s", attr->next ? ",\n" : "\n");
    }
}
Пример #4
0
int
json_print_data(struct lyout *out, const struct lyd_node *root, int options)
{
    int level = 0;

    /* start */
    ly_print(out, "{\n");

    /* content */
    json_print_nodes(out, level + 1, root, options & LYP_WITHSIBLINGS);

    /* end */
    ly_print(out, "}\n");

    return EXIT_SUCCESS;
}
Пример #5
0
static void
json_print_container(struct lyout *out, int level, const struct lyd_node *node)
{
    const char *schema;

    if (!node->parent || nscmp(node, node->parent)) {
        /* print "namespace" */
        schema = lys_node_module(node->schema)->name;
        ly_print(out, "%*s\"%s:%s\": {\n", LEVEL, INDENT, schema, node->schema->name);
    } else {
        ly_print(out, "%*s\"%s\": {\n", LEVEL, INDENT, node->schema->name);
    }
    level++;
    if (node->attr) {
        ly_print(out, "%*s\"@\": {\n", LEVEL, INDENT);
        json_print_attrs(out, level + 1, node);
        ly_print(out, "%*s}%s", LEVEL, INDENT, node->child ? ",\n" : "");
    }
    json_print_nodes(out, level, node->child, 1);
    level--;
    ly_print(out, "%*s}", LEVEL, INDENT);
}
Пример #6
0
static void
json_print_anyxml(struct lyout *out, int level, const struct lyd_node *node)
{
    const char *schema = NULL;

    if (!node->parent || nscmp(node, node->parent)) {
        /* print "namespace" */
        schema = lys_node_module(node->schema)->name;
        ly_print(out, "%*s\"%s:%s\": [null]", LEVEL, INDENT, schema, node->schema->name);
    } else {
        ly_print(out, "%*s\"%s\": [null]", LEVEL, INDENT, node->schema->name);
    }

    /* print attributes as sibling leaf */
    if (node->attr) {
        if (schema) {
            ly_print(out, ",\n%*s\"@%s:%s\": {\n", LEVEL, INDENT, schema, node->schema->name);
        } else {
            ly_print(out, ",\n%*s\"@%s\": {\n", LEVEL, INDENT, node->schema->name);
        }
        json_print_attrs(out, level + 1, node);
        ly_print(out, "%*s}", LEVEL, INDENT);
    }
}
Пример #7
0
int
lys_print_target(struct lyout *out, const struct lys_module *module, const char *target_schema_path,
                 void (*clb_print_typedef)(struct lyout*, const struct lys_tpdf*, int*),
                 void (*clb_print_identity)(struct lyout*, const struct lys_ident*, int*),
                 void (*clb_print_feature)(struct lyout*, const struct lys_feature*, int*),
                 void (*clb_print_type)(struct lyout*, const struct lys_type*, int*),
                 void (*clb_print_grouping)(struct lyout*, const struct lys_node*, int*),
                 void (*clb_print_container)(struct lyout*, const struct lys_node*, int*),
                 void (*clb_print_choice)(struct lyout*, const struct lys_node*, int*),
                 void (*clb_print_leaf)(struct lyout*, const struct lys_node*, int*),
                 void (*clb_print_leaflist)(struct lyout*, const struct lys_node*, int*),
                 void (*clb_print_list)(struct lyout*, const struct lys_node*, int*),
                 void (*clb_print_anydata)(struct lyout*, const struct lys_node*, int*),
                 void (*clb_print_case)(struct lyout*, const struct lys_node*, int*),
                 void (*clb_print_notif)(struct lyout*, const struct lys_node*, int*),
                 void (*clb_print_rpc)(struct lyout*, const struct lys_node*, int*),
                 void (*clb_print_action)(struct lyout*, const struct lys_node*, int*),
                 void (*clb_print_input)(struct lyout*, const struct lys_node*, int*),
                 void (*clb_print_output)(struct lyout*, const struct lys_node*, int*))
{
    int rc, i, f = 1;
    char *spec_target = NULL;
    struct lys_node *target = NULL;
    struct lys_tpdf *tpdf = NULL;
    uint8_t tpdf_size = 0;

    if ((target_schema_path[0] == '/') || !strncmp(target_schema_path, "type/", 5)) {
        rc = resolve_absolute_schema_nodeid((target_schema_path[0] == '/' ? target_schema_path : target_schema_path + 4), module,
                                            LYS_ANY & ~(LYS_USES | LYS_AUGMENT | LYS_GROUPING), (const struct lys_node **)&target);
        if (rc || !target) {
            LOGERR(module->ctx, LY_EINVAL, "Target %s could not be resolved.",
                   (target_schema_path[0] == '/' ? target_schema_path : target_schema_path + 4));
            return EXIT_FAILURE;
        }
    } else if (!strncmp(target_schema_path, "grouping/", 9)) {
        /* cut the data part off */
        if ((spec_target = strchr(target_schema_path + 9, '/'))) {
            /* HACK only temporary */
            spec_target[0] = '\0';
            ++spec_target;
        }
        rc = resolve_absolute_schema_nodeid(target_schema_path + 8, module, LYS_GROUPING, (const struct lys_node **)&target);
        if (rc || !target) {
            ly_print(out, "Grouping %s not found.\n", target_schema_path + 8);
            return EXIT_FAILURE;
        }
    } else if (!strncmp(target_schema_path, "typedef/", 8)) {
        if ((spec_target = strrchr(target_schema_path + 8, '/'))) {
            /* schema node typedef */
            /* HACK only temporary */
            spec_target[0] = '\0';
            ++spec_target;

            rc = resolve_absolute_schema_nodeid(target_schema_path + 7, module,
                                                LYS_CONTAINER | LYS_LIST | LYS_NOTIF | LYS_RPC | LYS_ACTION,
                                                (const struct lys_node **)&target);
            if (rc || !target) {
                /* perhaps it's in a grouping */
                rc = resolve_absolute_schema_nodeid(target_schema_path + 7, module, LYS_GROUPING,
                                                    (const struct lys_node **)&target);
            }
            if (!rc && target) {
                switch (target->nodetype) {
                case LYS_CONTAINER:
                    tpdf = ((struct lys_node_container *)target)->tpdf;
                    tpdf_size = ((struct lys_node_container *)target)->tpdf_size;
                    break;
                case LYS_LIST:
                    tpdf = ((struct lys_node_list *)target)->tpdf;
                    tpdf_size = ((struct lys_node_list *)target)->tpdf_size;
                    break;
                case LYS_NOTIF:
                    tpdf = ((struct lys_node_notif *)target)->tpdf;
                    tpdf_size = ((struct lys_node_notif *)target)->tpdf_size;
                    break;
                case LYS_RPC:
                case LYS_ACTION:
                    tpdf = ((struct lys_node_rpc_action *)target)->tpdf;
                    tpdf_size = ((struct lys_node_rpc_action *)target)->tpdf_size;
                    break;
                case LYS_GROUPING:
                    tpdf = ((struct lys_node_grp *)target)->tpdf;
                    tpdf_size = ((struct lys_node_grp *)target)->tpdf_size;
                    break;
                default:
                    LOGINT(module->ctx);
                    return EXIT_FAILURE;
                }
            }
        } else {
            /* module typedef */
            spec_target = (char *)target_schema_path + 8;
            tpdf = module->tpdf;
            tpdf_size = module->tpdf_size;
        }

        for (i = 0; i < tpdf_size; ++i) {
            if (!strcmp(tpdf[i].name, spec_target)) {
                clb_print_typedef(out, &tpdf[i], &f);
                break;
            }
        }
        /* HACK return previous hack */
        --spec_target;
        spec_target[0] = '/';

        if (i == tpdf_size) {
            ly_print(out, "Typedef %s not found.\n", target_schema_path);
            return EXIT_FAILURE;
        }
        return EXIT_SUCCESS;

    } else if (!strncmp(target_schema_path, "identity/", 9)) {
        target_schema_path += 9;
        for (i = 0; i < (signed)module->ident_size; ++i) {
            if (!strcmp(module->ident[i].name, target_schema_path)) {
                break;
            }
        }
        if (i == (signed)module->ident_size) {
            ly_print(out, "Identity %s not found.\n", target_schema_path);
            return EXIT_FAILURE;
        }

        clb_print_identity(out, &module->ident[i], &f);
        return EXIT_SUCCESS;

    } else if (!strncmp(target_schema_path, "feature/", 8)) {
        target_schema_path += 8;
        for (i = 0; i < module->features_size; ++i) {
            if (!strcmp(module->features[i].name, target_schema_path)) {
                break;
            }
        }
        if (i == module->features_size) {
            ly_print(out, "Feature %s not found.\n", target_schema_path);
            return EXIT_FAILURE;
        }

        clb_print_feature(out, &module->features[i], &f);
        return EXIT_SUCCESS;
    } else {
        ly_print(out, "Target could not be resolved.\n");
        return EXIT_FAILURE;
    }

    if (!strncmp(target_schema_path, "type/", 5)) {
        if (!(target->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
            LOGERR(module->ctx, LY_EINVAL, "Target is not a leaf or a leaf-list.");
            return EXIT_FAILURE;
        }
        clb_print_type(out, &((struct lys_node_leaf *)target)->type, &f);
        return EXIT_SUCCESS;
    } else if (!strncmp(target_schema_path, "grouping/", 9) && !spec_target) {
        clb_print_grouping(out, target, &f);
        return EXIT_SUCCESS;
    }

    /* find the node in the grouping */
    if (spec_target) {
        rc = resolve_descendant_schema_nodeid(spec_target, target->child, LYS_NO_RPC_NOTIF_NODE,
                                              0, (const struct lys_node **)&target);
        if (rc || !target) {
            ly_print(out, "Grouping %s child \"%s\" not found.\n", target_schema_path + 9, spec_target);
            return EXIT_FAILURE;
        }
        /* HACK return previous hack */
        --spec_target;
        spec_target[0] = '/';
    }
    switch (target->nodetype) {
    case LYS_CONTAINER:
        clb_print_container(out, target, &f);
        break;
    case LYS_CHOICE:
        clb_print_choice(out, target, &f);
        break;
    case LYS_LEAF:
        clb_print_leaf(out, target, &f);
        break;
    case LYS_LEAFLIST:
        clb_print_leaflist(out, target, &f);
        break;
    case LYS_LIST:
        clb_print_list(out, target, &f);
        break;
    case LYS_ANYXML:
    case LYS_ANYDATA:
        clb_print_anydata(out, target, &f);
        break;
    case LYS_CASE:
        clb_print_case(out, target, &f);
        break;
    case LYS_NOTIF:
        clb_print_notif(out, target, &f);
        break;
    case LYS_RPC:
        clb_print_rpc(out, target, &f);
        break;
    case LYS_ACTION:
        clb_print_action(out, target, &f);
        break;
    case LYS_INPUT:
        clb_print_input(out, target, &f);
        break;
    case LYS_OUTPUT:
        clb_print_output(out, target, &f);
        break;
    default:
        ly_print(out, "Nodetype %s not supported.\n", strnodetype(target->nodetype));
        break;
    }

    return EXIT_SUCCESS;
}
Пример #8
0
static void
json_print_leaf(struct lyout *out, int level, const struct lyd_node *node, int onlyvalue)
{
    struct lyd_node_leaf_list *leaf = (struct lyd_node_leaf_list *)node;
    const char *schema = NULL;

    if (!onlyvalue) {
        if (!node->parent || nscmp(node, node->parent)) {
            /* print "namespace" */
            schema = lys_node_module(node->schema)->name;
            ly_print(out, "%*s\"%s:%s\": ", LEVEL, INDENT, schema, node->schema->name);
        } else {
            ly_print(out, "%*s\"%s\": ", LEVEL, INDENT, node->schema->name);
        }
    }

    switch (leaf->value_type & LY_DATA_TYPE_MASK) {
    case LY_TYPE_BINARY:
    case LY_TYPE_STRING:
    case LY_TYPE_BITS:
    case LY_TYPE_ENUM:
    case LY_TYPE_IDENT:
    case LY_TYPE_INST:
        json_print_string(out, leaf->value_str ? leaf->value_str : "");
        break;

    case LY_TYPE_BOOL:
    case LY_TYPE_DEC64:
    case LY_TYPE_INT8:
    case LY_TYPE_INT16:
    case LY_TYPE_INT32:
    case LY_TYPE_INT64:
    case LY_TYPE_UINT8:
    case LY_TYPE_UINT16:
    case LY_TYPE_UINT32:
    case LY_TYPE_UINT64:
        ly_print(out, "%s", leaf->value_str ? leaf->value_str : "null");
        break;

    case LY_TYPE_LEAFREF:
        if (leaf->value.leafref) {
            json_print_leaf(out, level, leaf->value.leafref, 1);
        } else {
            ly_print(out, "");
        }
        break;

    case LY_TYPE_EMPTY:
        ly_print(out, "[null]");
        break;

    default:
        /* error */
        ly_print(out, "\"(!error!)\"");
    }

    /* print attributes as sibling leafs */
    if (!onlyvalue && node->attr) {
        if (schema) {
            ly_print(out, ",\n%*s\"@%s:%s\": {\n", LEVEL, INDENT, schema, node->schema->name);
        } else {
            ly_print(out, ",\n%*s\"@%s\": {\n", LEVEL, INDENT, node->schema->name);
        }
        json_print_attrs(out, level + 1, node);
        ly_print(out, "%*s}", LEVEL, INDENT);
    }

    return;
}
Пример #9
0
static void
json_print_nodes(struct lyout *out, int level, const struct lyd_node *root, int withsiblings)
{
    const struct lyd_node *node, *iter;

    LY_TREE_FOR(root, node) {
        switch (node->schema->nodetype) {
        case LYS_RPC:
        case LYS_NOTIF:
        case LYS_CONTAINER:
            if (node->prev->next) {
                /* print the previous comma */
                ly_print(out, ",\n");
            }
            json_print_container(out, level, node);
            break;
        case LYS_LEAF:
            if (node->prev->next) {
                /* print the previous comma */
                ly_print(out, ",\n");
            }
            json_print_leaf(out, level, node, 0);
            break;
        case LYS_LEAFLIST:
        case LYS_LIST:
            /* is it already printed? */
            for (iter = node->prev; iter->next; iter = iter->prev) {
                if (iter == node) {
                    continue;
                }
                if (iter->schema == node->schema) {
                    /* the list has alread some previous instance and therefore it is already printed */
                    break;
                }
            }
            if (!iter->next) {
                if (node->prev->next) {
                    /* print the previous comma */
                    ly_print(out, ",\n");
                }

                /* print the list/leaflist */
                json_print_leaf_list(out, level, node, node->schema->nodetype == LYS_LIST ? 1 : 0);
            }
            break;
        case LYS_ANYXML:
            if (node->prev->next) {
                /* print the previous comma */
                ly_print(out, ",\n");
            }
            json_print_anyxml(out, level, node);
            break;
        default:
            LOGINT;
            break;
        }

        if (!withsiblings) {
            break;
        }
    }
    ly_print(out, "\n");
}
Пример #10
0
static void
json_print_leaf_list(struct lyout *out, int level, const struct lyd_node *node, int is_list)
{
    const char *schema = NULL;
    const struct lyd_node *list = node;
    int flag_empty = 0, flag_attrs = 0;

    if (!list->child) {
        /* empty, e.g. in case of filter */
        flag_empty = 1;
    }

    if (!node->parent || nscmp(node, node->parent)) {
        /* print "namespace" */
        schema = lys_node_module(node->schema)->name;
        ly_print(out, "%*s\"%s:%s\":", LEVEL, INDENT, schema, node->schema->name);
    } else {
        ly_print(out, "%*s\"%s\":", LEVEL, INDENT, node->schema->name);
    }

    if (flag_empty) {
        ly_print(out, " null");
        return;
    }
    ly_print(out, " [\n");

    if (!is_list) {
        ++level;
    }

    while (list) {
        if (is_list) {
            /* list print */
            ++level;
            ly_print(out, "%*s{\n", LEVEL, INDENT);
            ++level;
            if (list->attr) {
                ly_print(out, "%*s\"@\": {\n", LEVEL, INDENT);
                json_print_attrs(out, level + 1, node);
                ly_print(out, "%*s}%s", LEVEL, INDENT, list->child ? ",\n" : "");
            }
            json_print_nodes(out, level, list->child, 1);
            --level;
            ly_print(out, "%*s}", LEVEL, INDENT);
            --level;
        } else {
            /* leaf-list print */
            ly_print(out, "%*s", LEVEL, INDENT);
            json_print_leaf(out, level, list, 1);
            if (list->attr) {
                flag_attrs = 1;
            }
        }
        for (list = list->next; list && list->schema != node->schema; list = list->next);
        if (list) {
            ly_print(out, ",\n");
        }
    }

    if (!is_list) {
        --level;
    }

    ly_print(out, "\n%*s]", LEVEL, INDENT);

    /* attributes */
    if (!is_list && flag_attrs) {
        if (schema) {
            ly_print(out, ",\n%*s\"@%s:%s\": [\n", LEVEL, INDENT, schema, node->schema->name);
        } else {
            ly_print(out, ",\n%*s\"@%s\": [\n", LEVEL, INDENT, node->schema->name);
        }
        level++;
        for (list = node; list; ) {
            if (list->attr) {
                ly_print(out, "%*s{ ", LEVEL, INDENT);
                json_print_attrs(out, 0, list);
                ly_print(out, "%*s}", LEVEL, INDENT);
            } else {
                ly_print(out, "%*snull", LEVEL, INDENT);
            }


            for (list = list->next; list && list->schema != node->schema; list = list->next);
            if (list) {
                ly_print(out, ",\n");
            }
        }
        level--;
        ly_print(out, "\n%*s]", LEVEL, INDENT);
    }
}